diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 06f8321df59..94355a84e3c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -397,7 +397,7 @@ public TestRule chain = RuleChain.outerRule(ccmRule).around(sessionRule); Only use this for: -* CCM tests that use `@CassandraRequirement` or `@DseRequirement` or `@ScyllaRequirement` restrictions at the method level +* CCM tests that use `@CassandraRequirement`, `@ScyllaRequirement`, or `@BackendRequirement` restrictions at the method level (ex: `BatchStatementIT`). * tests where you *really* need to restart from a clean state for every method. diff --git a/ci/run-tests.sh b/ci/run-tests.sh index 5268bdd7113..a294bfe0861 100755 --- a/ci/run-tests.sh +++ b/ci/run-tests.sh @@ -9,4 +9,4 @@ jabba use ${TEST_JAVA_VERSION} # Find out the latest patch version of Cassandra PATCH_SERVER_VERSION=$(curl -s https://downloads.apache.org/cassandra/ | grep -oP '(?<=href=\")[0-9]+\.[0-9]+\.[0-9]+(?=)' | sort -rV | uniq -w 3 | grep $SERVER_VERSION) printenv | sort -mvn -B -V verify -T 1 -Ptest-jdk-${TEST_JAVA_MAJOR_VERSION} -DtestJavaHome=$(jabba which ${TEST_JAVA_VERSION}) -Dccm.version=${PATCH_SERVER_VERSION} -Dccm.dse=false -Dmaven.test.failure.ignore=true -Dmaven.javadoc.skip=true +mvn -B -V verify -T 1 -Ptest-jdk-${TEST_JAVA_MAJOR_VERSION} -DtestJavaHome=$(jabba which ${TEST_JAVA_VERSION}) -Dccm.version=${PATCH_SERVER_VERSION} -Dmaven.test.failure.ignore=true -Dmaven.javadoc.skip=true diff --git a/core-shaded/pom.xml b/core-shaded/pom.xml index 4d6ccfd8fad..f5f8a6bf59a 100644 --- a/core-shaded/pom.xml +++ b/core-shaded/pom.xml @@ -94,21 +94,6 @@ org.hdrhistogram HdrHistogram - - com.esri.geometry - esri-geometry-api - true - - - org.apache.tinkerpop - gremlin-core - true - - - org.apache.tinkerpop - tinkergraph-gremlin - true - org.reactivestreams reactive-streams @@ -316,21 +301,6 @@ lz4-java ${lz4.version} - - org.apache.tinkerpop - gremlin-core - ${tinkerpop.version} - - - org.apache.tinkerpop - tinkergraph-gremlin - ${tinkerpop.version} - - - com.esri.geometry - esri-geometry-api - ${esri.version} - @@ -375,7 +345,7 @@ Note: dependencies marked as optional are by default included with optional resolution in the manifest; we only need to manually set the resolution to optional for dependencies declared as non-optional in the pom files. - -->jnr.*;resolution:=optional, com.esri.core.geometry.*;resolution:=optional,org.reactivestreams.*;resolution:=optional, org.apache.tinkerpop.*;resolution:=optional, org.javatuples.*;resolution:=optional, reactor.blockhound.*;resolution:=optional, + -->jnr.*;resolution:=optional,org.reactivestreams.*;resolution:=optional, reactor.blockhound.*;resolution:=optional, - com.datastax.oss.driver.api.core.*, com.datastax.oss.driver.internal.core.*, com.datastax.dse.driver.api.core.*, com.datastax.dse.driver.internal.core.*, com.datastax.oss.driver.shaded.netty.*, com.datastax.oss.driver.shaded.fasterxml.jackson.*, + + com.datastax.oss.driver.api.core.*, com.datastax.oss.driver.internal.core.*, com.datastax.dse.driver.api.core.cql.reactive, com.datastax.dse.driver.internal.core.cql.reactive, com.datastax.dse.driver.internal.core.util.concurrent, com.datastax.oss.driver.shaded.netty.*, com.datastax.oss.driver.shaded.fasterxml.jackson.*, true diff --git a/core/pom.xml b/core/pom.xml index 45f2ee64cf6..e6994d296d6 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -83,21 +83,6 @@ org.hdrhistogram HdrHistogram - - com.esri.geometry - esri-geometry-api - true - - - org.apache.tinkerpop - gremlin-core - true - - - org.apache.tinkerpop - tinkergraph-gremlin - true - com.fasterxml.jackson.core jackson-core @@ -324,32 +309,15 @@ Note: dependencies marked as optional are by default included with optional resolution in the manifest; we only need to manually set the resolution to optional for dependencies declared as non-optional in the pom files. - -->jnr.*;resolution:=optional, com.esri.core.geometry.*;resolution:=optional, org.reactivestreams.*;resolution:=optional, org.apache.tinkerpop.*;resolution:=optional, org.javatuples.*;resolution:=optional, reactor.blockhound.*;resolution:=optional, * + -->jnr.*;resolution:=optional, org.reactivestreams.*;resolution:=optional, reactor.blockhound.*;resolution:=optional, * - com.datastax.oss.driver.*.core.*, com.datastax.dse.driver.*.core.* + + com.datastax.oss.driver.*.core.*, com.datastax.dse.driver.api.core.cql.reactive, com.datastax.dse.driver.internal.core.cql.reactive, com.datastax.dse.driver.internal.core.util.concurrent - - maven-dependency-plugin - - - generate-dependency-list - - list - - generate-resources - - runtime - true - com.datastax.cassandra,com.datastax.dse - ${project.build.outputDirectory}/com/datastax/dse/driver/internal/deps.txt - - - - diff --git a/core/revapi.json b/core/revapi.json index 6e9d7234d8e..ca6e018a2af 100644 --- a/core/revapi.json +++ b/core/revapi.json @@ -5,7 +5,7 @@ "packages": { "regex": true, "exclude": [ - "com\\.datastax\\.(oss|dse)\\.protocol\\.internal(\\..+)?", + "com\\.datastax\\.oss\\.protocol\\.internal(\\..+)?", "com\\.datastax\\.(oss|dse)\\.driver\\.internal(\\..+)?", "com\\.datastax\\.oss\\.driver\\.shaded(\\..+)?", "org\\.assertj(\\..+)?" @@ -4836,13 +4836,6 @@ "annotation": "@edu.umd.cs.findbugs.annotations.NonNull", "justification": "JAVA-2434: added @NonNull to ProgrammaticSslEngineFactory(SSLContext) constructor" }, - { - "code": "java.class.nonFinalClassInheritsFromNewClass", - "old": "class com.datastax.oss.driver.api.core.auth.PlainTextAuthProviderBase.PlainTextAuthenticator", - "new": "class com.datastax.oss.driver.api.core.auth.PlainTextAuthProviderBase.PlainTextAuthenticator", - "superClass": "com.datastax.dse.driver.api.core.auth.BaseDseAuthenticator", - "justification": "New parent doesn't add constraints for implementors" - }, { "code": "java.method.exception.runtimeAdded", "old": "method com.datastax.oss.driver.api.core.auth.Authenticator com.datastax.oss.driver.api.core.auth.PlainTextAuthProviderBase::newAuthenticator(com.datastax.oss.driver.api.core.metadata.EndPoint, java.lang.String)", @@ -4850,14 +4843,6 @@ "exception": "com.datastax.oss.driver.api.core.auth.AuthenticationException", "justification": "New exception is unchecked" }, - { - "code": "java.class.superTypeTypeParametersChanged", - "old": "class com.datastax.dse.driver.api.core.DseSessionBuilderBase", - "new": "class com.datastax.dse.driver.api.core.DseSessionBuilderBase, SessionT>", - "oldSuperType": "com.datastax.oss.driver.api.core.session.SessionBuilder", - "newSuperType": "com.datastax.oss.driver.api.core.session.SessionBuilder, SessionT>", - "justification": "JAVA-2411: Type parameters were wrong but it is unlikely that implementors would notice that in subclasses" - }, { "code": "java.method.removed", "old": "method org.apache.tinkerpop.gremlin.process.remote.traversal.RemoteTraversal org.apache.tinkerpop.gremlin.process.remote.RemoteConnection::submit(org.apache.tinkerpop.gremlin.process.traversal.Bytecode) throws org.apache.tinkerpop.gremlin.process.remote.RemoteConnectionException", diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/DseProtocolVersion.java b/core/src/main/java/com/datastax/dse/driver/api/core/DseProtocolVersion.java deleted file mode 100644 index f5fe545c421..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/DseProtocolVersion.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Copyright (C) 2018 ScyllaDB - * - * Modified by ScyllaDB - */ -package com.datastax.dse.driver.api.core; - -import com.datastax.dse.protocol.internal.DseProtocolConstants; -import com.datastax.oss.driver.api.core.DefaultProtocolVersion; -import com.datastax.oss.driver.api.core.ProtocolVersion; - -/** - * A DSE-specific protocol version. - * - *

Legacy DSE versions did not have a specific version, but instead reused a Cassandra protocol - * version: DSE 5.0 is supported via {@link DefaultProtocolVersion#V4}, and DSE 4.7 and 4.8 via - * {@link DefaultProtocolVersion#V3}. - * - *

DSE 4.6 and earlier are not supported by this version of the driver, use the 1.x series. - */ -public enum DseProtocolVersion implements ProtocolVersion { - - /** Version 1, supported by DSE 5.1.0 and above. */ - DSE_V1(DseProtocolConstants.Version.DSE_V1, false), - - /** Version 2, supported by DSE 6 and above. */ - DSE_V2(DseProtocolConstants.Version.DSE_V2, false), - ; - - private final int code; - private final boolean beta; - - DseProtocolVersion(int code, boolean beta) { - this.code = code; - this.beta = beta; - } - - @Override - public int getCode() { - return code; - } - - @Override - public boolean isBeta() { - return beta; - } - - @Override - public boolean supportsShardingInfo() { - return false; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/DseSession.java b/core/src/main/java/com/datastax/dse/driver/api/core/DseSession.java deleted file mode 100644 index 8251aaf767c..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/DseSession.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core; - -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.MavenCoordinates; -import edu.umd.cs.findbugs.annotations.NonNull; - -/** - * @deprecated All DSE functionality is now available directly on {@link CqlSession}. This type is - * preserved for backward compatibility, but you should now use {@link CqlSession} instead. - */ -@Deprecated -public interface DseSession extends CqlSession { - - /** - * @deprecated the DSE driver is no longer published as a separate artifact. This field is - * preserved for backward compatibility, but it returns the same value as {@link - * CqlSession#OSS_DRIVER_COORDINATES}. - */ - @Deprecated @NonNull MavenCoordinates DSE_DRIVER_COORDINATES = CqlSession.OSS_DRIVER_COORDINATES; - - /** - * Returns a builder to create a new instance. - * - *

Note that this builder is mutable and not thread-safe. - */ - @NonNull - static DseSessionBuilder builder() { - return new DseSessionBuilder(); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/DseSessionBuilder.java b/core/src/main/java/com/datastax/dse/driver/api/core/DseSessionBuilder.java deleted file mode 100644 index 01e5f9f9125..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/DseSessionBuilder.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core; - -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.session.SessionBuilder; -import edu.umd.cs.findbugs.annotations.NonNull; -import net.jcip.annotations.NotThreadSafe; - -/** - * @deprecated DSE functionality is now exposed directly on {@link CqlSession}. This class is - * preserved for backward compatibility, but {@link CqlSession#builder()} should be used - * instead. - */ -@NotThreadSafe -@Deprecated -public class DseSessionBuilder extends SessionBuilder { - - @NonNull - @Override - protected DseSession wrap(@NonNull CqlSession defaultSession) { - return new com.datastax.dse.driver.internal.core.session.DefaultDseSession(defaultSession); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/auth/BaseDseAuthenticator.java b/core/src/main/java/com/datastax/dse/driver/api/core/auth/BaseDseAuthenticator.java deleted file mode 100644 index abd68b530b6..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/auth/BaseDseAuthenticator.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.auth; - -import com.datastax.oss.driver.api.core.auth.SyncAuthenticator; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.nio.ByteBuffer; -import net.jcip.annotations.ThreadSafe; - -/** - * Base class for {@link SyncAuthenticator} implementations that want to make use of the - * authentication scheme negotiation in DseAuthenticator. - */ -@ThreadSafe -public abstract class BaseDseAuthenticator implements SyncAuthenticator { - - private static final String DSE_AUTHENTICATOR = - "com.datastax.bdp.cassandra.auth.DseAuthenticator"; - - private final String serverAuthenticator; - - protected BaseDseAuthenticator(@NonNull String serverAuthenticator) { - this.serverAuthenticator = serverAuthenticator; - } - - /** - * Return a byte buffer containing the required SASL mechanism. - * - *

This should be one of: - * - *

    - *
  • PLAIN - *
  • GSSAPI - *
- * - * This must be either a {@linkplain ByteBuffer#asReadOnlyBuffer() read-only} buffer, or a new - * instance every time. - */ - @NonNull - protected abstract ByteBuffer getMechanism(); - - /** - * Return a byte buffer containing the expected successful server challenge. - * - *

This should be one of: - * - *

    - *
  • PLAIN-START - *
  • GSSAPI-START - *
- * - * This must be either a {@linkplain ByteBuffer#asReadOnlyBuffer() read-only} buffer, or a new - * instance every time. - */ - @NonNull - protected abstract ByteBuffer getInitialServerChallenge(); - - @Nullable - @Override - public ByteBuffer initialResponseSync() { - // DseAuthenticator communicates back the mechanism in response to server authenticate message. - // older authenticators simply expect the auth response with credentials. - if (isDseAuthenticator()) { - return getMechanism(); - } else { - return evaluateChallengeSync(getInitialServerChallenge()); - } - } - - @Override - public void onAuthenticationSuccessSync(@Nullable ByteBuffer token) {} - - private boolean isDseAuthenticator() { - return serverAuthenticator.equals(DSE_AUTHENTICATOR); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/auth/DseGssApiAuthProviderBase.java b/core/src/main/java/com/datastax/dse/driver/api/core/auth/DseGssApiAuthProviderBase.java deleted file mode 100644 index 48a0e5b0ef3..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/auth/DseGssApiAuthProviderBase.java +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.auth; - -import com.datastax.oss.driver.api.core.auth.AuthProvider; -import com.datastax.oss.driver.api.core.auth.AuthenticationException; -import com.datastax.oss.driver.api.core.auth.Authenticator; -import com.datastax.oss.driver.api.core.metadata.EndPoint; -import com.datastax.oss.driver.api.core.session.Session; -import com.datastax.oss.driver.shaded.guava.common.base.Charsets; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import com.datastax.oss.protocol.internal.util.Bytes; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.net.InetSocketAddress; -import java.nio.ByteBuffer; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import javax.security.auth.Subject; -import javax.security.auth.login.AppConfigurationEntry; -import javax.security.auth.login.Configuration; -import javax.security.auth.login.LoginContext; -import javax.security.auth.login.LoginException; -import javax.security.sasl.Sasl; -import javax.security.sasl.SaslClient; -import javax.security.sasl.SaslException; -import net.jcip.annotations.Immutable; -import net.jcip.annotations.NotThreadSafe; -import net.jcip.annotations.ThreadSafe; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@ThreadSafe -public abstract class DseGssApiAuthProviderBase implements AuthProvider { - - /** The default SASL service name used by this auth provider. */ - public static final String DEFAULT_SASL_SERVICE_NAME = "dse"; - - /** The name of the system property to use to specify the SASL service name. */ - public static final String SASL_SERVICE_NAME_PROPERTY = "dse.sasl.service"; - - /** - * Legacy system property for SASL protocol name. Clients should migrate to - * SASL_SERVICE_NAME_PROPERTY above. - */ - private static final String LEGACY_SASL_PROTOCOL_PROPERTY = "dse.sasl.protocol"; - - private static final Logger LOG = LoggerFactory.getLogger(DseGssApiAuthProviderBase.class); - - private final String logPrefix; - - /** - * @param logPrefix a string that will get prepended to the logs (this is used for discrimination - * when you have multiple driver instances executing in the same JVM). Config-based - * implementations fill this with {@link Session#getName()}. - */ - protected DseGssApiAuthProviderBase(@NonNull String logPrefix) { - this.logPrefix = Objects.requireNonNull(logPrefix); - } - - @NonNull - protected abstract GssApiOptions getOptions( - @NonNull EndPoint endPoint, @NonNull String serverAuthenticator); - - @NonNull - @Override - public Authenticator newAuthenticator( - @NonNull EndPoint endPoint, @NonNull String serverAuthenticator) - throws AuthenticationException { - return new GssApiAuthenticator( - getOptions(endPoint, serverAuthenticator), endPoint, serverAuthenticator); - } - - @Override - public void onMissingChallenge(@NonNull EndPoint endPoint) { - LOG.warn( - "[{}] {} did not send an authentication challenge; " - + "This is suspicious because the driver expects authentication", - logPrefix, - endPoint); - } - - @Override - public void close() { - // nothing to do - } - - /** - * The options to initialize a new authenticator. - * - *

Use {@link #builder()} to create an instance. - */ - @Immutable - public static class GssApiOptions { - - @NonNull - public static Builder builder() { - return new Builder(); - } - - private final Configuration loginConfiguration; - private final Subject subject; - private final String saslProtocol; - private final String authorizationId; - private final Map saslProperties; - - private GssApiOptions( - @Nullable Configuration loginConfiguration, - @Nullable Subject subject, - @Nullable String saslProtocol, - @Nullable String authorizationId, - @NonNull Map saslProperties) { - this.loginConfiguration = loginConfiguration; - this.subject = subject; - this.saslProtocol = saslProtocol; - this.authorizationId = authorizationId; - this.saslProperties = saslProperties; - } - - @Nullable - public Configuration getLoginConfiguration() { - return loginConfiguration; - } - - @Nullable - public Subject getSubject() { - return subject; - } - - @Nullable - public String getSaslProtocol() { - return saslProtocol; - } - - @Nullable - public String getAuthorizationId() { - return authorizationId; - } - - @NonNull - public Map getSaslProperties() { - return saslProperties; - } - - @NotThreadSafe - public static class Builder { - - private Configuration loginConfiguration; - private Subject subject; - private String saslProtocol; - private String authorizationId; - private final Map saslProperties = new HashMap<>(); - - public Builder() { - saslProperties.put(Sasl.SERVER_AUTH, "true"); - saslProperties.put(Sasl.QOP, "auth"); - } - - /** - * Sets a login configuration that will be used to create a {@link LoginContext}. - * - *

You MUST call either a withLoginConfiguration method or {@link #withSubject(Subject)}; - * if both are called, the subject takes precedence, and the login configuration will be - * ignored. - * - * @see #withLoginConfiguration(Map) - */ - @NonNull - public Builder withLoginConfiguration(@Nullable Configuration loginConfiguration) { - this.loginConfiguration = loginConfiguration; - return this; - } - /** - * Sets a login configuration that will be used to create a {@link LoginContext}. - * - *

This is an alternative to {@link #withLoginConfiguration(Configuration)}, that builds - * the configuration from {@code Krb5LoginModule} with the given options. - * - *

You MUST call either a withLoginConfiguration method or {@link #withSubject(Subject)}; - * if both are called, the subject takes precedence, and the login configuration will be - * ignored. - */ - @NonNull - public Builder withLoginConfiguration(@Nullable Map loginConfiguration) { - this.loginConfiguration = fetchLoginConfiguration(loginConfiguration); - return this; - } - - /** - * Sets a previously authenticated subject to reuse. - * - *

You MUST call either this method or {@link #withLoginConfiguration(Configuration)}; if - * both are called, the subject takes precedence, and the login configuration will be ignored. - */ - @NonNull - public Builder withSubject(@Nullable Subject subject) { - this.subject = subject; - return this; - } - - /** - * Sets the SASL protocol name to use; should match the username of the Kerberos service - * principal used by the DSE server. - */ - @NonNull - public Builder withSaslProtocol(@Nullable String saslProtocol) { - this.saslProtocol = saslProtocol; - return this; - } - - /** Sets the authorization ID (allows proxy authentication). */ - @NonNull - public Builder withAuthorizationId(@Nullable String authorizationId) { - this.authorizationId = authorizationId; - return this; - } - - /** - * Add a SASL property to use when creating the SASL client. - * - *

Note that this builder pre-initializes these two default properties: - * - *

-       * javax.security.sasl.server.authentication = true
-       * javax.security.sasl.qop = auth
-       * 
- */ - @NonNull - public Builder addSaslProperty(@NonNull String name, @NonNull String value) { - this.saslProperties.put(Objects.requireNonNull(name), Objects.requireNonNull(value)); - return this; - } - - @NonNull - public GssApiOptions build() { - return new GssApiOptions( - loginConfiguration, - subject, - saslProtocol, - authorizationId, - ImmutableMap.copyOf(saslProperties)); - } - - public static Configuration fetchLoginConfiguration(Map options) { - return new Configuration() { - - @Override - public AppConfigurationEntry[] getAppConfigurationEntry(String name) { - return new AppConfigurationEntry[] { - new AppConfigurationEntry( - "com.sun.security.auth.module.Krb5LoginModule", - AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, - options) - }; - } - }; - } - } - } - - protected static class GssApiAuthenticator extends BaseDseAuthenticator { - - private static final ByteBuffer MECHANISM = - ByteBuffer.wrap("GSSAPI".getBytes(Charsets.UTF_8)).asReadOnlyBuffer(); - private static final ByteBuffer SERVER_INITIAL_CHALLENGE = - ByteBuffer.wrap("GSSAPI-START".getBytes(Charsets.UTF_8)).asReadOnlyBuffer(); - private static final ByteBuffer EMPTY_BYTE_ARRAY = - ByteBuffer.wrap(new byte[0]).asReadOnlyBuffer(); - private static final String JAAS_CONFIG_ENTRY = "DseClient"; - private static final String[] SUPPORTED_MECHANISMS = new String[] {"GSSAPI"}; - - private Subject subject; - private SaslClient saslClient; - private EndPoint endPoint; - - protected GssApiAuthenticator( - GssApiOptions options, EndPoint endPoint, String serverAuthenticator) { - super(serverAuthenticator); - - try { - if (options.getSubject() != null) { - this.subject = options.getSubject(); - } else { - Configuration loginConfiguration = options.getLoginConfiguration(); - if (loginConfiguration == null) { - throw new IllegalArgumentException("Must provide one of subject or loginConfiguration"); - } - LoginContext login = new LoginContext(JAAS_CONFIG_ENTRY, null, null, loginConfiguration); - login.login(); - this.subject = login.getSubject(); - } - String protocol = options.getSaslProtocol(); - if (protocol == null) { - protocol = - System.getProperty( - SASL_SERVICE_NAME_PROPERTY, - System.getProperty(LEGACY_SASL_PROTOCOL_PROPERTY, DEFAULT_SASL_SERVICE_NAME)); - } - this.saslClient = - Sasl.createSaslClient( - SUPPORTED_MECHANISMS, - options.getAuthorizationId(), - protocol, - ((InetSocketAddress) endPoint.resolve()).getAddress().getCanonicalHostName(), - options.getSaslProperties(), - null); - } catch (LoginException | SaslException e) { - throw new AuthenticationException(endPoint, e.getMessage()); - } - this.endPoint = endPoint; - } - - @NonNull - @Override - protected ByteBuffer getMechanism() { - return MECHANISM; - } - - @NonNull - @Override - protected ByteBuffer getInitialServerChallenge() { - return SERVER_INITIAL_CHALLENGE; - } - - @Nullable - @Override - public ByteBuffer evaluateChallengeSync(@Nullable ByteBuffer challenge) { - - byte[] challengeBytes; - if (SERVER_INITIAL_CHALLENGE.equals(challenge)) { - if (!saslClient.hasInitialResponse()) { - return EMPTY_BYTE_ARRAY; - } - challengeBytes = new byte[0]; - } else { - // The native protocol spec says the incoming challenge can be null depending on the - // implementation. But saslClient.evaluateChallenge clearly documents that the byte array - // can't be null, which probably means that a SASL authenticator never sends back null. - if (challenge == null) { - throw new AuthenticationException(this.endPoint, "Unexpected null challenge from server"); - } - challengeBytes = Bytes.getArray(challenge); - } - try { - - return ByteBuffer.wrap( - Subject.doAs( - subject, - new PrivilegedExceptionAction() { - @Override - public byte[] run() throws SaslException { - return saslClient.evaluateChallenge(challengeBytes); - } - })); - } catch (PrivilegedActionException e) { - throw new AuthenticationException(this.endPoint, e.getMessage(), e.getException()); - } - } - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/auth/DsePlainTextAuthProviderBase.java b/core/src/main/java/com/datastax/dse/driver/api/core/auth/DsePlainTextAuthProviderBase.java deleted file mode 100644 index 7c5ee23bd6c..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/auth/DsePlainTextAuthProviderBase.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.auth; - -import com.datastax.oss.driver.api.core.auth.PlainTextAuthProviderBase; -import edu.umd.cs.findbugs.annotations.NonNull; -import net.jcip.annotations.ThreadSafe; - -/** - * @deprecated The driver's default plain text providers now support both Apache Cassandra and DSE. - * This type was preserved for backward compatibility, but implementors should now extend {@link - * PlainTextAuthProviderBase} instead. - */ -@ThreadSafe -@Deprecated -public abstract class DsePlainTextAuthProviderBase extends PlainTextAuthProviderBase { - - protected DsePlainTextAuthProviderBase(@NonNull String logPrefix) { - super(logPrefix); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/auth/ProgrammaticDseGssApiAuthProvider.java b/core/src/main/java/com/datastax/dse/driver/api/core/auth/ProgrammaticDseGssApiAuthProvider.java deleted file mode 100644 index 64ee5265b5a..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/auth/ProgrammaticDseGssApiAuthProvider.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.auth; - -import com.datastax.oss.driver.api.core.auth.AuthProvider; -import com.datastax.oss.driver.api.core.metadata.EndPoint; -import edu.umd.cs.findbugs.annotations.NonNull; - -/** - * {@link AuthProvider} that provides GSSAPI authenticator instances for clients to connect to DSE - * clusters secured with {@code DseAuthenticator}, in a programmatic way. - * - *

To use this provider the corresponding GssApiOptions must be passed into the provider - * directly, for example: - * - *

- *     DseGssApiAuthProviderBase.GssApiOptions.Builder builder =
- *         DseGssApiAuthProviderBase.GssApiOptions.builder();
- *     Map<String, String> loginConfig =
- *         ImmutableMap.of(
- *             "principal",
- *             "user principal here ex cassandra@DATASTAX.COM",
- *             "useKeyTab",
- *             "true",
- *             "refreshKrb5Config",
- *             "true",
- *             "keyTab",
- *             "Path to keytab file here");
- *
- *     builder.withLoginConfiguration(loginConfig);
- *
- *     CqlSession session =
- *         CqlSession.builder()
- *             .withAuthProvider(new ProgrammaticDseGssApiAuthProvider(builder.build()))
- *             .build();
- * 
- * - * or alternatively - * - *
- *     DseGssApiAuthProviderBase.GssApiOptions.Builder builder =
- *         DseGssApiAuthProviderBase.GssApiOptions.builder().withSubject(subject);
- *     CqlSession session =
- *         CqlSession.builder()
- *             .withAuthProvider(new ProgrammaticDseGssApiAuthProvider(builder.build()))
- *             .build();
- * 
- * - *

Kerberos Authentication

- * - * Keytab and ticket cache settings are specified using a standard JAAS configuration file. The - * location of the file can be set using the java.security.auth.login.config system - * property or by adding a login.config.url.n entry in the java.security - * properties file. Alternatively a login-configuration, or subject can be provided to the provider - * via the GssApiOptions (see above). - * - *

See the following documents for further details: - * - *

    - *
  1. JAAS - * Login Configuration File; - *
  2. Krb5LoginModule - * options; - *
  3. JAAS - * Authentication Tutorial for more on JAAS in general. - *
- * - *

Authentication using ticket cache

- * - * Run kinit to obtain a ticket and populate the cache before connecting. JAAS config: - * - *
- * DseClient {
- *   com.sun.security.auth.module.Krb5LoginModule required
- *     useTicketCache=true
- *     renewTGT=true;
- * };
- * 
- * - *

Authentication using a keytab file

- * - * To enable authentication using a keytab file, specify its location on disk. If your keytab - * contains more than one principal key, you should also specify which one to select. This - * information can also be specified in the driver config, under the login-configuration section. - * - *
- * DseClient {
- *     com.sun.security.auth.module.Krb5LoginModule required
- *       useKeyTab=true
- *       keyTab="/path/to/file.keytab"
- *       principal="user@MYDOMAIN.COM";
- * };
- * 
- * - *

Specifying SASL protocol name

- * - * The SASL protocol name used by this auth provider defaults to " - * {@value #DEFAULT_SASL_SERVICE_NAME}". - * - *

Important: the SASL protocol name should match the username of the Kerberos - * service principal used by the DSE server. This information is specified in the dse.yaml file by - * the {@code service_principal} option under the kerberos_options - * section, and may vary from one DSE installation to another – especially if you installed - * DSE with an automated package installer. - * - *

For example, if your dse.yaml file contains the following: - * - *

{@code
- * kerberos_options:
- *     ...
- *     service_principal: cassandra/my.host.com@MY.REALM.COM
- * }
- * - * The correct SASL protocol name to use when authenticating against this DSE server is "{@code - * cassandra}". - * - *

Should you need to change the SASL protocol name specify it in the GssApiOptions, use the - * method below: - * - *

- *     DseGssApiAuthProviderBase.GssApiOptions.Builder builder =
- *         DseGssApiAuthProviderBase.GssApiOptions.builder();
- *     builder.withSaslProtocol("alternate");
- *     DseGssApiAuthProviderBase.GssApiOptions options = builder.build();
- * 
- * - *

Should internal sasl properties need to be set such as qop. This can also be accomplished by - * setting it in the GssApiOptions: - * - *

- *   DseGssApiAuthProviderBase.GssApiOptions.Builder builder =
- *         DseGssApiAuthProviderBase.GssApiOptions.builder();
- *     builder.addSaslProperty("javax.security.sasl.qop", "auth-conf");
- *     DseGssApiAuthProviderBase.GssApiOptions options = builder.build();
- * 
- * - * @see Authenticating - * a DSE cluster with Kerberos - */ -public class ProgrammaticDseGssApiAuthProvider extends DseGssApiAuthProviderBase { - private final GssApiOptions options; - - public ProgrammaticDseGssApiAuthProvider(GssApiOptions options) { - super("Programmatic-Kerberos"); - this.options = options; - } - - @NonNull - @Override - protected GssApiOptions getOptions( - @NonNull EndPoint endPoint, @NonNull String serverAuthenticator) { - return options; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/auth/ProxyAuthentication.java b/core/src/main/java/com/datastax/dse/driver/api/core/auth/ProxyAuthentication.java deleted file mode 100644 index a3624ba736d..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/auth/ProxyAuthentication.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.auth; - -import com.datastax.dse.driver.api.core.graph.GraphStatement; -import com.datastax.oss.driver.api.core.cql.Statement; -import com.datastax.oss.driver.shaded.guava.common.base.Charsets; -import com.datastax.oss.protocol.internal.util.collection.NullAllowingImmutableMap; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.nio.ByteBuffer; -import java.util.Map; - -public class ProxyAuthentication { - private static final String PROXY_EXECUTE = "ProxyExecute"; - - /** - * Adds proxy authentication information to a CQL statement. - * - *

This allows executing a statement as another role than the one the session is currently - * authenticated as. - * - * @param userOrRole the role to use for execution. If the statement was already configured with - * another role, it will get replaced by this one. - * @param statement the statement to modify. - * @return a statement that will run the same CQL query as {@code statement}, but acting as the - * provided role. Note: with the driver's default implementations, this will always be a copy; - * but if you use a custom implementation, it might return the same instance (depending on the - * behavior of {@link Statement#setCustomPayload(Map) statement.setCustomPayload()}). - * @see Setting - * up roles for applications (DSE 6.0 admin guide) - */ - @NonNull - public static > StatementT executeAs( - @NonNull String userOrRole, @NonNull StatementT statement) { - return statement.setCustomPayload( - addProxyExecuteEntry(statement.getCustomPayload(), userOrRole)); - } - - /** - * Adds proxy authentication information to a graph statement. - * - * @see #executeAs(String, Statement) - */ - @NonNull - public static > StatementT executeAs( - @NonNull String userOrRole, @NonNull StatementT statement) { - return statement.setCustomPayload( - addProxyExecuteEntry(statement.getCustomPayload(), userOrRole)); - } - - private static Map addProxyExecuteEntry( - Map currentPayload, @NonNull String userOrRole) { - NullAllowingImmutableMap.Builder builder = - NullAllowingImmutableMap.builder(); - builder.put(PROXY_EXECUTE, ByteBuffer.wrap(userOrRole.getBytes(Charsets.UTF_8))); - if (!currentPayload.isEmpty()) { - for (Map.Entry entry : currentPayload.entrySet()) { - String key = entry.getKey(); - if (!key.equals(PROXY_EXECUTE)) { - builder.put(key, entry.getValue()); - } - } - } - return builder.build(); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/config/DseDriverConfigLoader.java b/core/src/main/java/com/datastax/dse/driver/api/core/config/DseDriverConfigLoader.java deleted file mode 100644 index 2694b51ffca..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/config/DseDriverConfigLoader.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.config; - -import com.datastax.oss.driver.api.core.config.DriverConfigLoader; -import com.datastax.oss.driver.api.core.config.ProgrammaticDriverConfigLoaderBuilder; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.io.File; -import java.net.URL; - -/** - * @deprecated This class only exists for backward compatibility. All of its methods delegate to - * their counterparts on {@link DriverConfigLoader}, which you should call directly instead. - */ -@Deprecated -public class DseDriverConfigLoader { - - /** - * @deprecated This method only exists for backward compatibility. It delegates to {@link - * DriverConfigLoader#fromClasspath(String)}, which you should call directly instead. - */ - @Deprecated - @NonNull - public static DriverConfigLoader fromClasspath(@NonNull String resourceBaseName) { - return DriverConfigLoader.fromClasspath(resourceBaseName); - } - - /** - * @deprecated This method only exists for backward compatibility. It delegates to {@link - * DriverConfigLoader#fromFile(File)}, which you should call directly instead. - */ - @Deprecated - @NonNull - public static DriverConfigLoader fromFile(@NonNull File file) { - return DriverConfigLoader.fromFile(file); - } - - /** - * @deprecated This method only exists for backward compatibility. It delegates to {@link - * DriverConfigLoader#fromUrl(URL)}, which you should call directly instead. - */ - @Deprecated - @NonNull - public static DriverConfigLoader fromUrl(@NonNull URL url) { - return DriverConfigLoader.fromUrl(url); - } - - /** - * @deprecated This method only exists for backward compatibility. It delegates to {@link - * DriverConfigLoader#programmaticBuilder()}, which you should call directly instead. - */ - @Deprecated - @NonNull - public static ProgrammaticDriverConfigLoaderBuilder programmaticBuilder() { - return DriverConfigLoader.programmaticBuilder(); - } - - private DseDriverConfigLoader() { - throw new AssertionError("Not meant to be instantiated"); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/config/DseDriverOption.java b/core/src/main/java/com/datastax/dse/driver/api/core/config/DseDriverOption.java deleted file mode 100644 index 4d10501f6d2..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/config/DseDriverOption.java +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.config; - -import com.datastax.oss.driver.api.core.config.DriverOption; -import edu.umd.cs.findbugs.annotations.NonNull; - -public enum DseDriverOption implements DriverOption { - /** - * The name of the application using the session. - * - *

Value type: {@link String} - */ - APPLICATION_NAME("basic.application.name"), - /** - * The version of the application using the session. - * - *

Value type: {@link String} - */ - APPLICATION_VERSION("basic.application.version"), - - /** - * Proxy authentication for GSSAPI authentication: allows to login as another user or role. - * - *

Value type: {@link String} - */ - AUTH_PROVIDER_AUTHORIZATION_ID("advanced.auth-provider.authorization-id"), - /** - * Service name for GSSAPI authentication. - * - *

Value type: {@link String} - */ - AUTH_PROVIDER_SERVICE("advanced.auth-provider.service"), - /** - * Login configuration for GSSAPI authentication. - * - *

Value type: {@link java.util.Map Map}<{@link String},{@link String}> - */ - AUTH_PROVIDER_LOGIN_CONFIGURATION("advanced.auth-provider.login-configuration"), - /** - * Internal SASL properties, if any, such as QOP, for GSSAPI authentication. - * - *

Value type: {@link java.util.Map Map}<{@link String},{@link String}> - */ - AUTH_PROVIDER_SASL_PROPERTIES("advanced.auth-provider.sasl-properties"), - - /** - * The page size for continuous paging. - * - *

Value type: int - */ - CONTINUOUS_PAGING_PAGE_SIZE("advanced.continuous-paging.page-size"), - /** - * Whether {@link #CONTINUOUS_PAGING_PAGE_SIZE} should be interpreted in number of rows or bytes. - * - *

Value type: boolean - */ - CONTINUOUS_PAGING_PAGE_SIZE_BYTES("advanced.continuous-paging.page-size-in-bytes"), - /** - * The maximum number of continuous pages to return. - * - *

Value type: int - */ - CONTINUOUS_PAGING_MAX_PAGES("advanced.continuous-paging.max-pages"), - /** - * The maximum number of continuous pages per second. - * - *

Value type: int - */ - CONTINUOUS_PAGING_MAX_PAGES_PER_SECOND("advanced.continuous-paging.max-pages-per-second"), - /** - * The maximum number of continuous pages that can be stored in the local queue. - * - *

Value type: int - */ - CONTINUOUS_PAGING_MAX_ENQUEUED_PAGES("advanced.continuous-paging.max-enqueued-pages"), - /** - * How long to wait for the coordinator to send the first continuous page. - * - *

Value-type: {@link java.time.Duration Duration} - */ - CONTINUOUS_PAGING_TIMEOUT_FIRST_PAGE("advanced.continuous-paging.timeout.first-page"), - /** - * How long to wait for the coordinator to send subsequent continuous pages. - * - *

Value-type: {@link java.time.Duration Duration} - */ - CONTINUOUS_PAGING_TIMEOUT_OTHER_PAGES("advanced.continuous-paging.timeout.other-pages"), - - /** - * The largest latency that we expect to record for continuous requests. - * - *

Value-type: {@link java.time.Duration Duration} - */ - CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_HIGHEST( - "advanced.metrics.session.continuous-cql-requests.highest-latency"), - /** - * The number of significant decimal digits to which internal structures will maintain for - * continuous requests. - * - *

Value-type: int - */ - CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_DIGITS( - "advanced.metrics.session.continuous-cql-requests.significant-digits"), - /** - * The interval at which percentile data is refreshed for continuous requests. - * - *

Value-type: {@link java.time.Duration Duration} - */ - CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_INTERVAL( - "advanced.metrics.session.continuous-cql-requests.refresh-interval"), - - /** - * The read consistency level to use for graph statements. - * - *

Value type: {@link String} - */ - GRAPH_READ_CONSISTENCY_LEVEL("basic.graph.read-consistency-level"), - /** - * The write consistency level to use for graph statements. - * - *

Value type: {@link String} - */ - GRAPH_WRITE_CONSISTENCY_LEVEL("basic.graph.write-consistency-level"), - /** - * The traversal source to use for graph statements. - * - *

Value type: {@link String} - */ - GRAPH_TRAVERSAL_SOURCE("basic.graph.traversal-source"), - /** - * The sub-protocol the driver will use to communicate with DSE Graph, on top of the Cassandra - * native protocol. - * - *

Value type: {@link String} - */ - GRAPH_SUB_PROTOCOL("advanced.graph.sub-protocol"), - /** - * Whether a script statement represents a system query. - * - *

Value type: boolean - */ - GRAPH_IS_SYSTEM_QUERY("basic.graph.is-system-query"), - /** - * The name of the graph targeted by graph statements. - * - *

Value type: {@link String} - */ - GRAPH_NAME("basic.graph.name"), - /** - * How long the driver waits for a graph request to complete. - * - *

Value-type: {@link java.time.Duration Duration} - */ - GRAPH_TIMEOUT("basic.graph.timeout"), - - /** - * Whether to send events for Insights monitoring. - * - *

Value type: boolean - */ - MONITOR_REPORTING_ENABLED("advanced.monitor-reporting.enabled"), - - /** - * Whether to enable paging for Graph queries. - * - *

Value type: {@link String} - */ - GRAPH_PAGING_ENABLED("advanced.graph.paging-enabled"), - - /** - * The page size for Graph continuous paging. - * - *

Value type: int - */ - GRAPH_CONTINUOUS_PAGING_PAGE_SIZE("advanced.graph.paging-options.page-size"), - - /** - * The maximum number of Graph continuous pages to return. - * - *

Value type: int - */ - GRAPH_CONTINUOUS_PAGING_MAX_PAGES("advanced.graph.paging-options.max-pages"), - /** - * The maximum number of Graph continuous pages per second. - * - *

Value type: int - */ - GRAPH_CONTINUOUS_PAGING_MAX_PAGES_PER_SECOND( - "advanced.graph.paging-options.max-pages-per-second"), - /** - * The maximum number of Graph continuous pages that can be stored in the local queue. - * - *

Value type: int - */ - GRAPH_CONTINUOUS_PAGING_MAX_ENQUEUED_PAGES("advanced.graph.paging-options.max-enqueued-pages"), - /** - * The largest latency that we expect to record for graph requests. - * - *

Value-type: {@link java.time.Duration Duration} - */ - METRICS_SESSION_GRAPH_REQUESTS_HIGHEST("advanced.metrics.session.graph-requests.highest-latency"), - /** - * The number of significant decimal digits to which internal structures will maintain for graph - * requests. - * - *

Value-type: int - */ - METRICS_SESSION_GRAPH_REQUESTS_DIGITS( - "advanced.metrics.session.graph-requests.significant-digits"), - /** - * The interval at which percentile data is refreshed for graph requests. - * - *

Value-type: {@link java.time.Duration Duration} - */ - METRICS_SESSION_GRAPH_REQUESTS_INTERVAL( - "advanced.metrics.session.graph-requests.refresh-interval"), - /** - * The largest latency that we expect to record for graph requests. - * - *

Value-type: {@link java.time.Duration Duration} - */ - METRICS_NODE_GRAPH_MESSAGES_HIGHEST("advanced.metrics.node.graph-messages.highest-latency"), - /** - * The number of significant decimal digits to which internal structures will maintain for graph - * requests. - * - *

Value-type: int - */ - METRICS_NODE_GRAPH_MESSAGES_DIGITS("advanced.metrics.node.graph-messages.significant-digits"), - /** - * The interval at which percentile data is refreshed for graph requests. - * - *

Value-type: {@link java.time.Duration Duration} - */ - METRICS_NODE_GRAPH_MESSAGES_INTERVAL("advanced.metrics.node.graph-messages.refresh-interval"), - - /** - * The shortest latency that we expect to record for continuous requests. - * - *

Value-type: {@link java.time.Duration Duration} - */ - CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_LOWEST( - "advanced.metrics.session.continuous-cql-requests.lowest-latency"), - /** - * Optional service-level objectives to meet, as a list of latencies to track. - * - *

Value-type: {@link java.time.Duration Duration} - */ - CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_SLO( - "advanced.metrics.session.continuous-cql-requests.slo"), - - /** - * The shortest latency that we expect to record for graph requests. - * - *

Value-type: {@link java.time.Duration Duration} - */ - METRICS_SESSION_GRAPH_REQUESTS_LOWEST("advanced.metrics.session.graph-requests.lowest-latency"), - /** - * Optional service-level objectives to meet, as a list of latencies to track. - * - *

Value-type: {@link java.time.Duration Duration} - */ - METRICS_SESSION_GRAPH_REQUESTS_SLO("advanced.metrics.session.graph-requests.slo"), - - /** - * The shortest latency that we expect to record for graph requests. - * - *

Value-type: {@link java.time.Duration Duration} - */ - METRICS_NODE_GRAPH_MESSAGES_LOWEST("advanced.metrics.node.graph-messages.lowest-latency"), - /** - * Optional service-level objectives to meet, as a list of latencies to track. - * - *

Value-type: {@link java.time.Duration Duration} - */ - METRICS_NODE_GRAPH_MESSAGES_SLO("advanced.metrics.node.graph-messages.slo"), - /** - * Optional list of percentiles to publish for graph-requests metric. Produces an additional time - * series for each requested percentile. This percentile is computed locally, and so can't be - * aggregated with percentiles computed across other dimensions (e.g. in a different instance). - * - *

Value type: {@link java.util.List List}<{@link Double}> - */ - METRICS_SESSION_GRAPH_REQUESTS_PUBLISH_PERCENTILES( - "advanced.metrics.session.graph-requests.publish-percentiles"), - /** - * Optional list of percentiles to publish for node graph-messages metric. Produces an additional - * time series for each requested percentile. This percentile is computed locally, and so can't be - * aggregated with percentiles computed across other dimensions (e.g. in a different instance). - * - *

Value type: {@link java.util.List List}<{@link Double}> - */ - METRICS_NODE_GRAPH_MESSAGES_PUBLISH_PERCENTILES( - "advanced.metrics.node.graph-messages.publish-percentiles"), - /** - * Optional list of percentiles to publish for continuous paging requests metric. Produces an - * additional time series for each requested percentile. This percentile is computed locally, and - * so can't be aggregated with percentiles computed across other dimensions (e.g. in a different - * instance). - * - *

Value type: {@link java.util.List List}<{@link Double}> - */ - CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_PUBLISH_PERCENTILES( - "advanced.metrics.session.continuous-cql-requests.publish-percentiles"), - ; - - private final String path; - - DseDriverOption(String path) { - this.path = path; - } - - @NonNull - @Override - public String getPath() { - return path; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/cql/continuous/ContinuousAsyncResultSet.java b/core/src/main/java/com/datastax/dse/driver/api/core/cql/continuous/ContinuousAsyncResultSet.java deleted file mode 100644 index a9491ec2414..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/cql/continuous/ContinuousAsyncResultSet.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.cql.continuous; - -import com.datastax.oss.driver.api.core.AsyncPagingIterable; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import com.datastax.oss.driver.api.core.cql.Row; -import com.datastax.oss.driver.api.core.cql.Statement; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.nio.ByteBuffer; -import java.util.concurrent.CancellationException; - -/** - * The result of an {@linkplain ContinuousSession#executeContinuouslyAsync(Statement) asynchronous - * continuous paging query}. - * - *

DSE replies to a continuous query with a stream of response frames. There is one instance of - * this class for each frame. - */ -public interface ContinuousAsyncResultSet - extends AsyncPagingIterable { - - /** Returns the current page's number. Pages are numbered starting from 1. */ - int pageNumber(); - - /** - * Cancels the continuous query. - * - *

There might still be rows available in the {@linkplain #currentPage() current page} after - * the cancellation; these rows can be retrieved normally. - * - *

Also, there might be more pages available in the driver's local page cache after the - * cancellation; these extra pages will be discarded. - * - *

Therefore, if you plan to resume the iteration later, the correct procedure is as follows: - * - *

    - *
  1. Cancel the operation by invoking this method, or by cancelling the {@linkplain - * #fetchNextPage() next page's future}; - *
  2. Keep iterating on the current page until it doesn't return any more rows; - *
  3. Retrieve the paging state with {@link #getExecutionInfo() - * getExecutionInfo().getPagingState()}; - *
  4. {@linkplain Statement#setPagingState(ByteBuffer) Re-inject the paging state} in the - * statement; - *
  5. Resume the operation by invoking {@link - * ContinuousSession#executeContinuouslyAsync(Statement) executeContinuouslyAsync} again. - *
- * - * After a cancellation, futures returned by {@link #fetchNextPage()} that are not yet complete - * will always complete exceptionally by throwing a {@link CancellationException}, even if - * they were obtained before the cancellation. - */ - void cancel(); - - /** - * {@inheritDoc} - * - *

Note: because the driver does not support query traces for continuous queries, {@link - * ExecutionInfo#getTracingId()} will always be {@code null}. - */ - @NonNull - @Override - ExecutionInfo getExecutionInfo(); -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/cql/continuous/ContinuousResultSet.java b/core/src/main/java/com/datastax/dse/driver/api/core/cql/continuous/ContinuousResultSet.java deleted file mode 100644 index a333801a59a..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/cql/continuous/ContinuousResultSet.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.cql.continuous; - -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import com.datastax.oss.driver.api.core.cql.ResultSet; -import com.datastax.oss.driver.api.core.cql.Statement; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.nio.ByteBuffer; -import java.util.List; - -/** - * The result of a {@linkplain ContinuousSession#executeContinuously(Statement) synchronous - * continuous paging query}. - * - *

It uses {@linkplain ContinuousAsyncResultSet asynchronous calls} internally, but blocks on the - * results in order to provide a synchronous API to its clients. If the query is paged, only the - * first page will be fetched initially, and iteration will trigger background fetches of the next - * pages when necessary. - * - *

Note that this object can only be iterated once: rows are "consumed" as they are read, - * subsequent calls to {@code iterator()} will return the same iterator instance. - * - *

Implementations of this type are not thread-safe. They can only be iterated by the - * thread that invoked {@code session.executeContinuously}. - */ -public interface ContinuousResultSet extends ResultSet { - - /** - * Cancels the continuous query. - * - *

There might still be rows available in the current page after the cancellation; the - * iteration will only stop when such rows are fully iterated upon. - * - *

Also, there might be more pages available in the driver's local page cache after the - * cancellation; these extra pages will be discarded. - * - *

Therefore, if you plan to resume the iteration later, the correct procedure is as follows: - * - *

    - *
  1. Cancel the operation by invoking this method; - *
  2. Keep iterating on this object until it doesn't return any more rows; - *
  3. Retrieve the paging state with {@link #getExecutionInfo() - * getExecutionInfo().getPagingState()}; - *
  4. {@linkplain Statement#setPagingState(ByteBuffer) Re-inject the paging state} in the - * statement; - *
  5. Resume the operation by invoking {@link ContinuousSession#executeContinuously(Statement) - * executeContinuously} again. - *
- */ - void cancel(); - - /** - * {@inheritDoc} - * - *

Note: because the driver does not support query traces for continuous queries, {@link - * ExecutionInfo#getTracingId()} will always be {@code null}. - */ - @NonNull - @Override - default ExecutionInfo getExecutionInfo() { - List infos = getExecutionInfos(); - return infos.get(infos.size() - 1); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/cql/continuous/ContinuousSession.java b/core/src/main/java/com/datastax/dse/driver/api/core/cql/continuous/ContinuousSession.java deleted file mode 100644 index 1c647b33b92..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/cql/continuous/ContinuousSession.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.cql.continuous; - -import com.datastax.dse.driver.internal.core.cql.continuous.ContinuousCqlRequestAsyncProcessor; -import com.datastax.dse.driver.internal.core.cql.continuous.ContinuousCqlRequestSyncProcessor; -import com.datastax.oss.driver.api.core.DefaultConsistencyLevel; -import com.datastax.oss.driver.api.core.cql.Statement; -import com.datastax.oss.driver.api.core.loadbalancing.LoadBalancingPolicy; -import com.datastax.oss.driver.api.core.metadata.token.Token; -import com.datastax.oss.driver.api.core.session.Session; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.nio.ByteBuffer; -import java.util.Objects; -import java.util.concurrent.CompletionStage; - -/** - * A session that has the ability to execute continuous paging queries. - * - *

Continuous paging is a new method of streaming bulk amounts of records from DataStax - * Enterprise (DSE) to the Java Driver, available since DSE 5.1. It is mainly intended to be - * leveraged by DSE - * Analytics and Apache Spark™, or by any similar analytics tool that needs to read large - * portions of a table in one single operation, as quick and reliably as possible. - * - *

Continuous paging provides the best performance improvement against regular paging when the - * following conditions are met: - * - *

    - *
  1. The statement must target a single partition or a token range owned by one single replica; - * in practice, this means that the statement must have either a {@linkplain - * Statement#setRoutingKey(ByteBuffer) routing key} or a {@linkplain - * Statement#setRoutingToken(Token) routing token} set; - *
  2. The coordinator must be a replica; in practice, this is usually achieved by using - * token-aware routing (if you are using the driver's default {@link LoadBalancingPolicy}, - * then this condition is met); - *
  3. The consistency level must be {@link DefaultConsistencyLevel#ONE ONE} (or {@link - * DefaultConsistencyLevel#LOCAL_ONE LOCAL_ONE}). - *
- * - *

If the above conditions are met, the coordinator will be able to optimize the read path and - * serve results from local data, thus significantly improving response times; if however these - * conditions cannot be met, continuous paging would still work, but response times wouldn't be - * significantly better than those of regular paging anymore. - * - * @see Continuous - * paging options in cassandra.yaml configuration file - * @see DSE - * Continuous Paging Tuning and Support Guide - */ -public interface ContinuousSession extends Session { - - /** - * Executes the provided query with continuous paging synchronously. - * - *

This method takes care of chaining the successive results into a convenient iterable, - * provided that you always access the result from the same thread. For more flexibility, consider - * using the {@linkplain #executeContinuouslyAsync(Statement) asynchronous variant} of this method - * instead. - * - *

See {@link ContinuousSession} for more explanations about continuous paging. - * - *

This feature is only available with DataStax Enterprise. Executing continuous queries - * against an Apache Cassandra© cluster will result in a runtime error. - * - * @param statement the query to execute. - * @return a synchronous iterable on the results. - */ - @NonNull - default ContinuousResultSet executeContinuously(@NonNull Statement statement) { - return Objects.requireNonNull( - execute(statement, ContinuousCqlRequestSyncProcessor.CONTINUOUS_RESULT_SYNC)); - } - - /** - * Executes the provided query with continuous paging asynchronously. - * - *

The server will push all requested pages asynchronously, according to the options defined in - * the current execution profile. The client should consume all pages as quickly as possible, to - * avoid blocking the server for too long. The server will adjust the rate according to the client - * speed, but it will give up if the client does not consume any pages in a period of time equal - * to the read request timeout. - * - *

See {@link ContinuousSession} for more explanations about continuous paging. - * - *

This feature is only available with DataStax Enterprise. Executing continuous queries - * against an Apache Cassandra© cluster will result in a runtime error. - * - * @param statement the query to execute. - * @return a future to the first asynchronous result. - */ - @NonNull - default CompletionStage executeContinuouslyAsync( - @NonNull Statement statement) { - return Objects.requireNonNull( - execute(statement, ContinuousCqlRequestAsyncProcessor.CONTINUOUS_RESULT_ASYNC)); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/cql/continuous/reactive/ContinuousReactiveResultSet.java b/core/src/main/java/com/datastax/dse/driver/api/core/cql/continuous/reactive/ContinuousReactiveResultSet.java deleted file mode 100644 index 6b645ad05bf..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/cql/continuous/reactive/ContinuousReactiveResultSet.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.cql.continuous.reactive; - -import com.datastax.dse.driver.api.core.cql.reactive.ReactiveResultSet; -import com.datastax.oss.driver.api.core.cql.Statement; - -/** - * A marker interface for publishers returned by {@link ContinuousReactiveSession}. - * - * @see ContinuousReactiveSession#executeContinuouslyReactive(String) - * @see ContinuousReactiveSession#executeContinuouslyReactive(Statement) - */ -public interface ContinuousReactiveResultSet extends ReactiveResultSet {} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/cql/continuous/reactive/ContinuousReactiveSession.java b/core/src/main/java/com/datastax/dse/driver/api/core/cql/continuous/reactive/ContinuousReactiveSession.java deleted file mode 100644 index d00013731cb..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/cql/continuous/reactive/ContinuousReactiveSession.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.cql.continuous.reactive; - -import com.datastax.dse.driver.api.core.cql.continuous.ContinuousSession; -import com.datastax.dse.driver.api.core.cql.reactive.ReactiveRow; -import com.datastax.dse.driver.internal.core.cql.continuous.reactive.ContinuousCqlRequestReactiveProcessor; -import com.datastax.oss.driver.api.core.cql.SimpleStatement; -import com.datastax.oss.driver.api.core.cql.Statement; -import com.datastax.oss.driver.api.core.session.Session; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Objects; -import org.reactivestreams.Publisher; - -/** - * A {@link Session} that offers utility methods to issue queries using reactive-style programming - * and continuous paging, combined together. - * - *

Methods in this interface all return {@link ContinuousReactiveResultSet} instances. All - * publishers support multiple subscriptions in a unicast fashion: each subscriber triggers an - * independent request execution and gets its own copy of the results. - * - *

Also, note that the publishers may emit items to their subscribers on an internal driver IO - * thread. Subscriber implementors are encouraged to abide by Reactive Streams - * Specification rule 2.2 and avoid performing heavy computations or blocking calls inside - * {@link org.reactivestreams.Subscriber#onNext(Object) onNext} calls, as doing so could slow down - * the driver and impact performance. Instead, they should asynchronously dispatch received signals - * to their processing logic. - * - * @see ReactiveRow - */ -public interface ContinuousReactiveSession extends Session { - - /** - * Returns a {@link Publisher} that, once subscribed to, executes the given query continuously and - * emits all the results. - * - *

See {@link ContinuousSession} for more explanations about continuous paging. - * - *

This feature is only available with DataStax Enterprise. Executing continuous queries - * against an Apache Cassandra® cluster will result in a runtime error. - * - * @param query the query to execute. - * @return The {@link Publisher} that will publish the returned results. - */ - @NonNull - default ContinuousReactiveResultSet executeContinuouslyReactive(@NonNull String query) { - return executeContinuouslyReactive(SimpleStatement.newInstance(query)); - } - - /** - * Returns a {@link Publisher} that, once subscribed to, executes the given query continuously and - * emits all the results. - * - *

See {@link ContinuousSession} for more explanations about continuous paging. - * - *

This feature is only available with DataStax Enterprise. Executing continuous queries - * against an Apache Cassandra® cluster will result in a runtime error. - * - * @param statement the statement to execute. - * @return The {@link Publisher} that will publish the returned results. - */ - @NonNull - default ContinuousReactiveResultSet executeContinuouslyReactive(@NonNull Statement statement) { - return Objects.requireNonNull( - execute(statement, ContinuousCqlRequestReactiveProcessor.CONTINUOUS_REACTIVE_RESULT_SET)); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/cql/reactive/package-info.java b/core/src/main/java/com/datastax/dse/driver/api/core/cql/reactive/package-info.java index 01a5f514aba..bb9d4dd53c9 100644 --- a/core/src/main/java/com/datastax/dse/driver/api/core/cql/reactive/package-info.java +++ b/core/src/main/java/com/datastax/dse/driver/api/core/cql/reactive/package-info.java @@ -18,7 +18,7 @@ /** * Types related to CQL execution using reactive-style programming. * - *

Note that this is located in a {@code dse} package for historical reasons; reactive queries - * can now be used with open-source Cassandra as well. + *

This package keeps its historical {@code dse} namespace for API compatibility. Its reactive + * queries are generic and supported with Cassandra and Scylla. */ package com.datastax.dse.driver.api.core.cql.reactive; diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/data/geometry/Geometry.java b/core/src/main/java/com/datastax/dse/driver/api/core/data/geometry/Geometry.java deleted file mode 100644 index 66a5708832e..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/data/geometry/Geometry.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.data.geometry; - -import edu.umd.cs.findbugs.annotations.NonNull; -import java.nio.ByteBuffer; - -/** - * The driver-side representation for a DSE geospatial type. - * - *

- *     Row row = dseSession.execute("SELECT coords FROM points_of_interest WHERE name = 'Eiffel Tower'").one();
- *     Point coords = row.get("coords", Point.class);
- * 
- * - * The default implementations returned by the driver are immutable and serializable. If you write - * your own implementations, they should at least be thread-safe; serializability is not mandatory, - * but recommended for use with some 3rd-party tools like Apache Spark ™. - */ -public interface Geometry { - - /** - * Returns a Well-known Text (WKT) - * representation of this geospatial type. - */ - @NonNull - String asWellKnownText(); - - /** - * Returns a Well-known - * Binary (WKB) representation of this geospatial type. - * - *

Note that, due to DSE implementation details, the resulting byte buffer always uses - * little-endian order, regardless of the platform's native order. - */ - @NonNull - ByteBuffer asWellKnownBinary(); - - /** Returns a JSON representation of this geospatial type. */ - @NonNull - String asGeoJson(); - - /** - * Tests whether this geospatial type instance contains another instance. - * - * @param other the other instance. - * @return whether {@code this} contains {@code other}. - */ - boolean contains(@NonNull Geometry other); -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/data/geometry/LineString.java b/core/src/main/java/com/datastax/dse/driver/api/core/data/geometry/LineString.java deleted file mode 100644 index 7f77b3202a2..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/data/geometry/LineString.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.data.geometry; - -import com.datastax.dse.driver.internal.core.data.geometry.DefaultGeometry; -import com.datastax.dse.driver.internal.core.data.geometry.DefaultLineString; -import com.esri.core.geometry.ogc.OGCLineString; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.nio.ByteBuffer; -import java.util.List; - -/** - * The driver-side representation for DSE's {@code LineString}. - * - *

This is a curve in a two-dimensional XY-plane, represented by a set of points (with linear - * interpolation between them). - * - *

The default implementation returned by the driver is immutable. - */ -public interface LineString extends Geometry { - /** - * Creates a line string from its Well-known Text (WKT) representation. - * - * @param source the Well-known Text representation to parse. - * @return the line string represented by the WKT. - * @throws IllegalArgumentException if the string does not contain a valid Well-known Text - * representation. - */ - @NonNull - static LineString fromWellKnownText(@NonNull String source) { - return new DefaultLineString(DefaultGeometry.fromOgcWellKnownText(source, OGCLineString.class)); - } - - /** - * Creates a line string from its Well-known Binary - * (WKB) representation. - * - * @param source the Well-known Binary representation to parse. - * @return the line string represented by the WKB. - * @throws IllegalArgumentException if the provided {@link ByteBuffer} does not contain a valid - * Well-known Binary representation. - */ - @NonNull - static LineString fromWellKnownBinary(@NonNull ByteBuffer source) { - return new DefaultLineString( - DefaultGeometry.fromOgcWellKnownBinary(source, OGCLineString.class)); - } - - /** - * Creates a line string from a GeoJSON - * LineString representation. - * - * @param source the GeoJSON - * LineString representation to parse. - * @return the line string represented by the GeoJSON LineString. - * @throws IllegalArgumentException if the string does not contain a valid GeoJSON LineString - * representation. - */ - @NonNull - static LineString fromGeoJson(@NonNull String source) { - return new DefaultLineString(DefaultGeometry.fromOgcGeoJson(source, OGCLineString.class)); - } - - /** Creates a line string from two or more points. */ - @NonNull - static LineString fromPoints(@NonNull Point p1, @NonNull Point p2, @NonNull Point... pn) { - return new DefaultLineString(p1, p2, pn); - } - - @NonNull - List getPoints(); -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/data/geometry/Point.java b/core/src/main/java/com/datastax/dse/driver/api/core/data/geometry/Point.java deleted file mode 100644 index b064b3fb222..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/data/geometry/Point.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.data.geometry; - -import com.datastax.dse.driver.internal.core.data.geometry.DefaultGeometry; -import com.datastax.dse.driver.internal.core.data.geometry.DefaultPoint; -import com.esri.core.geometry.ogc.OGCPoint; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.nio.ByteBuffer; - -/** - * The driver-side representation of DSE's {@code Point}. - * - *

This is a zero-dimensional object that represents a specific (X,Y) location in a - * two-dimensional XY-plane. In case of Geographic Coordinate Systems, the X coordinate is the - * longitude and the Y is the latitude. - * - *

The default implementation returned by the driver is immutable. - */ -public interface Point extends Geometry { - - /** - * Creates a point from its Well-known - * Text (WKT) representation. - * - * @param source the Well-known Text representation to parse. - * @return the point represented by the WKT. - * @throws IllegalArgumentException if the string does not contain a valid Well-known Text - * representation. - */ - @NonNull - static Point fromWellKnownText(@NonNull String source) { - return new DefaultPoint(DefaultGeometry.fromOgcWellKnownText(source, OGCPoint.class)); - } - - /** - * Creates a point from its Well-known Binary - * (WKB) representation. - * - * @param source the Well-known Binary representation to parse. - * @return the point represented by the WKB. - * @throws IllegalArgumentException if the provided {@link ByteBuffer} does not contain a valid - * Well-known Binary representation. - */ - @NonNull - static Point fromWellKnownBinary(@NonNull ByteBuffer source) { - return new DefaultPoint(DefaultGeometry.fromOgcWellKnownBinary(source, OGCPoint.class)); - } - - /** - * Creates a point from a GeoJSON - * Point representation. - * - * @param source the GeoJSON Point - * representation to parse. - * @return the point represented by the GeoJSON Point. - * @throws IllegalArgumentException if the string does not contain a valid GeoJSON Point representation. - */ - @NonNull - static Point fromGeoJson(@NonNull String source) { - return new DefaultPoint(DefaultGeometry.fromOgcGeoJson(source, OGCPoint.class)); - } - - /** - * Creates a new point. - * - * @param x The X coordinate of this point (or its longitude in Geographic Coordinate Systems). - * @param y The Y coordinate of this point (or its latitude in Geographic Coordinate Systems). - * @return the point represented by coordinates. - */ - @NonNull - static Point fromCoordinates(double x, double y) { - return new DefaultPoint(x, y); - } - - /** - * Returns the X coordinate of this 2D point (or its longitude in Geographic Coordinate Systems). - */ - double X(); - - /** - * Returns the Y coordinate of this 2D point (or its latitude in Geographic Coordinate Systems). - */ - double Y(); -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/data/geometry/Polygon.java b/core/src/main/java/com/datastax/dse/driver/api/core/data/geometry/Polygon.java deleted file mode 100644 index d793704defa..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/data/geometry/Polygon.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.data.geometry; - -import com.datastax.dse.driver.internal.core.data.geometry.DefaultGeometry; -import com.datastax.dse.driver.internal.core.data.geometry.DefaultPolygon; -import com.esri.core.geometry.ogc.OGCPolygon; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.nio.ByteBuffer; -import java.util.List; - -/** - * The driver-side representation of DSE's {@code Polygon}. - * - *

This is a planar surface in a two-dimensional XY-plane, represented by one exterior boundary - * and 0 or more interior boundaries. - * - *

The default implementation returned by the driver is immutable. - */ -public interface Polygon extends Geometry { - /** - * Creates a polygon from its Well-known - * Text (WKT) representation. - * - * @param source the Well-known Text representation to parse. - * @return the polygon represented by the WKT. - * @throws IllegalArgumentException if the string does not contain a valid Well-known Text - * representation. - */ - @NonNull - static Polygon fromWellKnownText(@NonNull String source) { - return new DefaultPolygon(DefaultGeometry.fromOgcWellKnownText(source, OGCPolygon.class)); - } - - /** - * Creates a polygon from its Well-known Binary - * (WKB) representation. - * - * @param source the Well-known Binary representation to parse. - * @return the polygon represented by the WKB. - * @throws IllegalArgumentException if the provided {@link ByteBuffer} does not contain a valid - * Well-known Binary representation. - */ - @NonNull - static Polygon fromWellKnownBinary(@NonNull ByteBuffer source) { - return new DefaultPolygon(DefaultGeometry.fromOgcWellKnownBinary(source, OGCPolygon.class)); - } - - /** - * Creates a polygon from a GeoJSON - * Polygon representation. - * - * @param source the GeoJSON Polygon - * representation to parse. - * @return the polygon represented by the GeoJSON Polygon. - * @throws IllegalArgumentException if the string does not contain a valid GeoJSON Polygon representation. - */ - @NonNull - static Polygon fromGeoJson(@NonNull String source) { - return new DefaultPolygon(DefaultGeometry.fromOgcGeoJson(source, OGCPolygon.class)); - } - - /** Creates a polygon from a series of 3 or more points. */ - @NonNull - static Polygon fromPoints( - @NonNull Point p1, @NonNull Point p2, @NonNull Point p3, @NonNull Point... pn) { - return new DefaultPolygon(p1, p2, p3, pn); - } - - /** - * Returns a polygon builder. - * - *

This is intended for complex polygons with multiple rings (i.e. holes inside the polygon). - * For simple cases, consider {@link #fromPoints(Point, Point, Point, Point...)} instead. - */ - @NonNull - static Builder builder() { - return new DefaultPolygon.Builder(); - } - - /** Returns the external ring of the polygon. */ - @NonNull - List getExteriorRing(); - - /** - * Returns the internal rings of the polygon, i.e. any holes inside of it (or islands inside of - * the holes). - */ - @NonNull - List> getInteriorRings(); - - /** Provides a simple DSL to build a polygon. */ - interface Builder { - /** - * Adds a new ring for this polygon. - * - *

There can be one or more outer rings and zero or more inner rings. If a polygon has an - * inner ring, the inner ring looks like a hole. If the hole contains another outer ring, that - * outer ring looks like an island. - * - *

There must be one "main" outer ring that contains all the others. - */ - @NonNull - Builder addRing(@NonNull Point p1, @NonNull Point p2, @NonNull Point p3, @NonNull Point... pn); - - @NonNull - Polygon build(); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/data/time/DateRange.java b/core/src/main/java/com/datastax/dse/driver/api/core/data/time/DateRange.java deleted file mode 100644 index 3dd48915dba..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/data/time/DateRange.java +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.data.time; - -import com.datastax.oss.driver.shaded.guava.common.base.Preconditions; -import com.datastax.oss.driver.shaded.guava.common.base.Strings; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.io.Serializable; -import java.text.ParseException; -import java.time.ZonedDateTime; -import java.util.Objects; -import java.util.Optional; - -/** - * A date range, as defined by the server type {@code - * org.apache.cassandra.db.marshal.DateRangeType}, corresponding to the Apache Solr type {@code - * DateRangeField}. - * - *

A date range can be either {@linkplain DateRange#DateRange(DateRangeBound) single-bounded}, in - * which case it represents a unique instant (e.g. "{@code 2001-01-01}"), or {@linkplain - * #DateRange(DateRangeBound, DateRangeBound) double-bounded}, in which case it represents an - * interval of time (e.g. "{@code [2001-01-01 TO 2002]}"). - * - *

Date range {@linkplain DateRangeBound bounds} are always inclusive; they must be either valid - * dates, or the special value {@link DateRangeBound#UNBOUNDED UNBOUNDED}, represented by a "{@code - * *}", e.g. "{@code [2001 TO *]}". - * - *

Instances can be more easily created with the {@link #parse(String)} method. - * - *

This class is immutable and thread-safe. - * - * @since DSE 5.1 - */ -public class DateRange implements Serializable { - - /** - * Parses the given string as a date range. - * - *

The given input must be compliant with Apache Solr type {@code - * DateRangeField} syntax; it can either be a {@linkplain #DateRange(DateRangeBound) - * single-bounded range}, or a {@linkplain #DateRange(DateRangeBound, DateRangeBound) - * double-bounded range}. - * - * @throws ParseException if the given string could not be parsed into a valid range. - * @see DateRangeBound#parseLowerBound(String) - * @see DateRangeBound#parseUpperBound(String) - */ - @NonNull - public static DateRange parse(@NonNull String source) throws ParseException { - if (Strings.isNullOrEmpty(source)) { - throw new ParseException("Date range is null or empty", 0); - } - - if (source.charAt(0) == '[') { - if (source.charAt(source.length() - 1) != ']') { - throw new ParseException( - "If date range starts with '[' it must end with ']'; got " + source, - source.length() - 1); - } - int middle = source.indexOf(" TO "); - if (middle < 0) { - throw new ParseException( - "If date range starts with '[' it must contain ' TO '; got " + source, 0); - } - String lowerBoundString = source.substring(1, middle); - int upperBoundStart = middle + 4; - String upperBoundString = source.substring(upperBoundStart, source.length() - 1); - DateRangeBound lowerBound; - try { - lowerBound = DateRangeBound.parseLowerBound(lowerBoundString); - } catch (Exception e) { - throw newParseException("Cannot parse date range lower bound: " + source, 1, e); - } - DateRangeBound upperBound; - try { - upperBound = DateRangeBound.parseUpperBound(upperBoundString); - } catch (Exception e) { - throw newParseException( - "Cannot parse date range upper bound: " + source, upperBoundStart, e); - } - return new DateRange(lowerBound, upperBound); - } else { - try { - return new DateRange(DateRangeBound.parseLowerBound(source)); - } catch (Exception e) { - throw newParseException("Cannot parse single date range bound: " + source, 0, e); - } - } - } - - @NonNull private final DateRangeBound lowerBound; - @Nullable private final DateRangeBound upperBound; - - /** - * Creates a "single bounded" instance, i.e., a date range whose upper and lower bounds are - * identical. - * - * @throws NullPointerException if {@code singleBound} is null. - */ - public DateRange(@NonNull DateRangeBound singleBound) { - this.lowerBound = Preconditions.checkNotNull(singleBound, "singleBound cannot be null"); - this.upperBound = null; - } - - /** - * Creates an instance composed of two distinct bounds. - * - * @throws NullPointerException if {@code lowerBound} or {@code upperBound} is null. - * @throws IllegalArgumentException if both {@code lowerBound} and {@code upperBound} are not - * unbounded and {@code lowerBound} is greater than {@code upperBound}. - */ - public DateRange(@NonNull DateRangeBound lowerBound, @NonNull DateRangeBound upperBound) { - Preconditions.checkNotNull(lowerBound, "lowerBound cannot be null"); - Preconditions.checkNotNull(upperBound, "upperBound cannot be null"); - if (!lowerBound.isUnbounded() - && !upperBound.isUnbounded() - && lowerBound.getTimestamp().compareTo(upperBound.getTimestamp()) >= 0) { - throw new IllegalArgumentException( - String.format( - "Lower bound of a date range should be before upper bound, got: [%s TO %s]", - lowerBound, upperBound)); - } - this.lowerBound = lowerBound; - this.upperBound = upperBound; - } - - /** Returns the lower bound of this range (inclusive). */ - @NonNull - public DateRangeBound getLowerBound() { - return lowerBound; - } - - /** - * Returns the upper bound of this range (inclusive), or empty if the range is {@linkplain - * #isSingleBounded() single-bounded}. - */ - @NonNull - public Optional getUpperBound() { - return Optional.ofNullable(upperBound); - } - - /** - * Returns whether this range is single-bounded, i.e. if the upper and lower bounds are identical. - */ - public boolean isSingleBounded() { - return upperBound == null; - } - - /** - * Returns the string representation of this range, in a format compatible with Apache Solr - * DateRageField syntax - * - * @see DateRangeBound#toString() - */ - @NonNull - @Override - public String toString() { - if (isSingleBounded()) { - return lowerBound.toString(); - } else { - return String.format("[%s TO %s]", lowerBound, upperBound); - } - } - - @Override - public boolean equals(@Nullable Object other) { - if (other == this) { - return true; - } else if (other instanceof DateRange) { - DateRange that = (DateRange) other; - return Objects.equals(this.lowerBound, that.lowerBound) - && Objects.equals(this.upperBound, that.upperBound); - - } else { - return false; - } - } - - @Override - public int hashCode() { - return Objects.hash(lowerBound, upperBound); - } - - private static ParseException newParseException(String message, int offset, Exception cause) { - ParseException parseException = new ParseException(message, offset); - parseException.initCause(cause); - return parseException; - } - - /** - * This object gets replaced by an internal proxy for serialization. - * - * @serialData the lower bound timestamp and precision, followed by the upper bound timestamp and - * precision, or two {@code null}s if the range is single-bounded. - */ - private Object writeReplace() { - return new SerializationProxy(this); - } - - private static class SerializationProxy implements Serializable { - - private static final long serialVersionUID = 1L; - - private final ZonedDateTime lowerBoundTimestamp; - private final DateRangePrecision lowerBoundPrecision; - private final ZonedDateTime upperBoundTimestamp; - private final DateRangePrecision upperBoundPrecision; - - SerializationProxy(DateRange input) { - this.lowerBoundTimestamp = input.lowerBound.getTimestamp(); - this.lowerBoundPrecision = input.lowerBound.getPrecision(); - if (input.upperBound != null) { - this.upperBoundTimestamp = input.upperBound.getTimestamp(); - this.upperBoundPrecision = input.upperBound.getPrecision(); - } else { - this.upperBoundTimestamp = null; - this.upperBoundPrecision = null; - } - } - - private Object readResolve() { - if (upperBoundTimestamp == null ^ upperBoundPrecision == null) { - // Should not happen, but protect against corrupted streams - throw new IllegalArgumentException( - "Invalid serialized form, upper bound timestamp and precision " - + "should be either both null or both non-null"); - } - - if (upperBoundTimestamp == null) { - return new DateRange(DateRangeBound.lowerBound(lowerBoundTimestamp, lowerBoundPrecision)); - } else { - return new DateRange( - DateRangeBound.lowerBound(lowerBoundTimestamp, lowerBoundPrecision), - DateRangeBound.upperBound(upperBoundTimestamp, upperBoundPrecision)); - } - } - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/data/time/DateRangeBound.java b/core/src/main/java/com/datastax/dse/driver/api/core/data/time/DateRangeBound.java deleted file mode 100644 index 1621b8bf742..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/data/time/DateRangeBound.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.data.time; - -import com.datastax.dse.driver.internal.core.search.DateRangeUtil; -import com.datastax.oss.driver.shaded.guava.common.base.Preconditions; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.text.ParseException; -import java.time.ZonedDateTime; -import java.util.Calendar; -import java.util.Objects; - -/** - * A date range bound. - * - *

It is composed of a {@link ZonedDateTime} field and a corresponding {@link - * DateRangePrecision}. - * - *

Date range bounds are inclusive. The special value {@link #UNBOUNDED} denotes an un unbounded - * (infinite) bound, represented by a {@code *} sign. - * - *

This class is immutable and thread-safe. - */ -public class DateRangeBound { - - /** - * The unbounded {@link DateRangeBound} instance. It is syntactically represented by a {@code *} - * (star) sign. - */ - public static final DateRangeBound UNBOUNDED = new DateRangeBound(); - - /** - * Parses the given input as a lower date range bound. - * - *

The input should be a Lucene-compliant - * string. - * - *

The returned bound will have its {@linkplain DateRangePrecision precision} inferred from the - * input, and its timestamp will be {@linkplain DateRangePrecision#roundDown(ZonedDateTime) - * rounded down} to that precision. - * - *

Note that, in order to align with the server's parsing behavior, dates will always be parsed - * in the UTC time zone. - * - * @throws NullPointerException if {@code lowerBound} is {@code null}. - * @throws ParseException if the given input cannot be parsed. - */ - @NonNull - public static DateRangeBound parseLowerBound(@NonNull String source) throws ParseException { - Preconditions.checkNotNull(source); - Calendar calendar = DateRangeUtil.parseCalendar(source); - DateRangePrecision precision = DateRangeUtil.getPrecision(calendar); - return (precision == null) - ? UNBOUNDED - : lowerBound(DateRangeUtil.toZonedDateTime(calendar), precision); - } - - /** - * Parses the given input as an upper date range bound. - * - *

The input should be a Lucene-compliant - * string. - * - *

The returned bound will have its {@linkplain DateRangePrecision precision} inferred from the - * input, and its timestamp will be {@linkplain DateRangePrecision#roundUp(ZonedDateTime)} rounded - * up} to that precision. - * - *

Note that, in order to align with the server's behavior (e.g. when using date range literals - * in CQL query strings), dates must always be in the UTC time zone: an optional trailing {@code - * Z}" is allowed, but no other time zone ID (not even {@code UTC}, {@code GMT} or {@code +00:00}) - * is permitted. - * - * @throws NullPointerException if {@code upperBound} is {@code null}. - * @throws ParseException if the given input cannot be parsed. - */ - public static DateRangeBound parseUpperBound(String source) throws ParseException { - Preconditions.checkNotNull(source); - Calendar calendar = DateRangeUtil.parseCalendar(source); - DateRangePrecision precision = DateRangeUtil.getPrecision(calendar); - return (precision == null) - ? UNBOUNDED - : upperBound(DateRangeUtil.toZonedDateTime(calendar), precision); - } - - /** - * Creates a date range lower bound from the given date and precision. Temporal fields smaller - * than the precision will be rounded down. - */ - public static DateRangeBound lowerBound(ZonedDateTime timestamp, DateRangePrecision precision) { - return new DateRangeBound(precision.roundDown(timestamp), precision); - } - - /** - * Creates a date range upper bound from the given date and precision. Temporal fields smaller - * than the precision will be rounded up. - */ - public static DateRangeBound upperBound(ZonedDateTime timestamp, DateRangePrecision precision) { - return new DateRangeBound(precision.roundUp(timestamp), precision); - } - - @Nullable private final ZonedDateTime timestamp; - @Nullable private final DateRangePrecision precision; - - private DateRangeBound(@NonNull ZonedDateTime timestamp, @NonNull DateRangePrecision precision) { - Preconditions.checkNotNull(timestamp); - Preconditions.checkNotNull(precision); - this.timestamp = timestamp; - this.precision = precision; - } - - // constructor used for the special UNBOUNDED value - private DateRangeBound() { - this.timestamp = null; - this.precision = null; - } - - /** Whether this bound is unbounded (i.e. denotes the special {@code *} value). */ - public boolean isUnbounded() { - return this.timestamp == null && this.precision == null; - } - - /** - * Returns the timestamp of this bound. - * - * @throws IllegalStateException if this bound is {@linkplain #isUnbounded() unbounded}. - */ - @NonNull - public ZonedDateTime getTimestamp() { - if (isUnbounded()) { - throw new IllegalStateException( - "Can't call this method on UNBOUNDED, use isUnbounded() to check first"); - } - assert timestamp != null; - return timestamp; - } - - /** - * Returns the precision of this bound. - * - * @throws IllegalStateException if this bound is {@linkplain #isUnbounded() unbounded}. - */ - @NonNull - public DateRangePrecision getPrecision() { - if (isUnbounded()) { - throw new IllegalStateException( - "Can't call this method on UNBOUNDED, use isUnbounded() to check first"); - } - assert precision != null; - return precision; - } - - /** - * Returns this bound as a Lucene-compliant string. - * - *

Unbounded bounds always return "{@code *}"; all other bounds are formatted in one of the - * common ISO-8601 datetime formats, depending on their precision. - * - *

Note that Lucene expects timestamps in UTC only. Timezone presence is always optional, and - * if present, it must be expressed with the symbol "Z" exclusively. Therefore this method does - * not include any timezone information in the returned string, except for bounds with {@linkplain - * DateRangePrecision#MILLISECOND millisecond} precision, where the symbol "Z" is always appended - * to the resulting string. - */ - @NonNull - @Override - public String toString() { - if (isUnbounded()) { - return "*"; - } else { - assert timestamp != null && precision != null; - return precision.format(timestamp); - } - } - - @Override - public boolean equals(@Nullable Object other) { - if (other == this) { - return true; - } else if (other instanceof DateRangeBound) { - DateRangeBound that = (DateRangeBound) other; - return Objects.equals(this.timestamp, that.timestamp) - && Objects.equals(this.precision, that.precision); - } else { - return false; - } - } - - @Override - public int hashCode() { - return Objects.hash(timestamp, precision); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/data/time/DateRangePrecision.java b/core/src/main/java/com/datastax/dse/driver/api/core/data/time/DateRangePrecision.java deleted file mode 100644 index a0b5d0e5500..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/data/time/DateRangePrecision.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.data.time; - -import com.datastax.dse.driver.internal.core.search.DateRangeUtil; -import com.datastax.oss.driver.shaded.guava.common.base.Preconditions; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; -import java.time.format.DateTimeFormatterBuilder; -import java.time.temporal.ChronoField; -import java.time.temporal.ChronoUnit; -import java.util.Locale; -import java.util.Map; - -/** The precision of a {@link DateRangeBound}. */ -public enum DateRangePrecision { - MILLISECOND( - 0x06, - ChronoUnit.MILLIS, - new DateTimeFormatterBuilder() - .parseCaseSensitive() - .parseStrict() - .appendPattern("uuuu-MM-dd'T'HH:mm:ss.SSS") - .optionalStart() - .appendZoneId() - .optionalEnd() - .toFormatter() - .withZone(ZoneOffset.UTC) - .withLocale(Locale.ROOT)), - SECOND( - 0x05, - ChronoUnit.SECONDS, - new DateTimeFormatterBuilder() - .parseCaseSensitive() - .parseStrict() - .appendPattern("uuuu-MM-dd'T'HH:mm:ss") - .parseDefaulting(ChronoField.MILLI_OF_SECOND, 0) - .toFormatter() - .withZone(ZoneOffset.UTC) - .withLocale(Locale.ROOT)), - MINUTE( - 0x04, - ChronoUnit.MINUTES, - new DateTimeFormatterBuilder() - .parseCaseSensitive() - .parseStrict() - .appendPattern("uuuu-MM-dd'T'HH:mm") - .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0) - .parseDefaulting(ChronoField.MILLI_OF_SECOND, 0) - .toFormatter() - .withZone(ZoneOffset.UTC) - .withLocale(Locale.ROOT)), - HOUR( - 0x03, - ChronoUnit.HOURS, - new DateTimeFormatterBuilder() - .parseCaseSensitive() - .parseStrict() - .appendPattern("uuuu-MM-dd'T'HH") - .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0) - .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0) - .parseDefaulting(ChronoField.MILLI_OF_SECOND, 0) - .toFormatter() - .withZone(ZoneOffset.UTC) - .withLocale(Locale.ROOT)), - DAY( - 0x02, - ChronoUnit.DAYS, - new DateTimeFormatterBuilder() - .parseCaseSensitive() - .parseStrict() - .appendPattern("uuuu-MM-dd") - .parseDefaulting(ChronoField.HOUR_OF_DAY, 0) - .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0) - .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0) - .parseDefaulting(ChronoField.MILLI_OF_SECOND, 0) - .toFormatter() - .withZone(ZoneOffset.UTC) - .withLocale(Locale.ROOT)), - MONTH( - 0x01, - ChronoUnit.MONTHS, - new DateTimeFormatterBuilder() - .parseCaseSensitive() - .parseStrict() - .appendPattern("uuuu-MM") - .parseDefaulting(ChronoField.DAY_OF_MONTH, 1) - .parseDefaulting(ChronoField.HOUR_OF_DAY, 0) - .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0) - .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0) - .parseDefaulting(ChronoField.MILLI_OF_SECOND, 0) - .toFormatter() - .withZone(ZoneOffset.UTC) - .withLocale(Locale.ROOT)), - YEAR( - 0x00, - ChronoUnit.YEARS, - new DateTimeFormatterBuilder() - .parseCaseSensitive() - .parseStrict() - .appendPattern("uuuu") - .parseDefaulting(ChronoField.MONTH_OF_YEAR, 1) - .parseDefaulting(ChronoField.DAY_OF_MONTH, 1) - .parseDefaulting(ChronoField.HOUR_OF_DAY, 0) - .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0) - .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0) - .parseDefaulting(ChronoField.MILLI_OF_SECOND, 0) - .toFormatter() - .withZone(ZoneOffset.UTC) - .withLocale(Locale.ROOT)); - - private final byte encoding; - private final ChronoUnit roundingUnit; - // The formatter is only used for formatting (parsing is done with DateRangeUtil.parseCalendar to - // be exactly the same as DSE's). - // If that ever were to change, note that DateTimeFormatters with a time zone had a parsing bug - // on older JDKs: the formatter's zone would always be used, even if the input string specified - // one explicitly. - // See https://stackoverflow.com/questions/41999421 - private final DateTimeFormatter formatter; - - DateRangePrecision(int encoding, ChronoUnit roundingUnit, DateTimeFormatter formatter) { - this.encoding = (byte) encoding; - this.roundingUnit = roundingUnit; - this.formatter = formatter; - } - - private static final Map ENCODINGS; - - static { - ImmutableMap.Builder builder = ImmutableMap.builder(); - for (DateRangePrecision precision : values()) { - builder.put(precision.encoding, precision); - } - ENCODINGS = builder.build(); - } - - public static DateRangePrecision fromEncoding(byte encoding) { - DateRangePrecision precision = ENCODINGS.get(encoding); - if (precision == null) { - throw new IllegalArgumentException("Invalid precision encoding: " + encoding); - } - return precision; - } - - /** The code used to represent the precision when a date range is encoded to binary. */ - public byte getEncoding() { - return encoding; - } - - /** - * Rounds up the given timestamp to this precision. - * - *

Temporal fields smaller than this precision will be rounded up; other fields will be left - * untouched. - */ - @NonNull - public ZonedDateTime roundUp(@NonNull ZonedDateTime timestamp) { - Preconditions.checkNotNull(timestamp); - return DateRangeUtil.roundUp(timestamp, roundingUnit); - } - - /** - * Rounds down the given timestamp to this precision. - * - *

Temporal fields smaller than this precision will be rounded down; other fields will be left - * untouched. - */ - @NonNull - public ZonedDateTime roundDown(@NonNull ZonedDateTime timestamp) { - Preconditions.checkNotNull(timestamp); - return DateRangeUtil.roundDown(timestamp, roundingUnit); - } - - /** Formats the given timestamp according to this precision. */ - public String format(ZonedDateTime timestamp) { - return formatter.format(timestamp); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/graph/AsyncGraphResultSet.java b/core/src/main/java/com/datastax/dse/driver/api/core/graph/AsyncGraphResultSet.java deleted file mode 100644 index 995de53959b..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/graph/AsyncGraphResultSet.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import com.datastax.dse.driver.internal.core.graph.GraphExecutionInfoConverter; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.util.Iterator; -import java.util.concurrent.CompletionStage; - -/** - * The result of an asynchronous graph query. - * - *

The default implementation returned by the driver is not thread-safe: the iterable - * returned by {@link #currentPage()} should only be iterated by a single thread. However, if - * subsequent pages are requested via {@link #fetchNextPage()}, it's safe to process those new - * instances in other threads (as long as each individual page of results is not accessed - * concurrently). - * - * @see GraphResultSet - */ -public interface AsyncGraphResultSet { - - /** The execution information for this page of results. */ - @NonNull - default ExecutionInfo getRequestExecutionInfo() { - return GraphExecutionInfoConverter.convert(getExecutionInfo()); - } - - /** - * The execution information for this page of results. - * - * @deprecated Use {@link #getRequestExecutionInfo()} instead. - */ - @Deprecated - @NonNull - com.datastax.dse.driver.api.core.graph.GraphExecutionInfo getExecutionInfo(); - - /** How many rows are left before the current page is exhausted. */ - int remaining(); - - /** - * The nodes in the current page. To keep iterating beyond that, use {@link #hasMorePages()} and - * {@link #fetchNextPage()}. - * - *

Note that this method always returns the same object, and that that object can only be - * iterated once: nodes are "consumed" as they are read. - */ - @NonNull - Iterable currentPage(); - - /** - * Returns the next node, or {@code null} if the result set is exhausted. - * - *

This is convenient for queries that are known to return exactly one node. - */ - @Nullable - default GraphNode one() { - Iterator iterator = currentPage().iterator(); - return iterator.hasNext() ? iterator.next() : null; - } - - /** - * Whether there are more pages of results. If so, call {@link #fetchNextPage()} to fetch the next - * one asynchronously. - */ - boolean hasMorePages(); - - /** - * Fetch the next page of results asynchronously. - * - * @throws IllegalStateException if there are no more pages. Use {@link #hasMorePages()} to check - * if you can call this method. - */ - @NonNull - CompletionStage fetchNextPage() throws IllegalStateException; - - /** - * Cancels the query and asks the server to stop sending results. - * - *

At this time, graph queries are not paginated and the server sends all the results at once; - * therefore this method has no effect. - */ - void cancel(); -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/graph/BatchGraphStatement.java b/core/src/main/java/com/datastax/dse/driver/api/core/graph/BatchGraphStatement.java deleted file mode 100644 index 2169dc5f053..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/graph/BatchGraphStatement.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import com.datastax.dse.driver.internal.core.graph.DefaultBatchGraphStatement; -import com.datastax.oss.driver.api.core.cql.Statement; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Collections; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; - -/** - * A graph statement that groups multiple mutating traversals together, to be executed in the - * same transaction. - * - *

It is reserved for graph mutations, and does not return any result. - * - *

All the mutations grouped in the batch will either all succeed, or they will all be discarded - * and return an error. - * - *

The default implementation returned by the driver is immutable and thread-safe. Each mutation - * operation returns a copy. If you chain many of those operations, it is recommended to use {@link - * #builder()} instead for better memory usage. - * - *

Typically used like so: - * - *

{@code
- * import static com.datastax.dse.driver.api.core.graph.DseGraph.g;
- *
- * BatchGraphStatement statement =
- *     BatchGraphStatement.builder()
- *         .addTraversal(
- *                 g.addV("person").property("name", "batch1").property("age", 1))
- *         .addTraversal(
- *                 g.addV("person").property("name", "batch2").property("age", 2))
- *         .build();
- *
- * GraphResultSet graphResultSet = dseSession.execute(statement);
- * }
- * - * @see DseGraph#g - */ -public interface BatchGraphStatement - extends GraphStatement, Iterable { - - /** - * Create a new, empty instance. - * - *

Traversals can be added with {@link #addTraversal(GraphTraversal)}. - */ - @NonNull - static BatchGraphStatement newInstance() { - return new DefaultBatchGraphStatement( - ImmutableList.of(), - null, - null, - null, - Statement.NO_DEFAULT_TIMESTAMP, - null, - null, - Collections.emptyMap(), - null, - null, - null, - null, - null, - null); - } - - /** Create a new instance from the given list of traversals. */ - @NonNull - static BatchGraphStatement newInstance(@NonNull Iterable traversals) { - return new DefaultBatchGraphStatement( - traversals, - null, - null, - null, - Statement.NO_DEFAULT_TIMESTAMP, - null, - null, - Collections.emptyMap(), - null, - null, - null, - null, - null, - null); - } - - /** Create a new instance from the given list of traversals. */ - @NonNull - static BatchGraphStatement newInstance(@NonNull GraphTraversal... traversals) { - return newInstance(ImmutableList.copyOf(traversals)); - } - - /** - * Create a builder helper object to start creating a new instance. - * - *

Note that this builder is mutable and not thread-safe. - */ - @NonNull - static BatchGraphStatementBuilder builder() { - return new BatchGraphStatementBuilder(); - } - - /** - * Create a builder helper object to start creating a new instance with an existing statement as a - * template. The traversals and options set on the template will be copied for the new statement - * at the moment this method is called. - * - *

Note that this builder is mutable and not thread-safe. - */ - @NonNull - static BatchGraphStatementBuilder builder(@NonNull BatchGraphStatement template) { - return new BatchGraphStatementBuilder(template); - } - - /** - * Add a traversal to this statement. If many traversals need to be added, use a {@link - * #builder()}, or the {@link #addTraversals(Iterable)} method instead to avoid intermediary - * copies. - */ - @NonNull - BatchGraphStatement addTraversal(@NonNull GraphTraversal traversal); - - /** - * Adds several traversals to this statement. If this method is to be called many times, consider - * using a {@link #builder()} instead to avoid intermediary copies. - */ - @NonNull - BatchGraphStatement addTraversals(@NonNull Iterable traversals); - - /** Get the number of traversals already added to this statement. */ - int size(); -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/graph/BatchGraphStatementBuilder.java b/core/src/main/java/com/datastax/dse/driver/api/core/graph/BatchGraphStatementBuilder.java deleted file mode 100644 index ac1b85bdc71..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/graph/BatchGraphStatementBuilder.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import com.datastax.dse.driver.internal.core.graph.DefaultBatchGraphStatement; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import edu.umd.cs.findbugs.annotations.NonNull; -import net.jcip.annotations.NotThreadSafe; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; - -/** - * A builder to create a batch graph statement. - * - *

This class is mutable and not thread-safe. - */ -@NotThreadSafe -public class BatchGraphStatementBuilder - extends GraphStatementBuilderBase { - - private ImmutableList.Builder traversalsBuilder = ImmutableList.builder(); - private int traversalsCount; - - public BatchGraphStatementBuilder() { - // nothing to do - } - - public BatchGraphStatementBuilder(BatchGraphStatement template) { - super(template); - traversalsBuilder.addAll(template); - traversalsCount = template.size(); - } - - /** Add a traversal to this builder to include in the generated {@link BatchGraphStatement}. */ - @NonNull - public BatchGraphStatementBuilder addTraversal(@NonNull GraphTraversal traversal) { - traversalsBuilder.add(traversal); - traversalsCount += 1; - return this; - } - - /** - * Add several traversals to this builder to include in the generated {@link BatchGraphStatement}. - */ - @NonNull - public BatchGraphStatementBuilder addTraversals(@NonNull Iterable traversals) { - for (GraphTraversal traversal : traversals) { - traversalsBuilder.add(traversal); - traversalsCount += 1; - } - return this; - } - - /** - * Add several traversals to this builder to include in the generated {@link BatchGraphStatement}. - */ - @NonNull - public BatchGraphStatementBuilder addTraversals(@NonNull GraphTraversal... traversals) { - for (GraphTraversal traversal : traversals) { - traversalsBuilder.add(traversal); - traversalsCount += 1; - } - return this; - } - - /** Clears all the traversals previously added to this builder. */ - @NonNull - public BatchGraphStatementBuilder clearTraversals() { - traversalsBuilder = ImmutableList.builder(); - traversalsCount = 0; - return this; - } - - /** Returns the number of traversals added to this statement so far. */ - public int getTraversalsCount() { - return traversalsCount; - } - - @NonNull - @Override - public BatchGraphStatement build() { - return new DefaultBatchGraphStatement( - traversalsBuilder.build(), - isIdempotent, - timeout, - node, - timestamp, - executionProfile, - executionProfileName, - buildCustomPayload(), - graphName, - traversalSource, - subProtocol, - consistencyLevel, - readConsistencyLevel, - writeConsistencyLevel); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/graph/DseGraph.java b/core/src/main/java/com/datastax/dse/driver/api/core/graph/DseGraph.java deleted file mode 100644 index dd1dbe95bc8..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/graph/DseGraph.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import com.datastax.dse.driver.internal.core.graph.DefaultDseRemoteConnectionBuilder; -import com.datastax.oss.driver.api.core.CqlSession; -import org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph; - -/** - * General purpose utility class for interaction with DSE Graph via the DataStax Enterprise Java - * driver. - */ -public class DseGraph { - - /** - * IMPORTANT: As of Tinkerpop 3.3.5, you should no longer use this shortcut if you intend - * to connect the traversal to DSE Graph using a {@linkplain - * org.apache.tinkerpop.gremlin.process.remote.RemoteConnection remote connection}, for example - * via the {@link #remoteConnectionBuilder} method declared below. Instead of: - * - *

{@code
-   * DseSession session = ...;
-   * RemoteConnection remoteConnection = DseGraph.remoteConnectionBuilder(session).build();
-   * GraphTraversalSource g = DseGraph.g.withRemote(remoteConnection);
-   * }
- * - * You should now use {@link AnonymousTraversalSource#traversal()}, and adopt the following idiom: - * - *
{@code
-   * DseSession session = ...;
-   * RemoteConnection remoteConnection = DseGraph.remoteConnectionBuilder(session).build();
-   * GraphTraversalSource g = AnonymousTraversalSource.traversal().withRemote(remoteConnection);
-   * }
- * - * A general-purpose shortcut for a non-connected TinkerPop {@link GraphTraversalSource} - * based on an immutable empty graph. This is really just a shortcut to {@code - * EmptyGraph.instance().traversal();}. - * - *

It can be used to create {@link FluentGraphStatement} instances (recommended); for ease of - * use you may statically import this variable. - * - *

Calling {@code g.getGraph()} will return a local immutable empty graph which is in no way - * connected to the DSE Graph server, it will not allow to modify a DSE Graph directly. To act on - * data stored in DSE Graph you must use {@linkplain - * org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal traversal}s such as - * {@code DseGraph.g.V()}, {@code DseGraph.g.addV/addE()}. - */ - public static final GraphTraversalSource g = EmptyGraph.instance().traversal(); - - /** - * Returns a builder helper class to help create {@link - * org.apache.tinkerpop.gremlin.process.remote.RemoteConnection} implementations that seamlessly - * connect to DSE Graph using the {@link CqlSession} in parameter. - */ - public static DseGraphRemoteConnectionBuilder remoteConnectionBuilder(CqlSession dseSession) { - return new DefaultDseRemoteConnectionBuilder(dseSession); - } - - private DseGraph() { - // nothing to do - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/graph/DseGraphRemoteConnectionBuilder.java b/core/src/main/java/com/datastax/dse/driver/api/core/graph/DseGraphRemoteConnectionBuilder.java deleted file mode 100644 index c4210a5b3dd..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/graph/DseGraphRemoteConnectionBuilder.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import org.apache.tinkerpop.gremlin.process.remote.RemoteConnection; - -/** - * A builder helper to create a {@link RemoteConnection} that will be used to build - * implicitly-executing fluent traversals. - * - *

To create an instance of this, use the {@link DseGraph#remoteConnectionBuilder(CqlSession)} - * method: - * - *

{@code
- * DseSession dseSession = DseSession.builder().build();
- * GraphTraversalSource g = AnonymousTraversalSource.traversal().withRemote(DseGraph.remoteConnectionBuilder(dseSession).build());
- * List vertices = g.V().hasLabel("person").toList();
- * }
- * - * @see CqlSession - */ -public interface DseGraphRemoteConnectionBuilder { - - /** Build the remote connection that was configured with this builder. */ - RemoteConnection build(); - - /** - * Set a configuration profile that will be used for every traversal built using the remote - * connection. - * - *

For the list of options available for Graph requests, see the {@code reference.conf} - * configuration file. - */ - DseGraphRemoteConnectionBuilder withExecutionProfile(DriverExecutionProfile executionProfile); - - /** - * Set the name of an execution profile that will be used for every traversal using from the - * remote connection. Named profiles are pre-defined in the driver configuration. - * - *

For the list of options available for Graph requests, see the {@code reference.conf} - * configuration file. - */ - DseGraphRemoteConnectionBuilder withExecutionProfileName(String executionProfileName); -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/graph/FluentGraphStatement.java b/core/src/main/java/com/datastax/dse/driver/api/core/graph/FluentGraphStatement.java deleted file mode 100644 index 051c6501c65..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/graph/FluentGraphStatement.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import com.datastax.dse.driver.internal.core.graph.DefaultFluentGraphStatement; -import com.datastax.oss.driver.api.core.cql.Statement; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Collections; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; - -/** - * A graph statement that uses a TinkerPop {@link GraphTraversal} as the query. - * - *

Typically used like so: - * - *

{@code
- * import static com.datastax.dse.driver.api.core.graph.DseGraph.g;
- *
- * FluentGraphStatement statement = FluentGraphStatement.newInstance(g.V().has("name", "marko"));
- *
- * GraphResultSet graphResultSet = dseSession.execute(statement);
- * }
- * - * @see DseGraph#g - */ -public interface FluentGraphStatement extends GraphStatement { - - /** - * Create a new instance from the given traversal. - * - *

Use {@link #builder(GraphTraversal)} if you want to set more options before building the - * final statement instance. - */ - @NonNull - static FluentGraphStatement newInstance(@NonNull GraphTraversal traversal) { - return new DefaultFluentGraphStatement( - traversal, - null, - null, - null, - Statement.NO_DEFAULT_TIMESTAMP, - null, - null, - Collections.emptyMap(), - null, - null, - null, - null, - null, - null); - } - - /** - * Create a builder object to start creating a new instance from the given traversal. - * - *

Note that this builder is mutable and not thread-safe. - */ - @NonNull - static FluentGraphStatementBuilder builder(@NonNull GraphTraversal traversal) { - return new FluentGraphStatementBuilder(traversal); - } - - /** - * Create a builder helper object to start creating a new instance with an existing statement as a - * template. The traversal and options set on the template will be copied for the new statement at - * the moment this method is called. - * - *

Note that this builder is mutable and not thread-safe. - */ - @NonNull - static FluentGraphStatementBuilder builder(@NonNull FluentGraphStatement template) { - return new FluentGraphStatementBuilder(template); - } - - /** The underlying TinkerPop object representing the traversal executed by this statement. */ - @NonNull - GraphTraversal getTraversal(); -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/graph/FluentGraphStatementBuilder.java b/core/src/main/java/com/datastax/dse/driver/api/core/graph/FluentGraphStatementBuilder.java deleted file mode 100644 index 59e588c564a..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/graph/FluentGraphStatementBuilder.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import com.datastax.dse.driver.internal.core.graph.DefaultFluentGraphStatement; -import edu.umd.cs.findbugs.annotations.NonNull; -import net.jcip.annotations.NotThreadSafe; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; - -/** - * A builder to create a fluent graph statement. - * - *

This class is mutable and not thread-safe. - */ -@NotThreadSafe -public class FluentGraphStatementBuilder - extends GraphStatementBuilderBase { - - private GraphTraversal traversal; - - public FluentGraphStatementBuilder(@NonNull GraphTraversal traversal) { - this.traversal = traversal; - } - - public FluentGraphStatementBuilder(@NonNull FluentGraphStatement template) { - super(template); - this.traversal = template.getTraversal(); - } - - @NonNull - @Override - public FluentGraphStatement build() { - return new DefaultFluentGraphStatement( - this.traversal, - isIdempotent, - timeout, - node, - timestamp, - executionProfile, - executionProfileName, - buildCustomPayload(), - graphName, - traversalSource, - subProtocol, - consistencyLevel, - readConsistencyLevel, - writeConsistencyLevel); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/graph/GraphExecutionInfo.java b/core/src/main/java/com/datastax/dse/driver/api/core/graph/GraphExecutionInfo.java deleted file mode 100644 index 758f6b358ed..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/graph/GraphExecutionInfo.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import com.datastax.oss.driver.api.core.DefaultProtocolVersion; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.datastax.oss.driver.api.core.specex.SpeculativeExecutionPolicy; -import java.nio.ByteBuffer; -import java.util.List; -import java.util.Map; - -/** - * Information about the execution of a graph statement. - * - * @deprecated This interface is not used by any driver component anymore; the driver now exposes - * instances of {@link com.datastax.oss.driver.api.core.cql.ExecutionInfo} for all Graph - * queries. - */ -@Deprecated -public interface GraphExecutionInfo { - - /** The statement that was executed. */ - GraphStatement getStatement(); - - /** The node that was used as a coordinator to successfully complete the query. */ - Node getCoordinator(); - - /** - * The number of speculative executions that were started for this query. - * - *

This does not include the initial, normal execution of the query. Therefore, if speculative - * executions are disabled, this will always be 0. If they are enabled and one speculative - * execution was triggered in addition to the initial execution, this will be 1, etc. - * - * @see SpeculativeExecutionPolicy - */ - int getSpeculativeExecutionCount(); - - /** - * The index of the execution that completed this query. - * - *

0 represents the initial, normal execution of the query, 1 the first speculative execution, - * etc. - * - * @see SpeculativeExecutionPolicy - */ - int getSuccessfulExecutionIndex(); - - /** - * The errors encountered on previous coordinators, if any. - * - *

The list is in chronological order, based on the time that the driver processed the error - * responses. If speculative executions are enabled, they run concurrently so their errors will be - * interleaved. A node can appear multiple times (if the retry policy decided to retry on the same - * node). - */ - List> getErrors(); - - /** - * The server-side warnings for this query, if any (otherwise the list will be empty). - * - *

This feature is only available with {@link DefaultProtocolVersion#V4} or above; with lower - * versions, this list will always be empty. - */ - List getWarnings(); - - /** - * The custom payload sent back by the server with the response, if any (otherwise the map will be - * empty). - * - *

This method returns a read-only view of the original map, but its values remain inherently - * mutable. If multiple clients will read these values, care should be taken not to corrupt the - * data (in particular, preserve the indices by calling {@link ByteBuffer#duplicate()}). - * - *

This feature is only available with {@link DefaultProtocolVersion#V4} or above; with lower - * versions, this map will always be empty. - */ - Map getIncomingPayload(); -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/graph/GraphNode.java b/core/src/main/java/com/datastax/dse/driver/api/core/graph/GraphNode.java deleted file mode 100644 index 97d48a6b04d..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/graph/GraphNode.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import com.datastax.oss.driver.api.core.type.reflect.GenericType; -import java.util.List; -import java.util.Map; -import java.util.Set; -import org.apache.tinkerpop.gremlin.process.traversal.Path; -import org.apache.tinkerpop.gremlin.structure.Edge; -import org.apache.tinkerpop.gremlin.structure.Property; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.apache.tinkerpop.gremlin.structure.VertexProperty; - -/** - * A node in a tree-like structure representing a Graph or a Graph component. - * - *

It can be: - * - *

    - *
  • a scalar value of a primitive type (boolean, string, int, long, double); - *
  • a graph element (vertex, edge, path or property); - *
  • a list of nodes; - *
  • a set of nodes; - *
  • a map of nodes. - *
- * - * This interface provides test methods to find out what a node represents, and conversion methods - * to cast it to a particular Java type. Two generic methods {@link #as(Class)} and {@link - * #as(GenericType)} can produce any arbitrary Java type, provided that the underlying serialization - * runtime has been correctly configured to support the requested conversion. - */ -public interface GraphNode { - - /** Whether this node represents a {@code null} value. */ - boolean isNull(); - - /** - * Returns {@code true} if this node is a {@link Map}, and {@code false} otherwise. - * - *

If this method returns {@code true}, you can convert this node with {@link #asMap()}, or use - * {@link #keys()} and {@link #getByKey(Object)} to access the individual fields (note that - * entries are not ordered, so {@link #getByIndex(int)} does not work). - */ - boolean isMap(); - - /** The keys of this map node, or an empty iterator if it is not a map. */ - Iterable keys(); - - /** - * Returns the value for the given key as a node. - * - *

If this node is not a map, or does not contain the specified key, {@code null} is returned. - * - *

If the property value has been explicitly set to {@code null}, implementors may return a - * special "null node" instead of {@code null}. - */ - GraphNode getByKey(Object key); - - /** Deserializes and returns this node as a {@link Map}. */ - Map asMap(); - - /** - * Returns {@code true} if this node is a {@link List}, and {@code false} otherwise. - * - *

If this method returns {@code true}, you can convert this node with {@link #asList()}, or - * use {@link #size()} and {@link #getByIndex(int)} to access the individual fields. - */ - boolean isList(); - - /** The size of the current node, if it is a list or map, or {@code 0} otherwise. */ - int size(); - - /** - * Returns the element at the given index as a node. - * - *

If this node is not a list, or {@code index} is out of bounds (i.e. less than zero or {@code - * >= size()}, {@code null} is returned; no exception will be thrown. - * - *

If the requested element has been explicitly set to {@code null}, implementors may return a - * special "null node" instead of {@code null}. - */ - GraphNode getByIndex(int index); - - /** Deserializes and returns this node as a {@link List}. */ - List asList(); - - /** - * Returns {@code true} if this node is a simple scalar value, (i.e., string, boolean or number), - * and {@code false} otherwise. - * - *

If this method returns {@code true}, you can convert this node with {@link #asString()}, - * {@link #asBoolean()}, {@link #asInt()}, {@link #asLong()} or {@link #asDouble()}. - */ - boolean isValue(); - - /** - * Returns this node as an integer. - * - *

If the underlying object is not convertible to integer, implementors may choose to either - * throw {@link ClassCastException} or return [null | empty | some default value], whichever is - * deemed more appropriate. - */ - int asInt(); - - /** - * Returns this node as a boolean. - * - *

If the underlying object is not convertible to boolean, implementors may choose to either - * throw {@link ClassCastException} or return [null | empty | some default value], whichever is - * deemed more appropriate. - */ - boolean asBoolean(); - - /** - * Returns this node as a long integer. - * - *

If the underlying object is not convertible to long, implementors may choose to either throw - * {@link ClassCastException} or return [null | empty | some default value], whichever is deemed - * more appropriate. - */ - long asLong(); - - /** - * Returns this node as a long integer. - * - *

If the underlying object is not convertible to double, implementors may choose to either - * throw {@link ClassCastException} or return [null | empty | some default value], whichever is - * deemed more appropriate. - */ - double asDouble(); - - /** - * A valid string representation of this node. - * - *

If the underlying object is not convertible to a string, implementors may choose to either - * throw {@link ClassCastException} or return an empty string, whichever is deemed more - * appropriate. - */ - String asString(); - - /** - * Deserializes and returns this node as an instance of {@code clazz}. - * - *

Before attempting such a conversion, there must be an appropriate converter configured on - * the underlying serialization runtime. - */ - ResultT as(Class clazz); - - /** - * Deserializes and returns this node as an instance of the given {@link GenericType type}. - * - *

Before attempting such a conversion, there must be an appropriate converter configured on - * the underlying serialization runtime. - */ - ResultT as(GenericType type); - - /** - * Returns {@code true} if this node is a {@link Vertex}, and {@code false} otherwise. - * - *

If this method returns {@code true}, then {@link #asVertex()} can be safely called. - */ - boolean isVertex(); - - /** Returns this node as a Tinkerpop {@link Vertex}. */ - Vertex asVertex(); - - /** - * Returns {@code true} if this node is a {@link Edge}, and {@code false} otherwise. - * - *

If this method returns {@code true}, then {@link #asEdge()} can be safely called. - */ - boolean isEdge(); - - /** Returns this node as a Tinkerpop {@link Edge}. */ - Edge asEdge(); - - /** - * Returns {@code true} if this node is a {@link Path}, and {@code false} otherwise. - * - *

If this method returns {@code true}, then {@link #asPath()} can be safely called. - */ - boolean isPath(); - - /** Returns this node as a Tinkerpop {@link Path}. */ - Path asPath(); - - /** - * Returns {@code true} if this node is a {@link Property}, and {@code false} otherwise. - * - *

If this method returns {@code true}, then {@link #asProperty()} can be safely called. - */ - boolean isProperty(); - - /** Returns this node as a Tinkerpop {@link Property}. */ - Property asProperty(); - - /** - * Returns {@code true} if this node is a {@link VertexProperty}, and {@code false} otherwise. - * - *

If this method returns {@code true}, then {@link #asVertexProperty()} ()} can be safely - * called. - */ - boolean isVertexProperty(); - - /** Returns this node as a Tinkerpop {@link VertexProperty}. */ - VertexProperty asVertexProperty(); - - /** - * Returns {@code true} if this node is a {@link Set}, and {@code false} otherwise. - * - *

If this method returns {@code true}, you can convert this node with {@link #asSet()}, or use - * {@link #size()}. - */ - boolean isSet(); - - /** Deserializes and returns this node as a {@link Set}. */ - Set asSet(); -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/graph/GraphResultSet.java b/core/src/main/java/com/datastax/dse/driver/api/core/graph/GraphResultSet.java deleted file mode 100644 index d9c8d8fa460..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/graph/GraphResultSet.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import com.datastax.dse.driver.internal.core.graph.GraphExecutionInfoConverter; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -/** - * The result of a synchronous Graph query. - * - *

This object is a container for {@link GraphNode} objects that will contain the data returned - * by Graph queries. - * - *

Note that this object can only be iterated once: items are "consumed" as they are read, - * subsequent calls to {@code iterator()} will return the same iterator instance. - * - *

The default implementation returned by the driver is not thread-safe. It can only be - * iterated by the thread that invoked {@code dseSession.execute}. - * - * @see GraphNode - * @see GraphSession#execute(GraphStatement) - */ -public interface GraphResultSet extends Iterable { - - /** - * Returns the next node, or {@code null} if the result set is exhausted. - * - *

This is convenient for queries that are known to return exactly one row, for example count - * queries. - */ - @Nullable - default GraphNode one() { - Iterator graphNodeIterator = iterator(); - return graphNodeIterator.hasNext() ? graphNodeIterator.next() : null; - } - - /** - * Returns all the remaining nodes as a list; not recommended for paginated queries that return - * a large number of nodes. - * - *

At this time (DSE 6.0.0), graph queries are not paginated and the server sends all the - * results at once. - */ - @NonNull - default List all() { - if (!iterator().hasNext()) { - return Collections.emptyList(); - } - return ImmutableList.copyOf(this); - } - - /** - * Cancels the query and asks the server to stop sending results. - * - *

At this time (DSE 6.0.0), graph queries are not paginated and the server sends all the - * results at once; therefore this method has no effect. - */ - void cancel(); - - /** - * The execution information for the query that have been performed to assemble this result set. - */ - @NonNull - default ExecutionInfo getRequestExecutionInfo() { - return GraphExecutionInfoConverter.convert(getExecutionInfo()); - } - - /** @deprecated Use {@link #getRequestExecutionInfo()} instead. */ - @Deprecated - @NonNull - com.datastax.dse.driver.api.core.graph.GraphExecutionInfo getExecutionInfo(); -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/graph/GraphSession.java b/core/src/main/java/com/datastax/dse/driver/api/core/graph/GraphSession.java deleted file mode 100644 index b985bc56353..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/graph/GraphSession.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.session.Session; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Objects; -import java.util.concurrent.CompletionStage; - -/** - * A session that has the ability to execute DSE Graph requests. - * - *

Generally this interface won't be referenced directly in an application; instead, you should - * use {@link CqlSession}, which is a combination of this interface and many others for a more - * integrated usage of DataStax Enterprise's multi-model database via a single entry point. However, - * it is still possible to cast a {@code CqlSession} to a {@code GraphSession} to only expose the - * DSE Graph execution methods. - */ -public interface GraphSession extends Session { - - /** - * Executes a graph statement synchronously (the calling thread blocks until the result becomes - * available). - * - *

The driver provides different kinds of graph statements: - * - *

    - *
  • {@link FluentGraphStatement} (recommended): wraps a fluent TinkerPop {@linkplain - * org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal traversal}; - *
  • {@link BatchGraphStatement}: groups together multiple mutating traversals ({@code - * g.addV()/g.addE()}) inside a single transaction and avoids multiple client-server - * round-trips. Improves performance in data ingestion scenarios; - *
  • {@link ScriptGraphStatement}: wraps a Gremlin-groovy script provided as a plain Java - * string. Required for administrative queries such as creating/dropping a graph, - * configuration and schema. - *
- * - *

This feature is only available with DataStax Enterprise. Executing graph queries against an - * Apache Cassandra® cluster will result in a runtime error. - * - * @see GraphResultSet - * @param graphStatement the graph query to execute (that can be any {@code GraphStatement}). - * @return the result of the graph query. That result will never be null but can be empty. - */ - @NonNull - default GraphResultSet execute(@NonNull GraphStatement graphStatement) { - return Objects.requireNonNull( - execute(graphStatement, GraphStatement.SYNC), - "The graph processor should never return a null result"); - } - - /** - * Executes a graph statement asynchronously (the call returns as soon as the statement was sent, - * generally before the result is available). - * - *

This feature is only available with DataStax Enterprise. Executing graph queries against an - * Apache Cassandra® cluster will result in a runtime error. - * - * @see #execute(GraphStatement) - * @see AsyncGraphResultSet - * @param graphStatement the graph query to execute (that can be any {@code GraphStatement}). - * @return the {@code CompletionStage} on the result of the graph query. - */ - @NonNull - default CompletionStage executeAsync( - @NonNull GraphStatement graphStatement) { - return Objects.requireNonNull( - execute(graphStatement, GraphStatement.ASYNC), - "The graph processor should never return a null result"); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/graph/GraphStatement.java b/core/src/main/java/com/datastax/dse/driver/api/core/graph/GraphStatement.java deleted file mode 100644 index f770469b824..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/graph/GraphStatement.java +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import com.datastax.oss.driver.api.core.ConsistencyLevel; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.NoNodeAvailableException; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.loadbalancing.LoadBalancingPolicy; -import com.datastax.oss.driver.api.core.loadbalancing.NodeDistance; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.datastax.oss.driver.api.core.metadata.token.Token; -import com.datastax.oss.driver.api.core.session.Request; -import com.datastax.oss.driver.api.core.session.Session; -import com.datastax.oss.driver.api.core.specex.SpeculativeExecutionPolicy; -import com.datastax.oss.driver.api.core.type.reflect.GenericType; -import edu.umd.cs.findbugs.annotations.CheckReturnValue; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.nio.ByteBuffer; -import java.time.Duration; -import java.util.Map; -import java.util.concurrent.CompletionStage; - -/** - * A request to execute a DSE Graph query. - * - * @param the "self type" used for covariant returns in subtypes. - */ -public interface GraphStatement> extends Request { - - /** - * The type returned when a graph statement is executed synchronously. - * - *

Most users won't use this explicitly. It is needed for the generic execute method ({@link - * Session#execute(Request, GenericType)}), but graph statements will generally be run with one of - * the DSE driver's built-in helper methods (such as {@link CqlSession#execute(GraphStatement)}). - */ - GenericType SYNC = GenericType.of(GraphResultSet.class); - - /** - * The type returned when a graph statement is executed asynchronously. - * - *

Most users won't use this explicitly. It is needed for the generic execute method ({@link - * Session#execute(Request, GenericType)}), but graph statements will generally be run with one of - * the DSE driver's built-in helper methods (such as {@link - * CqlSession#executeAsync(GraphStatement)}). - */ - GenericType> ASYNC = - new GenericType>() {}; - - /** - * Set the idempotence to use for execution. - * - *

Idempotence defines whether it will be possible to speculatively re-execute the statement, - * based on a {@link SpeculativeExecutionPolicy}. - * - *

All the driver's built-in implementations are immutable, and return a new instance from this - * method. However custom implementations may choose to be mutable and return the same instance. - * - * @param idempotent a boolean instance to set a statement-specific value, or {@code null} to use - * the default idempotence defined in the configuration. - */ - @NonNull - @CheckReturnValue - SelfT setIdempotent(@Nullable Boolean idempotent); - - /** - * {@inheritDoc} - * - *

Note that, if this method returns {@code null}, graph statements fall back to a dedicated - * configuration option: {@code basic.graph.timeout}. See {@code reference.conf} in the DSE driver - * distribution for more details. - */ - @Nullable - @Override - Duration getTimeout(); - - /** - * Sets how long to wait for this request to complete. This is a global limit on the duration of a - * session.execute() call, including any retries the driver might do. - * - *

All the driver's built-in implementations are immutable, and return a new instance from this - * method. However custom implementations may choose to be mutable and return the same instance. - * - * @param newTimeout the timeout to use, or {@code null} to use the default value defined in the - * configuration. - * @see #getTimeout() - */ - @NonNull - @CheckReturnValue - SelfT setTimeout(@Nullable Duration newTimeout); - - /** - * Sets the {@link Node} that should handle this query. - * - *

In the general case, use of this method is heavily discouraged and should only be - * used in specific cases, such as applying a series of schema changes, which may be advantageous - * to execute in sequence on the same node. - * - *

Configuring a specific node causes the configured {@link LoadBalancingPolicy} to be - * completely bypassed. However, if the load balancing policy dictates that the node is at - * distance {@link NodeDistance#IGNORED} or there is no active connectivity to the node, the - * request will fail with a {@link NoNodeAvailableException}. - * - *

All the driver's built-in implementations are immutable, and return a new instance from this - * method. However custom implementations may choose to be mutable and return the same instance. - * - * @param newNode The node that should be used to handle executions of this statement or null to - * delegate to the configured load balancing policy. - */ - @NonNull - @CheckReturnValue - SelfT setNode(@Nullable Node newNode); - - /** - * Get the timestamp set on the statement. - * - *

By default, if left unset, the value returned by this is {@code Long.MIN_VALUE}, which means - * that the timestamp will be set via the Timestamp Generator. - * - * @return the timestamp set on this statement. - */ - long getTimestamp(); - - /** - * Set the timestamp to use for execution. - * - *

By default the timestamp generator (see reference config file) will be used for timestamps, - * unless set explicitly via this method. - * - *

All the driver's built-in implementations are immutable, and return a new instance from this - * method. However custom implementations may choose to be mutable and return the same instance. - */ - @CheckReturnValue - SelfT setTimestamp(long timestamp); - - /** - * Sets the configuration profile to use for execution. - * - *

All the driver's built-in implementations are immutable, and return a new instance from this - * method. However custom implementations may choose to be mutable and return the same instance. - */ - @NonNull - @CheckReturnValue - SelfT setExecutionProfile(@Nullable DriverExecutionProfile executionProfile); - - /** - * Sets the name of the driver configuration profile that will be used for execution. - * - *

For all the driver's built-in implementations, this method has no effect if {@link - * #setExecutionProfile} has been called with a non-null argument. - * - *

All the driver's built-in implementations are immutable, and return a new instance from this - * method. However custom implementations may choose to be mutable and return the same instance. - */ - @NonNull - @CheckReturnValue - SelfT setExecutionProfileName(@Nullable String name); - - /** - * Sets the custom payload to use for execution. - * - *

This is intended for advanced use cases, such as tools with very advanced knowledge of DSE - * Graph, and reserved for internal settings like transaction settings. Note that the driver also - * adds graph-related options to the payload, in addition to the ones provided here; it won't - * override any option that is already present. - * - *

All the driver's built-in statement implementations are immutable, and return a new instance - * from this method. However custom implementations may choose to be mutable and return the same - * instance. - * - *

Note that it's your responsibility to provide a thread-safe map. This can be achieved with a - * concurrent or immutable implementation, or by making it effectively immutable (meaning that - * it's never modified after being set on the statement). - * - *

All the driver's built-in implementations are immutable, and return a new instance from this - * method. However custom implementations may choose to be mutable and return the same instance. - */ - @NonNull - @CheckReturnValue - SelfT setCustomPayload(@NonNull Map newCustomPayload); - - /** - * The name of the graph to use for this statement. - * - *

This is the programmatic equivalent of the configuration option {@code basic.graph.name}, - * and takes precedence over it. That is, if this property is non-null, then the configuration - * will be ignored. - */ - @Nullable - String getGraphName(); - - /** - * Sets the graph name. - * - *

All the driver's built-in implementations are immutable, and return a new instance from this - * method. However custom implementations may choose to be mutable and return the same instance. - * - * @see #getGraphName() - */ - @NonNull - @CheckReturnValue - SelfT setGraphName(@Nullable String newGraphName); - - /** - * The name of the traversal source to use for this statement. - * - *

This is the programmatic equivalent of the configuration option {@code - * basic.graph.traversal-source}, and takes precedence over it. That is, if this property is - * non-null, then the configuration will be ignored. - */ - @Nullable - String getTraversalSource(); - - /** - * Sets the traversal source. - * - *

All the driver's built-in implementations are immutable, and return a new instance from this - * method. However custom implementations may choose to be mutable and return the same instance. - * - * @see #getTraversalSource() - */ - @NonNull - @CheckReturnValue - SelfT setTraversalSource(@Nullable String newTraversalSource); - - /** - * The DSE graph sub-protocol to use for this statement. - * - *

This is the programmatic equivalent of the configuration option {@code - * advanced.graph.sub-protocol}, and takes precedence over it. That is, if this property is - * non-null, then the configuration will be ignored. - */ - @Nullable - String getSubProtocol(); - - /** - * Sets the sub-protocol. - * - *

All the driver's built-in implementations are immutable, and return a new instance from this - * method. However custom implementations may choose to be mutable and return the same instance. - * - * @see #getSubProtocol() - */ - @NonNull - @CheckReturnValue - SelfT setSubProtocol(@Nullable String newSubProtocol); - - /** - * Returns the consistency level to use for the statement. - * - *

This is the programmatic equivalent of the configuration option {@code - * basic.request.consistency}, and takes precedence over it. That is, if this property is - * non-null, then the configuration will be ignored. - */ - @Nullable - ConsistencyLevel getConsistencyLevel(); - - /** - * Sets the consistency level to use for this statement. - * - *

All the driver's built-in implementations are immutable, and return a new instance from this - * method. However custom implementations may choose to be mutable and return the same instance. - * - * @param newConsistencyLevel the consistency level to use, or null to use the default value - * defined in the configuration. - * @see #getConsistencyLevel() - */ - @CheckReturnValue - SelfT setConsistencyLevel(@Nullable ConsistencyLevel newConsistencyLevel); - - /** - * The consistency level to use for the internal read queries that will be produced by this - * statement. - * - *

This is the programmatic equivalent of the configuration option {@code - * basic.graph.read-consistency-level}, and takes precedence over it. That is, if this property is - * non-null, then the configuration will be ignored. - * - *

If this property isn't set here or in the configuration, the default consistency level will - * be used ({@link #getConsistencyLevel()} or {@code basic.request.consistency}). - */ - @Nullable - ConsistencyLevel getReadConsistencyLevel(); - - /** - * Sets the read consistency level. - * - *

All the driver's built-in implementations are immutable, and return a new instance from this - * method. However custom implementations may choose to be mutable and return the same instance. - * - * @see #getReadConsistencyLevel() - */ - @NonNull - @CheckReturnValue - SelfT setReadConsistencyLevel(@Nullable ConsistencyLevel newReadConsistencyLevel); - - /** - * The consistency level to use for the internal write queries that will be produced by this - * statement. - * - *

This is the programmatic equivalent of the configuration option {@code - * basic.graph.write-consistency-level}, and takes precedence over it. That is, if this property - * is non-null, then the configuration will be ignored. - * - *

If this property isn't set here or in the configuration, the default consistency level will - * be used ({@link #getConsistencyLevel()} or {@code basic.request.consistency}). - */ - @Nullable - ConsistencyLevel getWriteConsistencyLevel(); - - /** - * Sets the write consistency level. - * - *

All the driver's built-in implementations are immutable, and return a new instance from this - * method. However custom implementations may choose to be mutable and return the same instance. - * - * @see #getWriteConsistencyLevel() - */ - @NonNull - @CheckReturnValue - SelfT setWriteConsistencyLevel(@Nullable ConsistencyLevel newWriteConsistencyLevel); - - /** Graph statements do not have a per-query keyspace, this method always returns {@code null}. */ - @Nullable - @Override - default CqlIdentifier getKeyspace() { - return null; - } - - /** Graph statements can't be routed, this method always returns {@code null}. */ - @Nullable - @Override - default CqlIdentifier getRoutingKeyspace() { - return null; - } - - /** Graph statements can't be routed, this method always returns {@code null}. */ - @Nullable - @Override - default ByteBuffer getRoutingKey() { - return null; - } - - /** Graph statements can't be routed, this method always returns {@code null}. */ - @Nullable - @Override - default Token getRoutingToken() { - return null; - } - - /** - * Whether tracing information should be recorded for this statement. - * - *

This method is only exposed for future extensibility. At the time of writing, graph - * statements do not support tracing, and this always returns {@code false}. - */ - default boolean isTracing() { - return false; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/graph/GraphStatementBuilderBase.java b/core/src/main/java/com/datastax/dse/driver/api/core/graph/GraphStatementBuilderBase.java deleted file mode 100644 index 5cb48613cf5..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/graph/GraphStatementBuilderBase.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import com.datastax.oss.driver.api.core.ConsistencyLevel; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.cql.Statement; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.datastax.oss.protocol.internal.util.collection.NullAllowingImmutableMap; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.nio.ByteBuffer; -import java.time.Duration; -import java.util.Map; -import net.jcip.annotations.NotThreadSafe; - -@NotThreadSafe -public abstract class GraphStatementBuilderBase< - SelfT extends GraphStatementBuilderBase, - StatementT extends GraphStatement> { - - @SuppressWarnings({"unchecked"}) - private final SelfT self = (SelfT) this; - - protected Boolean isIdempotent; - protected Duration timeout; - protected Node node; - protected long timestamp = Statement.NO_DEFAULT_TIMESTAMP; - protected DriverExecutionProfile executionProfile; - protected String executionProfileName; - private NullAllowingImmutableMap.Builder customPayloadBuilder; - protected String graphName; - protected String traversalSource; - protected String subProtocol; - protected ConsistencyLevel consistencyLevel; - protected ConsistencyLevel readConsistencyLevel; - protected ConsistencyLevel writeConsistencyLevel; - - protected GraphStatementBuilderBase() { - // nothing to do - } - - protected GraphStatementBuilderBase(StatementT template) { - this.isIdempotent = template.isIdempotent(); - this.timeout = template.getTimeout(); - this.node = template.getNode(); - this.timestamp = template.getTimestamp(); - this.executionProfile = template.getExecutionProfile(); - this.executionProfileName = template.getExecutionProfileName(); - if (!template.getCustomPayload().isEmpty()) { - this.customPayloadBuilder = - NullAllowingImmutableMap.builder() - .putAll(template.getCustomPayload()); - } - this.graphName = template.getGraphName(); - this.traversalSource = template.getTraversalSource(); - this.subProtocol = template.getSubProtocol(); - this.consistencyLevel = template.getConsistencyLevel(); - this.readConsistencyLevel = template.getReadConsistencyLevel(); - this.writeConsistencyLevel = template.getWriteConsistencyLevel(); - } - - /** @see GraphStatement#setIdempotent(Boolean) */ - @NonNull - public SelfT setIdempotence(@Nullable Boolean idempotent) { - this.isIdempotent = idempotent; - return self; - } - - /** @see GraphStatement#setTimeout(Duration) */ - @NonNull - public SelfT setTimeout(@Nullable Duration timeout) { - this.timeout = timeout; - return self; - } - - /** @see GraphStatement#setNode(Node) */ - @NonNull - public SelfT setNode(@Nullable Node node) { - this.node = node; - return self; - } - - /** @see GraphStatement#setTimestamp(long) */ - @NonNull - public SelfT setTimestamp(long timestamp) { - this.timestamp = timestamp; - return self; - } - - /** @see GraphStatement#setExecutionProfileName(String) */ - @NonNull - public SelfT setExecutionProfileName(@Nullable String executionProfileName) { - this.executionProfileName = executionProfileName; - return self; - } - - /** @see GraphStatement#setExecutionProfile(DriverExecutionProfile) */ - @NonNull - public SelfT setExecutionProfile(@Nullable DriverExecutionProfile executionProfile) { - this.executionProfile = executionProfile; - this.executionProfileName = null; - return self; - } - - /** @see GraphStatement#setCustomPayload(Map) */ - @NonNull - public SelfT addCustomPayload(@NonNull String key, @Nullable ByteBuffer value) { - if (customPayloadBuilder == null) { - customPayloadBuilder = NullAllowingImmutableMap.builder(); - } - customPayloadBuilder.put(key, value); - return self; - } - - /** @see GraphStatement#setCustomPayload(Map) */ - @NonNull - public SelfT clearCustomPayload() { - customPayloadBuilder = null; - return self; - } - - /** @see GraphStatement#setGraphName(String) */ - @NonNull - public SelfT setGraphName(@Nullable String graphName) { - this.graphName = graphName; - return self; - } - - /** @see GraphStatement#setTraversalSource(String) */ - @NonNull - public SelfT setTraversalSource(@Nullable String traversalSource) { - this.traversalSource = traversalSource; - return self; - } - - /** @see GraphStatement#setSubProtocol(String) */ - @NonNull - public SelfT setSubProtocol(@Nullable String subProtocol) { - this.subProtocol = subProtocol; - return self; - } - - /** @see GraphStatement#setConsistencyLevel(ConsistencyLevel) */ - @NonNull - public SelfT setConsistencyLevel(@Nullable ConsistencyLevel consistencyLevel) { - this.consistencyLevel = consistencyLevel; - return self; - } - - /** @see GraphStatement#setReadConsistencyLevel(ConsistencyLevel) */ - @NonNull - public SelfT setReadConsistencyLevel(@Nullable ConsistencyLevel readConsistencyLevel) { - this.readConsistencyLevel = readConsistencyLevel; - return self; - } - - /** @see GraphStatement#setWriteConsistencyLevel(ConsistencyLevel) */ - @NonNull - public SelfT setWriteConsistencyLevel(@Nullable ConsistencyLevel writeConsistencyLevel) { - this.writeConsistencyLevel = writeConsistencyLevel; - return self; - } - - @NonNull - protected Map buildCustomPayload() { - return (customPayloadBuilder == null) - ? NullAllowingImmutableMap.of() - : customPayloadBuilder.build(); - } - - /** Create the statement with the configuration defined by this builder object. */ - @NonNull - public abstract StatementT build(); -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/graph/PagingEnabledOptions.java b/core/src/main/java/com/datastax/dse/driver/api/core/graph/PagingEnabledOptions.java deleted file mode 100644 index f59d0e50e93..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/graph/PagingEnabledOptions.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -public enum PagingEnabledOptions { - ENABLED, - DISABLED, - AUTO -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/graph/ScriptGraphStatement.java b/core/src/main/java/com/datastax/dse/driver/api/core/graph/ScriptGraphStatement.java deleted file mode 100644 index 2ad7aafc232..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/graph/ScriptGraphStatement.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import com.datastax.dse.driver.internal.core.graph.DefaultScriptGraphStatement; -import com.datastax.oss.driver.api.core.cql.Statement; -import com.datastax.oss.protocol.internal.util.collection.NullAllowingImmutableMap; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.util.Collections; -import java.util.Map; - -/** - * A graph statement that uses a Gremlin-groovy script the query. - * - *

These statements are generally used for DSE Graph set-up queries, such as creating or dropping - * a graph, or defining a graph schema. For graph traversals, we recommend using {@link - * FluentGraphStatement} instead. To do bulk data ingestion in graph, we recommend using {@link - * BatchGraphStatement} instead. - * - *

Typical usage: - * - *

{@code
- * ScriptGraphStatement statement = ScriptGraphStatement.newInstance("schema.propertyKey('age').Int().create()");
- *
- * GraphResultSet graphResultSet = dseSession.execute(statement);
- * }
- */ -public interface ScriptGraphStatement extends GraphStatement { - - /** Create a new instance from the given script. */ - @NonNull - static ScriptGraphStatement newInstance(@NonNull String script) { - return new DefaultScriptGraphStatement( - script, - NullAllowingImmutableMap.of(), - null, - null, - null, - null, - Statement.NO_DEFAULT_TIMESTAMP, - null, - null, - Collections.emptyMap(), - null, - null, - null, - null, - null, - null); - } - - /** - * Create a builder object to start creating a new instance from the given script. - * - *

Note that this builder is mutable and not thread-safe. - */ - @NonNull - static ScriptGraphStatementBuilder builder(@NonNull String script) { - return new ScriptGraphStatementBuilder(script); - } - - /** - * Create a builder helper object to start creating a new instance with an existing statement as a - * template. The script and options set on the template will be copied for the new statement at - * the moment this method is called. - * - *

Note that this builder is mutable and not thread-safe. - */ - @NonNull - static ScriptGraphStatementBuilder builder(@NonNull ScriptGraphStatement template) { - return new ScriptGraphStatementBuilder(template); - } - - /** The Gremlin-groovy script representing the graph query. */ - @NonNull - String getScript(); - - /** - * Whether the statement is a system query, or {@code null} if it defaults to the value defined in - * the configuration. - * - * @see #setSystemQuery(Boolean) - */ - @Nullable - Boolean isSystemQuery(); - - /** - * Defines if this statement is a system query. - * - *

Script statements that access the {@code system} variable must not specify a graph - * name (otherwise {@code system} is not available). However, if your application executes a lot - * of non-system statements, it is convenient to configure the graph name in your configuration to - * avoid repeating it every time. This method allows you to ignore that global graph name for a - * specific statement. - * - *

This property is the programmatic equivalent of the configuration option {@code - * basic.graph.is-system-query}, and takes precedence over it. That is, if this property is - * non-null, then the configuration will be ignored. - * - *

The driver's built-in implementation is immutable, and returns a new instance from this - * method. However custom implementations may choose to be mutable and return the same instance. - * - * @param newValue {@code true} to mark this statement as a system query (the driver will ignore - * any graph name set on the statement or the configuration); {@code false} to mark it as a - * non-system query; {@code null} to default to the value defined in the configuration. - * @see #isSystemQuery() - */ - @NonNull - ScriptGraphStatement setSystemQuery(@Nullable Boolean newValue); - - /** - * The query parameters to send along the request. - * - * @see #setQueryParam(String, Object) - */ - @NonNull - Map getQueryParams(); - - /** - * Set a value for a parameter defined in the Groovy script. - * - *

The script engine in the DSE Graph server allows to define parameters in a Groovy script and - * set the values of these parameters as a binding. Defining parameters allows to re-use scripts - * and only change their parameters values, which improves the performance of the script executed, - * so defining parameters is encouraged; however, for optimal Graph traversal performance, we - * recommend either using {@link BatchGraphStatement}s for data ingestion, or {@link - * FluentGraphStatement} for normal traversals. - * - *

Parameters in a Groovy script are always named; unlike CQL, they are not prefixed by a - * column ({@code :}). - * - *

The driver's built-in implementation is immutable, and returns a new instance from this - * method. However custom implementations may choose to be mutable and return the same instance. - * If many parameters are to be set in a query, it is recommended to create the statement with - * {@link #builder(String)} instead. - * - * @param name the name of the parameter defined in the script. If the statement already had a - * binding for this name, it gets replaced. - * @param value the value that will be transmitted with the request. - */ - @NonNull - ScriptGraphStatement setQueryParam(@NonNull String name, @Nullable Object value); - - /** - * Removes a binding for the given name from this statement. - * - *

If the statement did not have such a binding, this method has no effect and returns the same - * statement instance. Otherwise, the driver's built-in implementation returns a new instance - * (however custom implementations may choose to be mutable and return the same instance). - * - * @see #setQueryParam(String, Object) - */ - @NonNull - ScriptGraphStatement removeQueryParam(@NonNull String name); -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/graph/ScriptGraphStatementBuilder.java b/core/src/main/java/com/datastax/dse/driver/api/core/graph/ScriptGraphStatementBuilder.java deleted file mode 100644 index 1985c58955f..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/graph/ScriptGraphStatementBuilder.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import com.datastax.dse.driver.internal.core.graph.DefaultScriptGraphStatement; -import com.datastax.oss.driver.shaded.guava.common.base.Preconditions; -import com.datastax.oss.driver.shaded.guava.common.collect.Maps; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.util.Map; -import net.jcip.annotations.NotThreadSafe; - -/** - * A builder to create a script graph statement. - * - *

This class is mutable and not thread-safe. - */ -@NotThreadSafe -public class ScriptGraphStatementBuilder - extends GraphStatementBuilderBase { - - private String script; - private Boolean isSystemQuery; - private final Map queryParams; - - public ScriptGraphStatementBuilder() { - this.queryParams = Maps.newHashMap(); - } - - public ScriptGraphStatementBuilder(String script) { - this.script = script; - this.queryParams = Maps.newHashMap(); - } - - public ScriptGraphStatementBuilder(ScriptGraphStatement template) { - super(template); - this.script = template.getScript(); - this.queryParams = Maps.newHashMap(template.getQueryParams()); - this.isSystemQuery = template.isSystemQuery(); - } - - @NonNull - public ScriptGraphStatementBuilder setScript(@NonNull String script) { - this.script = script; - return this; - } - - /** @see ScriptGraphStatement#isSystemQuery() */ - @NonNull - public ScriptGraphStatementBuilder setSystemQuery(@Nullable Boolean isSystemQuery) { - this.isSystemQuery = isSystemQuery; - return this; - } - - /** - * Set a value for a parameter defined in the script query. - * - * @see ScriptGraphStatement#setQueryParam(String, Object) - */ - @NonNull - public ScriptGraphStatementBuilder setQueryParam(@NonNull String name, @Nullable Object value) { - this.queryParams.put(name, value); - return this; - } - - /** - * Set multiple values for named parameters defined in the script query. - * - * @see ScriptGraphStatement#setQueryParam(String, Object) - */ - @NonNull - public ScriptGraphStatementBuilder setQueryParams(@NonNull Map params) { - this.queryParams.putAll(params); - return this; - } - - /** - * Removes a parameter. - * - *

This is useful if the builder was {@linkplain - * ScriptGraphStatement#builder(ScriptGraphStatement) initialized with a template statement} that - * has more parameters than desired. - * - * @see ScriptGraphStatement#setQueryParam(String, Object) - * @see #clearQueryParams() - */ - @NonNull - public ScriptGraphStatementBuilder removeQueryParam(@NonNull String name) { - this.queryParams.remove(name); - return this; - } - - /** Clears all the parameters previously added to this builder. */ - public ScriptGraphStatementBuilder clearQueryParams() { - this.queryParams.clear(); - return this; - } - - @NonNull - @Override - public ScriptGraphStatement build() { - Preconditions.checkNotNull(this.script, "Script hasn't been defined in this builder."); - return new DefaultScriptGraphStatement( - this.script, - this.queryParams, - this.isSystemQuery, - isIdempotent, - timeout, - node, - timestamp, - executionProfile, - executionProfileName, - buildCustomPayload(), - graphName, - traversalSource, - subProtocol, - consistencyLevel, - readConsistencyLevel, - writeConsistencyLevel); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/graph/predicates/CqlCollection.java b/core/src/main/java/com/datastax/dse/driver/api/core/graph/predicates/CqlCollection.java deleted file mode 100644 index fdbf3fbe397..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/graph/predicates/CqlCollection.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph.predicates; - -import com.datastax.dse.driver.internal.core.graph.CqlCollectionPredicate; -import java.util.Collection; -import java.util.Map; -import org.apache.tinkerpop.gremlin.process.traversal.P; -import org.javatuples.Pair; - -/** - * Predicates that can be used on CQL collections (lists, sets and maps). - * - *

Note: CQL collection predicates are only available when using the binary subprotocol. - */ -public class CqlCollection { - - /** - * Checks if the target collection contains the given value. - * - * @param value the value to look for; cannot be {@code null}. - * @return a predicate to apply in a {@link - * org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal}. - */ - @SuppressWarnings("unchecked") - public static , V> P contains(V value) { - return new P(CqlCollectionPredicate.contains, value); - } - - /** - * Checks if the target map contains the given key. - * - * @param key the key to look for; cannot be {@code null}. - * @return a predicate to apply in a {@link - * org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal}. - */ - @SuppressWarnings("unchecked") - public static , K> P containsKey(K key) { - return new P(CqlCollectionPredicate.containsKey, key); - } - - /** - * Checks if the target map contains the given value. - * - * @param value the value to look for; cannot be {@code null}. - * @return a predicate to apply in a {@link - * org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal}. - */ - @SuppressWarnings("unchecked") - public static , V> P containsValue(V value) { - return new P(CqlCollectionPredicate.containsValue, value); - } - - /** - * Checks if the target map contains the given entry. - * - * @param key the key to look for; cannot be {@code null}. - * @param value the value to look for; cannot be {@code null}. - * @return a predicate to apply in a {@link - * org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal}. - */ - @SuppressWarnings("unchecked") - public static , K, V> P entryEq(K key, V value) { - return new P(CqlCollectionPredicate.entryEq, new Pair<>(key, value)); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/graph/predicates/Geo.java b/core/src/main/java/com/datastax/dse/driver/api/core/graph/predicates/Geo.java deleted file mode 100644 index 65dd84d0076..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/graph/predicates/Geo.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph.predicates; - -import com.datastax.dse.driver.api.core.data.geometry.LineString; -import com.datastax.dse.driver.api.core.data.geometry.Point; -import com.datastax.dse.driver.api.core.data.geometry.Polygon; -import com.datastax.dse.driver.internal.core.data.geometry.Distance; -import com.datastax.dse.driver.internal.core.graph.GeoPredicate; -import com.datastax.dse.driver.internal.core.graph.GeoUtils; -import edu.umd.cs.findbugs.annotations.NonNull; -import org.apache.tinkerpop.gremlin.process.traversal.P; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; - -public interface Geo { - - enum Unit { - MILES(GeoUtils.MILES_TO_KM * GeoUtils.KM_TO_DEG), - KILOMETERS(GeoUtils.KM_TO_DEG), - METERS(GeoUtils.KM_TO_DEG / 1000.0), - DEGREES(1); - - private final double multiplier; - - Unit(double multiplier) { - this.multiplier = multiplier; - } - - /** Convert distance to degrees (used internally only). */ - public double toDegrees(double distance) { - return distance * multiplier; - } - } - - /** - * Finds whether an entity is inside the given circular area using a geo coordinate system. - * - * @return a predicate to apply in a {@link GraphTraversal}. - */ - static P inside(Point center, double radius, Unit units) { - return new P<>(GeoPredicate.inside, new Distance(center, units.toDegrees(radius))); - } - - /** - * Finds whether an entity is inside the given circular area using a cartesian coordinate system. - * - * @return a predicate to apply in a {@link GraphTraversal}. - */ - static P inside(Point center, double radius) { - return new P<>(GeoPredicate.insideCartesian, new Distance(center, radius)); - } - - /** - * Finds whether an entity is inside the given polygon. - * - * @return a predicate to apply in a {@link GraphTraversal}. - */ - static P inside(Polygon polygon) { - return new P<>(GeoPredicate.insideCartesian, polygon); - } - - /** - * Creates a point from the given coordinates. - * - *

This is just a shortcut to {@link Point#fromCoordinates(double, double)}. It is duplicated - * here so that {@code Geo} can be used as a single entry point in Gremlin-groovy scripts. - */ - @NonNull - static Point point(double x, double y) { - return Point.fromCoordinates(x, y); - } - - /** - * Creates a line string from the given (at least 2) points. - * - *

This is just a shortcut to {@link LineString#fromPoints(Point, Point, Point...)}. It is - * duplicated here so that {@code Geo} can be used as a single entry point in Gremlin-groovy - * scripts. - */ - @NonNull - static LineString lineString( - @NonNull Point point1, @NonNull Point point2, @NonNull Point... otherPoints) { - return LineString.fromPoints(point1, point2, otherPoints); - } - - /** - * Creates a line string from the coordinates of its points. - * - *

This is provided for backward compatibility with previous DSE versions. We recommend {@link - * #lineString(Point, Point, Point...)} instead. - */ - @NonNull - static LineString lineString(double... coordinates) { - if (coordinates.length % 2 != 0) { - throw new IllegalArgumentException("lineString() must be passed an even number of arguments"); - } else if (coordinates.length < 4) { - throw new IllegalArgumentException( - "lineString() must be passed at least 4 arguments (2 points)"); - } - Point point1 = Point.fromCoordinates(coordinates[0], coordinates[1]); - Point point2 = Point.fromCoordinates(coordinates[2], coordinates[3]); - Point[] otherPoints = new Point[coordinates.length / 2 - 2]; - for (int i = 4; i < coordinates.length; i += 2) { - otherPoints[i / 2 - 2] = Point.fromCoordinates(coordinates[i], coordinates[i + 1]); - } - return LineString.fromPoints(point1, point2, otherPoints); - } - - /** - * Creates a polygon from the given (at least 3) points. - * - *

This is just a shortcut to {@link Polygon#fromPoints(Point, Point, Point, Point...)}. It is - * duplicated here so that {@code Geo} can be used as a single entry point in Gremlin-groovy - * scripts. - */ - @NonNull - static Polygon polygon( - @NonNull Point p1, @NonNull Point p2, @NonNull Point p3, @NonNull Point... otherPoints) { - return Polygon.fromPoints(p1, p2, p3, otherPoints); - } - - /** - * Creates a polygon from the coordinates of its points. - * - *

This is provided for backward compatibility with previous DSE versions. We recommend {@link - * #polygon(Point, Point, Point, Point...)} instead. - */ - @NonNull - static Polygon polygon(double... coordinates) { - if (coordinates.length % 2 != 0) { - throw new IllegalArgumentException("polygon() must be passed an even number of arguments"); - } else if (coordinates.length < 6) { - throw new IllegalArgumentException( - "polygon() must be passed at least 6 arguments (3 points)"); - } - Point point1 = Point.fromCoordinates(coordinates[0], coordinates[1]); - Point point2 = Point.fromCoordinates(coordinates[2], coordinates[3]); - Point point3 = Point.fromCoordinates(coordinates[4], coordinates[5]); - Point[] otherPoints = new Point[coordinates.length / 2 - 3]; - for (int i = 6; i < coordinates.length; i += 2) { - otherPoints[i / 2 - 3] = Point.fromCoordinates(coordinates[i], coordinates[i + 1]); - } - return Polygon.fromPoints(point1, point2, point3, otherPoints); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/graph/predicates/Search.java b/core/src/main/java/com/datastax/dse/driver/api/core/graph/predicates/Search.java deleted file mode 100644 index e285c118c8a..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/graph/predicates/Search.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph.predicates; - -import com.datastax.dse.driver.internal.core.graph.EditDistance; -import com.datastax.dse.driver.internal.core.graph.SearchPredicate; -import org.apache.tinkerpop.gremlin.process.traversal.P; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; - -public interface Search { - - /** - * Search any instance of a certain token within the text property targeted (case insensitive). - * - * @return a predicate to apply in a {@link GraphTraversal}. - */ - static P token(String value) { - return new P<>(SearchPredicate.token, value); - } - - /** - * Search any instance of a certain token prefix within the text property targeted (case - * insensitive). - * - * @return a predicate to apply in a {@link GraphTraversal}. - */ - static P tokenPrefix(String value) { - return new P<>(SearchPredicate.tokenPrefix, value); - } - - /** - * Search any instance of the provided regular expression for the targeted property (case - * insensitive). - * - * @return a predicate to apply in a {@link GraphTraversal}. - */ - static P tokenRegex(String value) { - return new P<>(SearchPredicate.tokenRegex, value); - } - - /** - * Search for a specific prefix at the beginning of the text property targeted (case sensitive). - * - * @return a predicate to apply in a {@link GraphTraversal}. - */ - static P prefix(String value) { - return new P<>(SearchPredicate.prefix, value); - } - - /** - * Search for this regular expression inside the text property targeted (case sensitive). - * - * @return a predicate to apply in a {@link GraphTraversal}. - */ - static P regex(String value) { - return new P<>(SearchPredicate.regex, value); - } - - /** - * Supports finding words which are a within a specific distance away (case insensitive). - * - *

Example: the search expression is {@code phrase("Hello world", 2)} - * - *

    - *
  • the inserted value "Hello world" is found - *
  • the inserted value "Hello wild world" is found - *
  • the inserted value "Hello big wild world" is found - *
  • the inserted value "Hello the big wild world" is not found - *
  • the inserted value "Goodbye world" is not found. - *
- * - * @param query the string to look for in the value - * @param distance the number of terms allowed between two correct terms to find a value. - * @return a predicate to apply in a {@link GraphTraversal}. - */ - static P phrase(String query, int distance) { - return new P<>(SearchPredicate.phrase, new EditDistance(query, distance)); - } - - /** - * Supports fuzzy searches based on the Damerau-Levenshtein Distance, or Edit Distance algorithm - * (case sensitive). - * - *

Example: the search expression is {@code fuzzy("david", 1)} - * - *

    - *
  • the inserted value "david" is found - *
  • the inserted value "dawid" is found - *
  • the inserted value "davids" is found - *
  • the inserted value "dewid" is not found - *
- * - * @param query the string to look for in the value - * @param distance the number of "uncertainties" allowed for the Levenshtein algorithm. - * @return a predicate to apply in a {@link GraphTraversal}. - */ - static P fuzzy(String query, int distance) { - return new P<>(SearchPredicate.fuzzy, new EditDistance(query, distance)); - } - - /** - * Supports fuzzy searches based on the Damerau-Levenshtein Distance, or Edit Distance algorithm - * after having tokenized the data stored (case insensitive). - * - *

Example: the search expression is {@code tokenFuzzy("david", 1)} - * - *

    - *
  • the inserted value "david" is found - *
  • the inserted value "dawid" is found - *
  • the inserted value "hello-dawid" is found - *
  • the inserted value "dewid" is not found - *
- * - * @param query the string to look for in the value - * @param distance the number of "uncertainties" allowed for the Levenshtein algorithm. - * @return a predicate to apply in a {@link GraphTraversal}. - */ - static P tokenFuzzy(String query, int distance) { - return new P<>(SearchPredicate.tokenFuzzy, new EditDistance(query, distance)); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/graph/reactive/ReactiveGraphNode.java b/core/src/main/java/com/datastax/dse/driver/api/core/graph/reactive/ReactiveGraphNode.java deleted file mode 100644 index ad7849633c6..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/graph/reactive/ReactiveGraphNode.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph.reactive; - -import com.datastax.dse.driver.api.core.graph.GraphNode; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import edu.umd.cs.findbugs.annotations.NonNull; - -/** - * A {@link GraphNode} produced by a {@linkplain ReactiveGraphResultSet reactive graph result set}. - * - *

This is essentially an extension of the driver's {@link GraphNode} object that also exposes - * useful information about {@linkplain #getExecutionInfo() request execution} (note however that - * this information is also exposed at result set level for convenience). - * - * @see ReactiveGraphSession - * @see ReactiveGraphResultSet - */ -public interface ReactiveGraphNode extends GraphNode { - - /** - * The execution information for the paged request that produced this result. - * - *

This object is the same for two rows pertaining to the same page, but differs for rows - * pertaining to different pages. - * - * @return the execution information for the paged request that produced this result. - * @see ReactiveGraphResultSet#getExecutionInfos() - */ - @NonNull - ExecutionInfo getExecutionInfo(); -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/graph/reactive/ReactiveGraphResultSet.java b/core/src/main/java/com/datastax/dse/driver/api/core/graph/reactive/ReactiveGraphResultSet.java deleted file mode 100644 index a0e3231750e..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/graph/reactive/ReactiveGraphResultSet.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph.reactive; - -import com.datastax.dse.driver.api.core.graph.GraphStatement; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import edu.umd.cs.findbugs.annotations.NonNull; -import org.reactivestreams.Publisher; - -/** - * A {@link Publisher} of {@link ReactiveGraphNode}s returned by a {@link ReactiveGraphSession}. - * - *

By default, all implementations returned by the driver are cold, unicast, single-subscriber - * only publishers. In other words, they do not support multiple subscriptions; consider - * caching the results produced by such publishers if you need to consume them by more than one - * downstream subscriber. - * - *

Also, note that reactive graph result sets may emit items to their subscribers on an internal - * driver IO thread. Subscriber implementors are encouraged to abide by Reactive Streams - * Specification rule 2.2 and avoid performing heavy computations or blocking calls inside - * {@link org.reactivestreams.Subscriber#onNext(Object) onNext} calls, as doing so could slow down - * the driver and impact performance. Instead, they should asynchronously dispatch received signals - * to their processing logic. - * - *

This interface exists mainly to expose useful information about {@linkplain - * #getExecutionInfos() request execution}. This is particularly convenient for queries that do not - * return rows; for queries that do return rows, it is also possible, and oftentimes easier, to - * access that same information {@linkplain ReactiveGraphNode at node level}. - * - * @see ReactiveGraphSession#executeReactive(GraphStatement) - * @see ReactiveGraphNode - */ -public interface ReactiveGraphResultSet extends Publisher { - - /** - * Returns {@linkplain ExecutionInfo information about the execution} of all requests that have - * been performed so far to assemble this result set. - * - *

If the query is not paged, this publisher will emit exactly one item as soon as the response - * arrives, then complete. If the query is paged, it will emit multiple items, one per page; then - * it will complete when the last page arrives. If the query execution fails, then this publisher - * will fail with the same error. - * - *

By default, publishers returned by this method do not support multiple subscriptions. - * - * @see ReactiveGraphNode#getExecutionInfo() - */ - @NonNull - Publisher getExecutionInfos(); -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/graph/reactive/ReactiveGraphSession.java b/core/src/main/java/com/datastax/dse/driver/api/core/graph/reactive/ReactiveGraphSession.java deleted file mode 100644 index 88f0e5def61..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/graph/reactive/ReactiveGraphSession.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph.reactive; - -import com.datastax.dse.driver.api.core.graph.GraphStatement; -import com.datastax.dse.driver.internal.core.graph.reactive.ReactiveGraphRequestProcessor; -import com.datastax.oss.driver.api.core.session.Session; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Objects; - -/** - * A {@link Session} that offers utility methods to issue graph queries using reactive-style - * programming. - */ -public interface ReactiveGraphSession extends Session { - - /** - * Returns a {@link ReactiveGraphResultSet} that, once subscribed to, executes the given query and - * emits all the results. - * - *

See the javadocs of {@link ReactiveGraphResultSet} for important remarks anc caveats - * regarding the subscription to and consumption of reactive graph result sets. - * - * @param statement the statement to execute. - * @return The {@link ReactiveGraphResultSet} that will publish the returned results. - * @see ReactiveGraphResultSet - * @see ReactiveGraphNode - */ - @NonNull - default ReactiveGraphResultSet executeReactive(@NonNull GraphStatement statement) { - return Objects.requireNonNull( - execute(statement, ReactiveGraphRequestProcessor.REACTIVE_GRAPH_RESULT_SET)); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/metadata/DseNodeProperties.java b/core/src/main/java/com/datastax/dse/driver/api/core/metadata/DseNodeProperties.java deleted file mode 100644 index 88dbc164588..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/metadata/DseNodeProperties.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.metadata; - -import com.datastax.oss.driver.api.core.Version; -import com.datastax.oss.driver.api.core.metadata.Node; - -/** The keys for the additional DSE-specific properties stored in {@link Node#getExtras()}. */ -public class DseNodeProperties { - - /** - * The DSE version that the node is running. - * - *

The associated value in {@link Node#getExtras()} is a {@link Version}). - */ - public static final String DSE_VERSION = "DSE_VERSION"; - - /** - * The value of the {@code server_id} field in the {@code peers} system table for this node. - * - *

This is the single identifier of the machine running a DSE instance. If DSE has been - * configured with Multi-Instance, the {@code server_id} helps identifying the single physical - * machine that runs the multiple DSE instances. If DSE is not configured with DSE Multi-Instance, - * the {@code server_id} will be automatically set and be unique for each node. - * - *

This information is only available if connecting to a DSE 6.0+ node. - * - *

The associated value in {@link Node#getExtras()} is a {@code String}). - * - * @see DSE - * Multi-Instance (DSE Administrator Guide) - * @see - * server_id (DSE Administrator Guide) - */ - public static final String SERVER_ID = "SERVER_ID"; - - /** - * The DSE workloads that the node is running. - * - *

This is based on the {@code workload} or {@code workloads} columns in {@code system.local} - * and {@code system.peers}. - * - *

Workload labels may vary depending on the DSE version in use; e.g. DSE 5.1 may report two - * distinct workloads: {@code Search} and {@code Analytics}, while DSE 5.0 would report a single - * {@code SearchAnalytics} workload instead. It is up to users to deal with such discrepancies; - * the driver simply returns the workload labels as reported by DSE, without any form of - * pre-processing (with the exception of Graph in DSE 5.0, which is stored in a separate column, - * but will be reported as {@code Graph} here). - * - *

The associated value in {@link Node#getExtras()} is an immutable {@code Set}. - */ - public static final String DSE_WORKLOADS = "DSE_WORKLOADS"; - - /** - * The port for the native transport connections on the DSE node. - * - *

The native transport port is {@code 9042} by default but can be changed on instances - * requiring specific firewall configurations. This can be configured in the {@code - * cassandra.yaml} configuration file under the {@code native_transport_port} property. - * - *

This information is only available if connecting the driver to a DSE 6.0+ node. - * - *

The associated value in {@link Node#getExtras()} is an {@code Integer}. - */ - public static final String NATIVE_TRANSPORT_PORT = "NATIVE_TRANSPORT_PORT"; - - /** - * The port for the encrypted native transport connections on the DSE node. - * - *

In most scenarios enabling client communications in DSE will result in using a single port - * that will only accept encrypted connections (by default the port {@code 9042} is reused since - * unencrypted connections are not allowed). - * - *

However, it is possible to configure DSE to use both encrypted and a non-encrypted - * communication ports with clients. In that case the port accepting encrypted connections will - * differ from the non-encrypted one (see {@link #NATIVE_TRANSPORT_PORT}) and will be exposed via - * this method. - * - *

This information is only available if connecting the driver to a DSE 6.0+ node. - * - *

The associated value in {@link Node#getExtras()} is an {@code Integer}. - */ - public static final String NATIVE_TRANSPORT_PORT_SSL = "NATIVE_TRANSPORT_PORT_SSL"; - - /** - * The storage port used by the DSE node. - * - *

The storage port is used for internal communication between the DSE server nodes. This port - * is never used by the driver. - * - *

This information is only available if connecting the driver to a DSE 6.0+ node. - * - *

The associated value in {@link Node#getExtras()} is an {@code Integer}. - */ - public static final String STORAGE_PORT = "STORAGE_PORT"; - - /** - * The encrypted storage port used by the DSE node. - * - *

If inter-node encryption is enabled on the DSE cluster, nodes will communicate securely - * between each other via this port. This port is never used by the driver. - * - *

This information is only available if connecting the driver to a DSE 6.0+ node. - * - *

The associated value in {@link Node#getExtras()} is an {@code Integer}. - */ - public static final String STORAGE_PORT_SSL = "STORAGE_PORT_SSL"; - - /** - * The JMX port used by this node. - * - *

The JMX port can be configured in the {@code cassandra-env.sh} configuration file separately - * on each node. - * - *

This information is only available if connecting the driver to a DSE 6.0+ node. - * - *

The associated value in {@link Node#getExtras()} is an {@code Integer}. - */ - public static final String JMX_PORT = "JMX_PORT"; -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseAggregateMetadata.java b/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseAggregateMetadata.java deleted file mode 100644 index 609c64f7c15..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseAggregateMetadata.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.metadata.schema; - -import com.datastax.oss.driver.api.core.metadata.schema.AggregateMetadata; -import com.datastax.oss.driver.api.core.type.DataType; -import com.datastax.oss.driver.internal.core.metadata.schema.ScriptBuilder; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Optional; - -/** - * Specialized aggregate metadata for DSE. - * - *

It adds support for the DSE-specific {@link #getDeterministic() DETERMINISTIC} keyword. - */ -public interface DseAggregateMetadata extends AggregateMetadata { - - /** @deprecated Use {@link #getDeterministic()} instead. */ - @Deprecated - boolean isDeterministic(); - - /** - * Indicates if this aggregate is deterministic. A deterministic aggregate means that given a - * particular input, the aggregate will always produce the same output. - * - *

This method returns {@linkplain Optional#empty() empty} if this information was not found in - * the system tables, regardless of the actual aggregate characteristics; this is the case for all - * versions of DSE older than 6.0.0. - * - * @return Whether or not this aggregate is deterministic; or {@linkplain Optional#empty() empty} - * if such information is not available in the system tables. - */ - default Optional getDeterministic() { - return Optional.of(isDeterministic()); - } - - @NonNull - @Override - default String describe(boolean pretty) { - // Easiest to just copy the OSS describe() method and add in DETERMINISTIC - ScriptBuilder builder = new ScriptBuilder(pretty); - builder - .append("CREATE AGGREGATE ") - .append(getKeyspace()) - .append(".") - .append(getSignature().getName()) - .append("("); - boolean first = true; - for (int i = 0; i < getSignature().getParameterTypes().size(); i++) { - if (first) { - first = false; - } else { - builder.append(","); - } - DataType type = getSignature().getParameterTypes().get(i); - builder.append(type.asCql(false, pretty)); - } - builder - .increaseIndent() - .append(")") - .newLine() - .append("SFUNC ") - .append(getStateFuncSignature().getName()) - .newLine() - .append("STYPE ") - .append(getStateType().asCql(false, pretty)); - - if (getFinalFuncSignature().isPresent()) { - builder.newLine().append("FINALFUNC ").append(getFinalFuncSignature().get().getName()); - } - if (getInitCond().isPresent()) { - Optional formatInitCond = formatInitCond(); - assert formatInitCond.isPresent(); - builder.newLine().append("INITCOND ").append(formatInitCond.get()); - } - // add DETERMINISTIC if present - if (getDeterministic().orElse(false)) { - builder.newLine().append("DETERMINISTIC"); - } - return builder.append(";").build(); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseColumnMetadata.java b/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseColumnMetadata.java deleted file mode 100644 index 62b5650697e..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseColumnMetadata.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.metadata.schema; - -import com.datastax.oss.driver.api.core.metadata.schema.ColumnMetadata; - -/** - * Specialized column metadata for DSE. - * - *

This type exists only for future extensibility; currently, it is identical to {@link - * ColumnMetadata}. - */ -public interface DseColumnMetadata extends ColumnMetadata {} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseEdgeMetadata.java b/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseEdgeMetadata.java deleted file mode 100644 index 59ee8a277ff..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseEdgeMetadata.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.metadata.schema; - -import com.datastax.oss.driver.api.core.CqlIdentifier; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.List; - -/** Edge metadata, for a table that was created with CREATE TABLE ... WITH EDGE LABEL. */ -public interface DseEdgeMetadata { - - /** The label of the edge in graph. */ - @NonNull - CqlIdentifier getLabelName(); - - /** The identifier of the table representing the incoming vertex. */ - @NonNull - CqlIdentifier getFromTable(); - - /** The label of the incoming vertex in graph. */ - @NonNull - CqlIdentifier getFromLabel(); - - /** The columns in this table that match the partition key of the incoming vertex table. */ - @NonNull - List getFromPartitionKeyColumns(); - - /** The columns in this table that match the clustering columns of the incoming vertex table. */ - @NonNull - List getFromClusteringColumns(); - - /** The identifier of the table representing the outgoing vertex. */ - @NonNull - CqlIdentifier getToTable(); - - /** The label of the outgoing vertex in graph. */ - @NonNull - CqlIdentifier getToLabel(); - - /** The columns in this table that match the partition key of the outgoing vertex table. */ - @NonNull - List getToPartitionKeyColumns(); - - /** The columns in this table that match the clustering columns of the outgoing vertex table. */ - @NonNull - List getToClusteringColumns(); -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseFunctionMetadata.java b/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseFunctionMetadata.java deleted file mode 100644 index 91298795959..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseFunctionMetadata.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.metadata.schema; - -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.metadata.schema.FunctionMetadata; -import com.datastax.oss.driver.api.core.type.DataType; -import com.datastax.oss.driver.internal.core.metadata.schema.ScriptBuilder; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.List; -import java.util.Optional; - -/** - * Specialized function metadata for DSE. - * - *

It adds support for the DSE-specific {@link #getDeterministic() DETERMINISTIC} and {@link - * #getMonotonicity() MONOTONIC} keywords. - */ -public interface DseFunctionMetadata extends FunctionMetadata { - - /** The monotonicity of a function. */ - enum Monotonicity { - - /** - * Indicates that the function is fully monotonic on all of its arguments. This means that it is - * either entirely non-increasing or non-decreasing. Full monotonicity is required to use the - * function in a GROUP BY clause. - */ - FULLY_MONOTONIC, - - /** - * Indicates that the function is partially monotonic, meaning that partial application over - * some of the its arguments is monotonic. Currently (DSE 6.0.0), CQL only allows partial - * monotonicity on exactly one argument. This may change in a future CQL version. - */ - PARTIALLY_MONOTONIC, - - /** Indicates that the function is not monotonic. */ - NOT_MONOTONIC, - } - - /** @deprecated Use {@link #getDeterministic()} instead. */ - @Deprecated - boolean isDeterministic(); - - /** - * Indicates if this function is deterministic. A deterministic function means that given a - * particular input, the function will always produce the same output. - * - *

This method returns {@linkplain Optional#empty() empty} if this information was not found in - * the system tables, regardless of the actual function characteristics; this is the case for all - * versions of DSE older than 6.0.0. - * - * @return Whether or not this function is deterministic; or {@linkplain Optional#empty() empty} - * if such information is not available in the system tables. - */ - default Optional getDeterministic() { - return Optional.of(isDeterministic()); - } - - /** @deprecated use {@link #getMonotonicity()} instead. */ - @Deprecated - boolean isMonotonic(); - - /** - * Returns this function's {@link Monotonicity}. - * - *

A function can be either: - * - *

    - *
  • fully monotonic. In that case, this method returns {@link Monotonicity#FULLY_MONOTONIC}, - * and {@link #getMonotonicArgumentNames()} returns all the arguments; - *
  • partially monotonic, meaning that partial application over some of the arguments is - * monotonic. Currently (DSE 6.0.0), CQL only allows partial monotonicity on exactly one - * argument. This may change in a future CQL version. In that case, this method returns - * {@link Monotonicity#PARTIALLY_MONOTONIC}, and {@link #getMonotonicArgumentNames()} - * returns a singleton list; - *
  • not monotonic. In that case, this method return {@link Monotonicity#NOT_MONOTONIC} and - * {@link #getMonotonicArgumentNames()} returns an empty list. - *
- * - *

Full monotonicity is required to use the function in a GROUP BY clause. - * - *

This method returns {@linkplain Optional#empty() empty} if this information was not found in - * the system tables, regardless of the actual function characteristics; this is the case for all - * versions of DSE older than 6.0.0. - * - * @return this function's {@link Monotonicity}; or {@linkplain Optional#empty() empty} if such - * information is not available in the system tables. - */ - default Optional getMonotonicity() { - return Optional.of( - isMonotonic() - ? Monotonicity.FULLY_MONOTONIC - : getMonotonicArgumentNames().isEmpty() - ? Monotonicity.NOT_MONOTONIC - : Monotonicity.PARTIALLY_MONOTONIC); - } - - /** - * Returns a list of argument names that are monotonic. - * - *

See {@link #getMonotonicity()} for explanations on monotonicity, and the possible values - * returned by this method. - * - *

NOTE: For versions of DSE older than 6.0.0, this method will always return an empty list, - * regardless of the actual function characteristics. - * - * @return the argument names that the function is monotonic on. - */ - @NonNull - List getMonotonicArgumentNames(); - - @NonNull - @Override - default String describe(boolean pretty) { - ScriptBuilder builder = new ScriptBuilder(pretty); - builder - .append("CREATE FUNCTION ") - .append(getKeyspace()) - .append(".") - .append(getSignature().getName()) - .append("("); - boolean first = true; - for (int i = 0; i < getSignature().getParameterTypes().size(); i++) { - if (first) { - first = false; - } else { - builder.append(","); - } - DataType type = getSignature().getParameterTypes().get(i); - CqlIdentifier name = getParameterNames().get(i); - builder.append(name).append(" ").append(type.asCql(false, pretty)); - } - builder - .append(")") - .increaseIndent() - .newLine() - .append(isCalledOnNullInput() ? "CALLED ON NULL INPUT" : "RETURNS NULL ON NULL INPUT") - .newLine() - .append("RETURNS ") - .append(getReturnType().asCql(false, true)) - .newLine(); - // handle deterministic and monotonic - if (getDeterministic().orElse(false)) { - builder.append("DETERMINISTIC").newLine(); - } - if (getMonotonicity().isPresent()) { - switch (getMonotonicity().get()) { - case FULLY_MONOTONIC: - builder.append("MONOTONIC").newLine(); - break; - case PARTIALLY_MONOTONIC: - builder.append("MONOTONIC ON ").append(getMonotonicArgumentNames().get(0)).newLine(); - break; - default: - break; - } - } - builder - .append("LANGUAGE ") - .append(getLanguage()) - .newLine() - .append("AS '") - .append(getBody()) - .append("';"); - return builder.build(); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseGraphKeyspaceMetadata.java b/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseGraphKeyspaceMetadata.java deleted file mode 100644 index 8978a8858f9..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseGraphKeyspaceMetadata.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.metadata.schema; - -import com.datastax.oss.driver.api.core.metadata.schema.KeyspaceMetadata; -import com.datastax.oss.driver.internal.core.metadata.schema.ScriptBuilder; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Map; -import java.util.Optional; - -/** - * Specialized keyspace metadata, that handles the graph-specific properties introduced in DSE 6.8. - * - *

This type only exists to avoid breaking binary compatibility. When the driver is connected to - * a DSE cluster, all the {@link KeyspaceMetadata} instances it returns can be safely downcast to - * this interface. - */ -public interface DseGraphKeyspaceMetadata extends DseKeyspaceMetadata { - - /** The graph engine that will be used to interpret this keyspace. */ - @NonNull - Optional getGraphEngine(); - - @NonNull - @Override - default String describe(boolean pretty) { - ScriptBuilder builder = new ScriptBuilder(pretty); - if (isVirtual()) { - builder.append("/* VIRTUAL "); - } else { - builder.append("CREATE "); - } - builder - .append("KEYSPACE ") - .append(getName()) - .append(" WITH replication = { 'class' : '") - .append(getReplication().get("class")) - .append("'"); - for (Map.Entry entry : getReplication().entrySet()) { - if (!entry.getKey().equals("class")) { - builder - .append(", '") - .append(entry.getKey()) - .append("': '") - .append(entry.getValue()) - .append("'"); - } - } - builder.append(" } AND durable_writes = ").append(Boolean.toString(isDurableWrites())); - getGraphEngine() - .ifPresent( - graphEngine -> builder.append(" AND graph_engine ='").append(graphEngine).append("'")); - builder.append(";"); - if (isVirtual()) { - builder.append(" */"); - } - return builder.build(); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseGraphTableMetadata.java b/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseGraphTableMetadata.java deleted file mode 100644 index 8f340b3b447..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseGraphTableMetadata.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.metadata.schema; - -import com.datastax.dse.driver.internal.core.metadata.schema.ScriptHelper; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.metadata.schema.ClusteringOrder; -import com.datastax.oss.driver.api.core.metadata.schema.ColumnMetadata; -import com.datastax.oss.driver.api.core.metadata.schema.TableMetadata; -import com.datastax.oss.driver.internal.core.metadata.schema.ScriptBuilder; -import com.datastax.oss.driver.internal.core.metadata.schema.parsing.RelationParser; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Map; -import java.util.Optional; - -/** - * Specialized table metadata, that handles the graph-specific properties introduced in DSE 6.8. - * - *

This type only exists to avoid breaking binary compatibility. When the driver is connected to - * a DSE cluster, all the {@link TableMetadata} instances it returns can be safely downcast to this - * interface. - */ -public interface DseGraphTableMetadata extends DseTableMetadata { - /** - * The vertex metadata if this table represents a vertex in graph, otherwise empty. - * - *

This is mutually exclusive with {@link #getEdge()}. - */ - @NonNull - Optional getVertex(); - - /** - * The edge metadata if this table represents an edge in graph, otherwise empty. - * - *

This is mutually exclusive with {@link #getVertex()}. - */ - @NonNull - Optional getEdge(); - - @NonNull - @Override - default String describe(boolean pretty) { - ScriptBuilder builder = new ScriptBuilder(pretty); - if (isVirtual()) { - builder.append("/* VIRTUAL "); - } else { - builder.append("CREATE "); - } - - builder - .append("TABLE ") - .append(getKeyspace()) - .append(".") - .append(getName()) - .append(" (") - .newLine() - .increaseIndent(); - - for (ColumnMetadata column : getColumns().values()) { - builder.append(column.getName()).append(" ").append(column.getType().asCql(true, pretty)); - if (column.isStatic()) { - builder.append(" static"); - } - builder.append(",").newLine(); - } - - // PK - builder.append("PRIMARY KEY ("); - if (getPartitionKey().size() == 1) { // PRIMARY KEY (k - builder.append(getPartitionKey().get(0).getName()); - } else { // PRIMARY KEY ((k1, k2) - builder.append("("); - boolean first = true; - for (ColumnMetadata pkColumn : getPartitionKey()) { - if (first) { - first = false; - } else { - builder.append(", "); - } - builder.append(pkColumn.getName()); - } - builder.append(")"); - } - // PRIMARY KEY (, cc1, cc2, cc3) - for (ColumnMetadata clusteringColumn : getClusteringColumns().keySet()) { - builder.append(", ").append(clusteringColumn.getName()); - } - builder.append(")"); - - builder.newLine().decreaseIndent().append(")"); - - builder.increaseIndent(); - if (isCompactStorage()) { - builder.andWith().append("COMPACT STORAGE"); - } - if (getClusteringColumns().containsValue(ClusteringOrder.DESC)) { - builder.andWith().append("CLUSTERING ORDER BY ("); - boolean first = true; - for (Map.Entry entry : - getClusteringColumns().entrySet()) { - if (first) { - first = false; - } else { - builder.append(", "); - } - builder.append(entry.getKey().getName()).append(" ").append(entry.getValue().name()); - } - builder.append(")"); - } - getVertex() - .ifPresent( - vertex -> { - builder.andWith().append("VERTEX LABEL").append(" ").append(vertex.getLabelName()); - }); - getEdge() - .ifPresent( - edge -> { - builder.andWith().append("EDGE LABEL").append(" ").append(edge.getLabelName()); - ScriptHelper.appendEdgeSide( - builder, - edge.getFromTable(), - edge.getFromLabel(), - edge.getFromPartitionKeyColumns(), - edge.getFromClusteringColumns(), - "FROM"); - ScriptHelper.appendEdgeSide( - builder, - edge.getToTable(), - edge.getToLabel(), - edge.getToPartitionKeyColumns(), - edge.getToClusteringColumns(), - "TO"); - }); - Map options = getOptions(); - RelationParser.appendOptions(options, builder); - builder.append(";"); - if (isVirtual()) { - builder.append(" */"); - } - return builder.build(); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseIndexMetadata.java b/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseIndexMetadata.java deleted file mode 100644 index ac4c1057fbf..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseIndexMetadata.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.metadata.schema; - -import com.datastax.oss.driver.api.core.metadata.schema.IndexMetadata; - -/** - * Specialized index metadata for DSE. - * - *

This type exists only for future extensibility; currently, it is identical to {@link - * IndexMetadata}. - */ -public interface DseIndexMetadata extends IndexMetadata {} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseKeyspaceMetadata.java b/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseKeyspaceMetadata.java deleted file mode 100644 index bc5cb002802..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseKeyspaceMetadata.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.metadata.schema; - -import com.datastax.oss.driver.api.core.metadata.schema.KeyspaceMetadata; -import com.datastax.oss.driver.api.core.metadata.schema.TableMetadata; - -/** - * Specialized keyspace metadata for DSE. - * - *

Notes: - * - *

    - *
  • this type can always be safely downcast to {@link DseGraphKeyspaceMetadata} (the only - * reason the two interfaces are separate is for backward compatibility). - *
  • all returned elements can be cast to their DSE counterparts, for example {@link - * TableMetadata} to {@link DseTableMetadata}. - *
- */ -public interface DseKeyspaceMetadata extends KeyspaceMetadata {} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseRelationMetadata.java b/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseRelationMetadata.java deleted file mode 100644 index 55b36cb7fe5..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseRelationMetadata.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.metadata.schema; - -import com.datastax.oss.driver.api.core.metadata.schema.ColumnMetadata; -import com.datastax.oss.driver.api.core.metadata.schema.RelationMetadata; - -/** - * Specialized table or materialized view metadata for DSE. - * - *

This type exists only for future extensibility; currently, it is identical to {@link - * RelationMetadata}. - * - *

Note that all returned {@link ColumnMetadata} can be cast to {@link DseColumnMetadata}. - */ -public interface DseRelationMetadata extends RelationMetadata {} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseTableMetadata.java b/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseTableMetadata.java deleted file mode 100644 index a140f93bc2e..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseTableMetadata.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.metadata.schema; - -import com.datastax.oss.driver.api.core.metadata.schema.ColumnMetadata; -import com.datastax.oss.driver.api.core.metadata.schema.IndexMetadata; -import com.datastax.oss.driver.api.core.metadata.schema.TableMetadata; - -/** - * Specialized table metadata for DSE. - * - *

Notes: - * - *

    - *
  • this type can always be safely downcast to {@link DseGraphTableMetadata} (the only reason - * the two interfaces are separate is for backward compatibility). - *
  • all returned {@link ColumnMetadata} can be cast to {@link DseColumnMetadata}, and all - * {@link IndexMetadata} to {@link DseIndexMetadata}. - *
- */ -public interface DseTableMetadata extends DseRelationMetadata, TableMetadata {} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseViewMetadata.java b/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseViewMetadata.java deleted file mode 100644 index 0f68ea7e456..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseViewMetadata.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.metadata.schema; - -import com.datastax.oss.driver.api.core.metadata.schema.ColumnMetadata; -import com.datastax.oss.driver.api.core.metadata.schema.ViewMetadata; - -/** - * Specialized materialized view metadata for DSE. - * - *

This type exists only for future extensibility; currently, it is identical to {@link - * ViewMetadata}. - * - *

Note that all returned {@link ColumnMetadata} can be cast to {@link DseColumnMetadata}. - */ -public interface DseViewMetadata extends DseRelationMetadata, ViewMetadata {} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/metrics/DseNodeMetric.java b/core/src/main/java/com/datastax/dse/driver/api/core/metrics/DseNodeMetric.java deleted file mode 100644 index cf4b4d0aa18..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/metrics/DseNodeMetric.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.metrics; - -import com.datastax.oss.driver.api.core.metrics.NodeMetric; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Map; - -/** See {@code reference.conf} for a description of each metric. */ -public enum DseNodeMetric implements NodeMetric { - GRAPH_MESSAGES("graph-messages"); - - private static final Map BY_PATH = sortByPath(); - - private final String path; - - DseNodeMetric(String path) { - this.path = path; - } - - @Override - @NonNull - public String getPath() { - return path; - } - - @NonNull - public static DseNodeMetric fromPath(@NonNull String path) { - DseNodeMetric metric = BY_PATH.get(path); - if (metric == null) { - throw new IllegalArgumentException("Unknown node metric path " + path); - } - return metric; - } - - private static Map sortByPath() { - ImmutableMap.Builder result = ImmutableMap.builder(); - for (DseNodeMetric value : values()) { - result.put(value.getPath(), value); - } - return result.build(); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/metrics/DseSessionMetric.java b/core/src/main/java/com/datastax/dse/driver/api/core/metrics/DseSessionMetric.java deleted file mode 100644 index 79584f3c44a..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/metrics/DseSessionMetric.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.metrics; - -import com.datastax.oss.driver.api.core.metrics.SessionMetric; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Map; - -/** See {@code reference.conf} for a description of each metric. */ -public enum DseSessionMetric implements SessionMetric { - CONTINUOUS_CQL_REQUESTS("continuous-cql-requests"), - GRAPH_REQUESTS("graph-requests"), - GRAPH_CLIENT_TIMEOUTS("graph-client-timeouts"), - ; - - private static final Map BY_PATH = sortByPath(); - - private final String path; - - DseSessionMetric(String path) { - this.path = path; - } - - @NonNull - @Override - public String getPath() { - return path; - } - - @NonNull - public static DseSessionMetric fromPath(@NonNull String path) { - DseSessionMetric metric = BY_PATH.get(path); - if (metric == null) { - throw new IllegalArgumentException("Unknown DSE session metric path " + path); - } - return metric; - } - - private static Map sortByPath() { - ImmutableMap.Builder result = ImmutableMap.builder(); - for (DseSessionMetric value : values()) { - result.put(value.getPath(), value); - } - return result.build(); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/servererrors/UnfitClientException.java b/core/src/main/java/com/datastax/dse/driver/api/core/servererrors/UnfitClientException.java deleted file mode 100644 index 8bf4d80699d..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/servererrors/UnfitClientException.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.servererrors; - -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.datastax.oss.driver.api.core.servererrors.CoordinatorException; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; - -/** - * A server-side error triggered when DSE can't send asynchronous results back to the client. - * - *

Currently, this is used when the client is unable to keep up with the rate during a continuous - * paging session. - * - *

Note that the protocol specification refers to this error as {@code CLIENT_WRITE_FAILURE}; we - * don't follow that terminology because it would be too misleading (this is not a client error, and - * it doesn't occur while writing data to DSE). - */ -public class UnfitClientException extends CoordinatorException { - - public UnfitClientException(@NonNull Node coordinator, @NonNull String message) { - this(coordinator, message, null, false); - } - - private UnfitClientException( - @NonNull Node coordinator, - @NonNull String message, - @Nullable ExecutionInfo executionInfo, - boolean writableStackTrace) { - super(coordinator, message, executionInfo, writableStackTrace); - } - - @Override - @NonNull - public UnfitClientException copy() { - return new UnfitClientException(getCoordinator(), getMessage(), getExecutionInfo(), true); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/type/DseDataTypes.java b/core/src/main/java/com/datastax/dse/driver/api/core/type/DseDataTypes.java deleted file mode 100644 index 6003274e09a..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/type/DseDataTypes.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.type; - -import com.datastax.oss.driver.api.core.type.CustomType; -import com.datastax.oss.driver.api.core.type.DataTypes; - -/** Extends {@link DataTypes} to handle DSE-specific types. */ -public class DseDataTypes extends DataTypes { - - public static final CustomType LINE_STRING = - (CustomType) custom("org.apache.cassandra.db.marshal.LineStringType"); - - public static final CustomType POINT = - (CustomType) custom("org.apache.cassandra.db.marshal.PointType"); - - public static final CustomType POLYGON = - (CustomType) custom("org.apache.cassandra.db.marshal.PolygonType"); - - public static final CustomType DATE_RANGE = - (CustomType) custom("org.apache.cassandra.db.marshal.DateRangeType"); -} diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/type/codec/DseTypeCodecs.java b/core/src/main/java/com/datastax/dse/driver/api/core/type/codec/DseTypeCodecs.java deleted file mode 100644 index fb0225970b4..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/api/core/type/codec/DseTypeCodecs.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.type.codec; - -import com.datastax.dse.driver.api.core.data.geometry.LineString; -import com.datastax.dse.driver.api.core.data.geometry.Point; -import com.datastax.dse.driver.api.core.data.geometry.Polygon; -import com.datastax.dse.driver.api.core.data.time.DateRange; -import com.datastax.dse.driver.internal.core.type.codec.geometry.LineStringCodec; -import com.datastax.dse.driver.internal.core.type.codec.geometry.PointCodec; -import com.datastax.dse.driver.internal.core.type.codec.geometry.PolygonCodec; -import com.datastax.dse.driver.internal.core.type.codec.time.DateRangeCodec; -import com.datastax.oss.driver.api.core.type.codec.TypeCodec; -import com.datastax.oss.driver.api.core.type.codec.TypeCodecs; - -/** Extends {@link TypeCodecs} to handle DSE-specific types. */ -public class DseTypeCodecs extends TypeCodecs { - - public static final TypeCodec LINE_STRING = new LineStringCodec(); - - public static final TypeCodec POINT = new PointCodec(); - - public static final TypeCodec POLYGON = new PolygonCodec(); - - public static final TypeCodec DATE_RANGE = new DateRangeCodec(); -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/DseProtocolFeature.java b/core/src/main/java/com/datastax/dse/driver/internal/core/DseProtocolFeature.java deleted file mode 100644 index 95f245061d2..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/DseProtocolFeature.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core; - -import com.datastax.oss.driver.internal.core.ProtocolFeature; - -/** - * Features that are supported by DataStax Enterprise (DSE) protocol versions. - * - * @see com.datastax.dse.driver.api.core.DseProtocolVersion - * @see com.datastax.oss.driver.internal.core.DefaultProtocolFeature - */ -public enum DseProtocolFeature implements ProtocolFeature { - - /** - * The ability to execute continuous paging requests. - * - * @see CASSANDRA-11521 - * @see com.datastax.dse.driver.api.core.cql.continuous.ContinuousSession - */ - CONTINUOUS_PAGING, - ; -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/InsightsClientLifecycleListener.java b/core/src/main/java/com/datastax/dse/driver/internal/core/InsightsClientLifecycleListener.java deleted file mode 100644 index e4dd6f93bf7..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/InsightsClientLifecycleListener.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core; - -import static com.datastax.dse.driver.api.core.config.DseDriverOption.MONITOR_REPORTING_ENABLED; - -import com.datastax.dse.driver.internal.core.insights.InsightsClient; -import com.datastax.dse.driver.internal.core.insights.configuration.InsightsConfiguration; -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import com.datastax.oss.driver.internal.core.context.LifecycleListener; - -public class InsightsClientLifecycleListener implements LifecycleListener { - private static final boolean DEFAULT_INSIGHTS_ENABLED = true; - private static final long STATUS_EVENT_DELAY_MILLIS = 300000L; - private final InternalDriverContext context; - private final StackTraceElement[] initCallStackTrace; - private volatile InsightsClient insightsClient; - - public InsightsClientLifecycleListener( - InternalDriverContext context, StackTraceElement[] initCallStackTrace) { - this.context = context; - this.initCallStackTrace = initCallStackTrace; - } - - @Override - public void onSessionReady() { - boolean monitorReportingEnabled = - context - .getConfig() - .getDefaultProfile() - .getBoolean(MONITOR_REPORTING_ENABLED, DEFAULT_INSIGHTS_ENABLED); - - this.insightsClient = - InsightsClient.createInsightsClient( - new InsightsConfiguration( - monitorReportingEnabled, - STATUS_EVENT_DELAY_MILLIS, - context.getNettyOptions().adminEventExecutorGroup().next()), - context, - initCallStackTrace); - insightsClient.sendStartupMessage(); - insightsClient.scheduleStatusMessageSend(); - } - - @Override - public void close() { - if (insightsClient != null) { - insightsClient.shutdown(); - } - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/auth/DseGssApiAuthProvider.java b/core/src/main/java/com/datastax/dse/driver/internal/core/auth/DseGssApiAuthProvider.java deleted file mode 100644 index 6ef6596a870..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/auth/DseGssApiAuthProvider.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.auth; - -import com.datastax.dse.driver.api.core.auth.DseGssApiAuthProviderBase; -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.oss.driver.api.core.auth.AuthProvider; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.context.DriverContext; -import com.datastax.oss.driver.api.core.metadata.EndPoint; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Map; -import net.jcip.annotations.ThreadSafe; - -/** - * {@link AuthProvider} that provides GSSAPI authenticator instances for clients to connect to DSE - * clusters secured with {@code DseAuthenticator}. - * - *

To activate this provider an {@code auth-provider} section must be included in the driver - * configuration, for example: - * - *

- * dse-java-driver {
- *  auth-provider {
- *      class = com.datastax.dse.driver.internal.core.auth.DseGssApiAuthProvider
- *      login-configuration {
- *          principal = "user principal here ex cassandra@DATASTAX.COM"
- *          useKeyTab = "true"
- *          refreshKrb5Config = "true"
- *          keyTab = "Path to keytab file here"
- *      }
- *   }
- * }
- * 
- * - *

Kerberos Authentication

- * - * Keytab and ticket cache settings are specified using a standard JAAS configuration file. The - * location of the file can be set using the java.security.auth.login.config system - * property or by adding a login.config.url.n entry in the java.security - * properties file. Alternatively a login-configuration section can be included in the driver - * configuration. - * - *

See the following documents for further details: - * - *

    - *
  1. JAAS - * Login Configuration File; - *
  2. Krb5LoginModule - * options; - *
  3. JAAS - * Authentication Tutorial for more on JAAS in general. - *
- * - *

Authentication using ticket cache

- * - * Run kinit to obtain a ticket and populate the cache before connecting. JAAS config: - * - *
- * DseClient {
- *   com.sun.security.auth.module.Krb5LoginModule required
- *     useTicketCache=true
- *     renewTGT=true;
- * };
- * 
- * - *

Authentication using a keytab file

- * - * To enable authentication using a keytab file, specify its location on disk. If your keytab - * contains more than one principal key, you should also specify which one to select. This - * information can also be specified in the driver config, under the login-configuration section. - * - *
- * DseClient {
- *     com.sun.security.auth.module.Krb5LoginModule required
- *       useKeyTab=true
- *       keyTab="/path/to/file.keytab"
- *       principal="user@MYDOMAIN.COM";
- * };
- * 
- * - *

Specifying SASL protocol name

- * - * The SASL protocol name used by this auth provider defaults to " - * {@value #DEFAULT_SASL_SERVICE_NAME}". - * - *

Important: the SASL protocol name should match the username of the Kerberos - * service principal used by the DSE server. This information is specified in the dse.yaml file by - * the {@code service_principal} option under the kerberos_options - * section, and may vary from one DSE installation to another – especially if you installed - * DSE with an automated package installer. - * - *

For example, if your dse.yaml file contains the following: - * - *

{@code
- * kerberos_options:
- *     ...
- *     service_principal: cassandra/my.host.com@MY.REALM.COM
- * }
- * - * The correct SASL protocol name to use when authenticating against this DSE server is "{@code - * cassandra}". - * - *

Should you need to change the SASL protocol name, use one of the methods below: - * - *

    - *
  1. Specify the service name in the driver config. - *
    - * dse-java-driver {
    - *   auth-provider {
    - *     class = com.datastax.dse.driver.internal.core.auth.DseGssApiAuthProvider
    - *     service = "alternate"
    - *   }
    - * }
    - * 
    - *
  2. Specify the service name with the {@code dse.sasl.service} system property when starting - * your application, e.g. {@code -Ddse.sasl.service=cassandra}. - *
- * - * If a non-null SASL service name is provided to the aforementioned config, that name takes - * precedence over the contents of the {@code dse.sasl.service} system property. - * - *

Should internal sasl properties need to be set such as qop. This can be accomplished by - * including a sasl-properties in the driver config, for example: - * - *

- * dse-java-driver {
- *   auth-provider {
- *     class = com.datastax.dse.driver.internal.core.auth.DseGssApiAuthProvider
- *     sasl-properties {
- *       javax.security.sasl.qop = "auth-conf"
- *     }
- *   }
- * }
- * 
- */ -@ThreadSafe -public class DseGssApiAuthProvider extends DseGssApiAuthProviderBase { - - private final DriverExecutionProfile config; - - public DseGssApiAuthProvider(DriverContext context) { - super(context.getSessionName()); - - this.config = context.getConfig().getDefaultProfile(); - } - - @NonNull - @Override - protected GssApiOptions getOptions( - @NonNull EndPoint endPoint, @NonNull String serverAuthenticator) { - // A login configuration is always necessary, throw an exception if that option is missing. - AuthUtils.validateConfigPresent( - config, - DseGssApiAuthProvider.class.getName(), - endPoint, - DseDriverOption.AUTH_PROVIDER_LOGIN_CONFIGURATION); - - GssApiOptions.Builder optionsBuilder = GssApiOptions.builder(); - - if (config.isDefined(DseDriverOption.AUTH_PROVIDER_AUTHORIZATION_ID)) { - optionsBuilder.withAuthorizationId( - config.getString(DseDriverOption.AUTH_PROVIDER_AUTHORIZATION_ID)); - } - if (config.isDefined(DseDriverOption.AUTH_PROVIDER_SERVICE)) { - optionsBuilder.withSaslProtocol(config.getString(DseDriverOption.AUTH_PROVIDER_SERVICE)); - } - if (config.isDefined(DseDriverOption.AUTH_PROVIDER_SASL_PROPERTIES)) { - for (Map.Entry entry : - config.getStringMap(DseDriverOption.AUTH_PROVIDER_SASL_PROPERTIES).entrySet()) { - optionsBuilder.addSaslProperty(entry.getKey(), entry.getValue()); - } - } - Map loginConfigurationMap = - config.getStringMap(DseDriverOption.AUTH_PROVIDER_LOGIN_CONFIGURATION); - optionsBuilder.withLoginConfiguration(loginConfigurationMap); - return optionsBuilder.build(); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/auth/DsePlainTextAuthProvider.java b/core/src/main/java/com/datastax/dse/driver/internal/core/auth/DsePlainTextAuthProvider.java deleted file mode 100644 index 6cf82aef03e..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/auth/DsePlainTextAuthProvider.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.auth; - -import com.datastax.oss.driver.api.core.context.DriverContext; -import com.datastax.oss.driver.internal.core.auth.PlainTextAuthProvider; -import net.jcip.annotations.ThreadSafe; - -/** - * @deprecated The driver's default plain text providers now support both Apache Cassandra and DSE. - * This type was preserved for backward compatibility, but {@link PlainTextAuthProvider} should - * be used instead. - */ -@ThreadSafe -@Deprecated -public class DsePlainTextAuthProvider extends PlainTextAuthProvider { - - public DsePlainTextAuthProvider(DriverContext context) { - super(context); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/cql/DseConversions.java b/core/src/main/java/com/datastax/dse/driver/internal/core/cql/DseConversions.java deleted file mode 100644 index bf20aa18036..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/cql/DseConversions.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.cql; - -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.dse.driver.api.core.servererrors.UnfitClientException; -import com.datastax.dse.protocol.internal.DseProtocolConstants; -import com.datastax.dse.protocol.internal.request.query.ContinuousPagingOptions; -import com.datastax.dse.protocol.internal.request.query.DseQueryOptions; -import com.datastax.oss.driver.api.core.ConsistencyLevel; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.ProtocolVersion; -import com.datastax.oss.driver.api.core.config.DefaultDriverOption; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.cql.BoundStatement; -import com.datastax.oss.driver.api.core.cql.PreparedStatement; -import com.datastax.oss.driver.api.core.cql.SimpleStatement; -import com.datastax.oss.driver.api.core.cql.Statement; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.datastax.oss.driver.api.core.servererrors.CoordinatorException; -import com.datastax.oss.driver.api.core.type.codec.registry.CodecRegistry; -import com.datastax.oss.driver.internal.core.ConsistencyLevelRegistry; -import com.datastax.oss.driver.internal.core.DefaultProtocolFeature; -import com.datastax.oss.driver.internal.core.ProtocolVersionRegistry; -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import com.datastax.oss.driver.internal.core.cql.Conversions; -import com.datastax.oss.driver.internal.core.cql.DefaultPreparedStatement; -import com.datastax.oss.protocol.internal.Message; -import com.datastax.oss.protocol.internal.request.Execute; -import com.datastax.oss.protocol.internal.request.Query; -import com.datastax.oss.protocol.internal.response.Error; -import com.datastax.oss.protocol.internal.util.Bytes; -import java.nio.ByteBuffer; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -public class DseConversions { - - public static Message toContinuousPagingMessage( - Statement statement, DriverExecutionProfile config, InternalDriverContext context) { - ConsistencyLevelRegistry consistencyLevelRegistry = context.getConsistencyLevelRegistry(); - ConsistencyLevel consistency = statement.getConsistencyLevel(); - int consistencyCode = - (consistency == null) - ? consistencyLevelRegistry.nameToCode( - config.getString(DefaultDriverOption.REQUEST_CONSISTENCY)) - : consistency.getProtocolCode(); - int pageSize = config.getInt(DseDriverOption.CONTINUOUS_PAGING_PAGE_SIZE); - boolean pageSizeInBytes = config.getBoolean(DseDriverOption.CONTINUOUS_PAGING_PAGE_SIZE_BYTES); - int maxPages = config.getInt(DseDriverOption.CONTINUOUS_PAGING_MAX_PAGES); - int maxPagesPerSecond = config.getInt(DseDriverOption.CONTINUOUS_PAGING_MAX_PAGES_PER_SECOND); - int maxEnqueuedPages = config.getInt(DseDriverOption.CONTINUOUS_PAGING_MAX_ENQUEUED_PAGES); - ContinuousPagingOptions options = - new ContinuousPagingOptions(maxPages, maxPagesPerSecond, maxEnqueuedPages); - ConsistencyLevel serialConsistency = statement.getSerialConsistencyLevel(); - int serialConsistencyCode = - (serialConsistency == null) - ? consistencyLevelRegistry.nameToCode( - config.getString(DefaultDriverOption.REQUEST_SERIAL_CONSISTENCY)) - : serialConsistency.getProtocolCode(); - long timestamp = statement.getQueryTimestamp(); - if (timestamp == Statement.NO_DEFAULT_TIMESTAMP) { - timestamp = context.getTimestampGenerator().next(); - } - CodecRegistry codecRegistry = context.getCodecRegistry(); - ProtocolVersion protocolVersion = context.getProtocolVersion(); - ProtocolVersionRegistry protocolVersionRegistry = context.getProtocolVersionRegistry(); - CqlIdentifier keyspace = statement.getKeyspace(); - if (statement instanceof SimpleStatement) { - SimpleStatement simpleStatement = (SimpleStatement) statement; - List positionalValues = simpleStatement.getPositionalValues(); - Map namedValues = simpleStatement.getNamedValues(); - if (!positionalValues.isEmpty() && !namedValues.isEmpty()) { - throw new IllegalArgumentException( - "Can't have both positional and named values in a statement."); - } - if (keyspace != null - && !protocolVersionRegistry.supports( - protocolVersion, DefaultProtocolFeature.PER_REQUEST_KEYSPACE)) { - throw new IllegalArgumentException( - "Can't use per-request keyspace with protocol " + protocolVersion); - } - DseQueryOptions queryOptions = - new DseQueryOptions( - consistencyCode, - Conversions.encode(positionalValues, codecRegistry, protocolVersion), - Conversions.encode(namedValues, codecRegistry, protocolVersion), - false, - pageSize, - statement.getPagingState(), - serialConsistencyCode, - timestamp, - (keyspace == null) ? null : keyspace.asInternal(), - pageSizeInBytes, - options); - return new Query(simpleStatement.getQuery(), queryOptions); - } else if (statement instanceof BoundStatement) { - BoundStatement boundStatement = (BoundStatement) statement; - if (!protocolVersionRegistry.supports( - protocolVersion, DefaultProtocolFeature.UNSET_BOUND_VALUES)) { - Conversions.ensureAllSet(boundStatement); - } - - boolean skipMetadata; - if (boundStatement.getPreparedStatement() instanceof DefaultPreparedStatement) { - skipMetadata = - ((DefaultPreparedStatement) boundStatement.getPreparedStatement()).isSkipMetadata(); - } else { - skipMetadata = boundStatement.getPreparedStatement().getResultSetDefinitions().size() > 0; - ; - } - DseQueryOptions queryOptions = - new DseQueryOptions( - consistencyCode, - boundStatement.getValues(), - Collections.emptyMap(), - skipMetadata, - pageSize, - statement.getPagingState(), - serialConsistencyCode, - timestamp, - null, - pageSizeInBytes, - options); - PreparedStatement preparedStatement = boundStatement.getPreparedStatement(); - ByteBuffer id = preparedStatement.getId(); - ByteBuffer resultMetadataId = preparedStatement.getResultMetadataId(); - return new Execute( - Bytes.getArray(id), - (resultMetadataId == null) ? null : Bytes.getArray(resultMetadataId), - queryOptions); - } else { - throw new IllegalArgumentException( - "Unsupported statement type: " + statement.getClass().getName()); - } - } - - public static CoordinatorException toThrowable( - Node node, Error errorMessage, InternalDriverContext context) { - switch (errorMessage.code) { - case DseProtocolConstants.ErrorCode.CLIENT_WRITE_FAILURE: - return new UnfitClientException(node, errorMessage.message); - default: - return Conversions.toThrowable(node, errorMessage, context); - } - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/cql/continuous/ContinuousCqlRequestAsyncProcessor.java b/core/src/main/java/com/datastax/dse/driver/internal/core/cql/continuous/ContinuousCqlRequestAsyncProcessor.java deleted file mode 100644 index 8a098bf2895..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/cql/continuous/ContinuousCqlRequestAsyncProcessor.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.cql.continuous; - -import com.datastax.dse.driver.api.core.cql.continuous.ContinuousAsyncResultSet; -import com.datastax.oss.driver.api.core.cql.Statement; -import com.datastax.oss.driver.api.core.session.Request; -import com.datastax.oss.driver.api.core.type.reflect.GenericType; -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import com.datastax.oss.driver.internal.core.session.DefaultSession; -import com.datastax.oss.driver.internal.core.session.RequestProcessor; -import com.datastax.oss.driver.internal.core.util.concurrent.CompletableFutures; -import java.util.concurrent.CompletionStage; -import net.jcip.annotations.ThreadSafe; - -@ThreadSafe -public class ContinuousCqlRequestAsyncProcessor - implements RequestProcessor, CompletionStage> { - - public static final GenericType> - CONTINUOUS_RESULT_ASYNC = new GenericType>() {}; - - @Override - public boolean canProcess(Request request, GenericType resultType) { - return request instanceof Statement && resultType.equals(CONTINUOUS_RESULT_ASYNC); - } - - @Override - public CompletionStage process( - Statement request, - DefaultSession session, - InternalDriverContext context, - String sessionLogPrefix) { - return new ContinuousCqlRequestHandler(request, session, context, sessionLogPrefix).handle(); - } - - @Override - public CompletionStage newFailure(RuntimeException error) { - return CompletableFutures.failedFuture(error); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/cql/continuous/ContinuousCqlRequestHandler.java b/core/src/main/java/com/datastax/dse/driver/internal/core/cql/continuous/ContinuousCqlRequestHandler.java deleted file mode 100644 index dd308c11854..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/cql/continuous/ContinuousCqlRequestHandler.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.cql.continuous; - -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.dse.driver.api.core.cql.continuous.ContinuousAsyncResultSet; -import com.datastax.dse.driver.api.core.metrics.DseSessionMetric; -import com.datastax.dse.driver.internal.core.cql.DseConversions; -import com.datastax.dse.protocol.internal.response.result.DseRowsMetadata; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.cql.ColumnDefinitions; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import com.datastax.oss.driver.api.core.cql.Row; -import com.datastax.oss.driver.api.core.cql.Statement; -import com.datastax.oss.driver.api.core.metrics.DefaultNodeMetric; -import com.datastax.oss.driver.api.core.metrics.DefaultSessionMetric; -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import com.datastax.oss.driver.internal.core.cql.Conversions; -import com.datastax.oss.driver.internal.core.cql.DefaultRow; -import com.datastax.oss.driver.internal.core.session.DefaultSession; -import com.datastax.oss.driver.internal.core.util.CountingIterator; -import com.datastax.oss.protocol.internal.Message; -import com.datastax.oss.protocol.internal.response.result.Rows; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.nio.ByteBuffer; -import java.time.Duration; -import java.util.List; -import java.util.Map; -import java.util.Queue; -import net.jcip.annotations.ThreadSafe; - -/** - * Handles a request that supports multiple response messages (a.k.a. continuous paging request). - */ -@ThreadSafe -public class ContinuousCqlRequestHandler - extends ContinuousRequestHandlerBase, ContinuousAsyncResultSet> { - - ContinuousCqlRequestHandler( - @NonNull Statement statement, - @NonNull DefaultSession session, - @NonNull InternalDriverContext context, - @NonNull String sessionLogPrefix) { - super( - statement, - session, - context, - sessionLogPrefix, - ContinuousAsyncResultSet.class, - false, - DefaultSessionMetric.CQL_CLIENT_TIMEOUTS, - DseSessionMetric.CONTINUOUS_CQL_REQUESTS, - DefaultNodeMetric.CQL_MESSAGES); - // NOTE that ordering of the following statement matters. - // We should register this request after all fields have been initialized. - throttler.register(this); - } - - @NonNull - @Override - protected Duration getGlobalTimeout() { - return Duration.ZERO; - } - - @NonNull - @Override - protected Duration getPageTimeout(@NonNull Statement statement, int pageNumber) { - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(statement, context); - if (pageNumber == 1) { - return executionProfile.getDuration(DseDriverOption.CONTINUOUS_PAGING_TIMEOUT_FIRST_PAGE); - } else { - return executionProfile.getDuration(DseDriverOption.CONTINUOUS_PAGING_TIMEOUT_OTHER_PAGES); - } - } - - @NonNull - @Override - protected Duration getReviseRequestTimeout(@NonNull Statement statement) { - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(statement, context); - return executionProfile.getDuration(DseDriverOption.CONTINUOUS_PAGING_TIMEOUT_OTHER_PAGES); - } - - @Override - protected int getMaxEnqueuedPages(@NonNull Statement statement) { - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(statement, context); - return executionProfile.getInt(DseDriverOption.CONTINUOUS_PAGING_MAX_ENQUEUED_PAGES); - } - - @Override - protected int getMaxPages(@NonNull Statement statement) { - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(statement, context); - return executionProfile.getInt(DseDriverOption.CONTINUOUS_PAGING_MAX_PAGES); - } - - @NonNull - @Override - protected Message getMessage(@NonNull Statement statement) { - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(statement, context); - return DseConversions.toContinuousPagingMessage(statement, executionProfile, context); - } - - @Override - protected boolean isTracingEnabled(@NonNull Statement statement) { - return false; - } - - @NonNull - @Override - protected Map createPayload(@NonNull Statement statement) { - return statement.getCustomPayload(); - } - - @NonNull - @Override - protected ContinuousAsyncResultSet createEmptyResultSet(@NonNull ExecutionInfo executionInfo) { - return DefaultContinuousAsyncResultSet.empty(executionInfo); - } - - @NonNull - @Override - protected DefaultContinuousAsyncResultSet createResultSet( - @NonNull Statement statement, - @NonNull Rows rows, - @NonNull ExecutionInfo executionInfo, - @NonNull ColumnDefinitions columnDefinitions) { - Queue> data = rows.getData(); - CountingIterator iterator = - new CountingIterator(data.size()) { - @Override - protected Row computeNext() { - List rowData = data.poll(); - return (rowData == null) - ? endOfData() - : new DefaultRow(columnDefinitions, rowData, context); - } - }; - DseRowsMetadata metadata = (DseRowsMetadata) rows.getMetadata(); - return new DefaultContinuousAsyncResultSet( - iterator, - columnDefinitions, - metadata.continuousPageNumber, - !metadata.isLastContinuousPage, - executionInfo, - this); - } - - @Override - protected int pageNumber(@NonNull ContinuousAsyncResultSet resultSet) { - return resultSet.pageNumber(); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/cql/continuous/ContinuousCqlRequestSyncProcessor.java b/core/src/main/java/com/datastax/dse/driver/internal/core/cql/continuous/ContinuousCqlRequestSyncProcessor.java deleted file mode 100644 index f151eb7eae2..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/cql/continuous/ContinuousCqlRequestSyncProcessor.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.cql.continuous; - -import com.datastax.dse.driver.api.core.cql.continuous.ContinuousAsyncResultSet; -import com.datastax.dse.driver.api.core.cql.continuous.ContinuousResultSet; -import com.datastax.oss.driver.api.core.cql.Statement; -import com.datastax.oss.driver.api.core.session.Request; -import com.datastax.oss.driver.api.core.type.reflect.GenericType; -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import com.datastax.oss.driver.internal.core.session.DefaultSession; -import com.datastax.oss.driver.internal.core.session.RequestProcessor; -import com.datastax.oss.driver.internal.core.util.concurrent.BlockingOperation; -import com.datastax.oss.driver.internal.core.util.concurrent.CompletableFutures; -import net.jcip.annotations.ThreadSafe; - -@ThreadSafe -public class ContinuousCqlRequestSyncProcessor - implements RequestProcessor, ContinuousResultSet> { - - public static final GenericType CONTINUOUS_RESULT_SYNC = - GenericType.of(ContinuousResultSet.class); - - private final ContinuousCqlRequestAsyncProcessor asyncProcessor; - - public ContinuousCqlRequestSyncProcessor(ContinuousCqlRequestAsyncProcessor asyncProcessor) { - this.asyncProcessor = asyncProcessor; - } - - @Override - public boolean canProcess(Request request, GenericType resultType) { - return request instanceof Statement && resultType.equals(CONTINUOUS_RESULT_SYNC); - } - - @Override - public ContinuousResultSet process( - Statement request, - DefaultSession session, - InternalDriverContext context, - String sessionLogPrefix) { - BlockingOperation.checkNotDriverThread(); - ContinuousAsyncResultSet firstPage = - CompletableFutures.getUninterruptibly( - asyncProcessor.process(request, session, context, sessionLogPrefix)); - return new DefaultContinuousResultSet(firstPage); - } - - @Override - public ContinuousResultSet newFailure(RuntimeException error) { - throw error; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/cql/continuous/ContinuousRequestHandlerBase.java b/core/src/main/java/com/datastax/dse/driver/internal/core/cql/continuous/ContinuousRequestHandlerBase.java deleted file mode 100644 index c17ccd50ff8..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/cql/continuous/ContinuousRequestHandlerBase.java +++ /dev/null @@ -1,1724 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.cql.continuous; - -import static com.datastax.oss.driver.api.core.DriverTimeoutException.UNAVAILABLE; - -import com.datastax.dse.driver.api.core.DseProtocolVersion; -import com.datastax.dse.driver.api.core.cql.continuous.ContinuousAsyncResultSet; -import com.datastax.dse.driver.internal.core.DseProtocolFeature; -import com.datastax.dse.driver.internal.core.cql.DseConversions; -import com.datastax.dse.protocol.internal.request.Revise; -import com.datastax.dse.protocol.internal.response.result.DseRowsMetadata; -import com.datastax.oss.driver.api.core.AllNodesFailedException; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.DriverTimeoutException; -import com.datastax.oss.driver.api.core.DriverTimeoutException.NodeDiagnostics; -import com.datastax.oss.driver.api.core.NodeUnavailableException; -import com.datastax.oss.driver.api.core.ProtocolVersion; -import com.datastax.oss.driver.api.core.RequestThrottlingException; -import com.datastax.oss.driver.api.core.config.DefaultDriverOption; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.connection.FrameTooLongException; -import com.datastax.oss.driver.api.core.cql.ColumnDefinitions; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.datastax.oss.driver.api.core.metrics.DefaultNodeMetric; -import com.datastax.oss.driver.api.core.metrics.DefaultSessionMetric; -import com.datastax.oss.driver.api.core.metrics.NodeMetric; -import com.datastax.oss.driver.api.core.metrics.SessionMetric; -import com.datastax.oss.driver.api.core.retry.RetryPolicy; -import com.datastax.oss.driver.api.core.retry.RetryVerdict; -import com.datastax.oss.driver.api.core.servererrors.BootstrappingException; -import com.datastax.oss.driver.api.core.servererrors.CoordinatorException; -import com.datastax.oss.driver.api.core.servererrors.FunctionFailureException; -import com.datastax.oss.driver.api.core.servererrors.ProtocolError; -import com.datastax.oss.driver.api.core.servererrors.QueryValidationException; -import com.datastax.oss.driver.api.core.servererrors.ReadTimeoutException; -import com.datastax.oss.driver.api.core.servererrors.UnavailableException; -import com.datastax.oss.driver.api.core.servererrors.WriteTimeoutException; -import com.datastax.oss.driver.api.core.session.Request; -import com.datastax.oss.driver.api.core.session.throttling.RequestThrottler; -import com.datastax.oss.driver.api.core.session.throttling.Throttled; -import com.datastax.oss.driver.internal.core.adminrequest.ThrottledAdminRequestHandler; -import com.datastax.oss.driver.internal.core.adminrequest.UnexpectedResponseException; -import com.datastax.oss.driver.internal.core.channel.DriverChannel; -import com.datastax.oss.driver.internal.core.channel.ResponseCallback; -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import com.datastax.oss.driver.internal.core.cql.Conversions; -import com.datastax.oss.driver.internal.core.cql.DefaultExecutionInfo; -import com.datastax.oss.driver.internal.core.metadata.DefaultNode; -import com.datastax.oss.driver.internal.core.metrics.NodeMetricUpdater; -import com.datastax.oss.driver.internal.core.metrics.SessionMetricUpdater; -import com.datastax.oss.driver.internal.core.pool.ChannelPool; -import com.datastax.oss.driver.internal.core.session.DefaultSession; -import com.datastax.oss.driver.internal.core.session.RepreparePayload; -import com.datastax.oss.driver.internal.core.util.Loggers; -import com.datastax.oss.driver.internal.core.util.collection.SimpleQueryPlan; -import com.datastax.oss.driver.shaded.guava.common.annotations.VisibleForTesting; -import com.datastax.oss.protocol.internal.Frame; -import com.datastax.oss.protocol.internal.Message; -import com.datastax.oss.protocol.internal.ProtocolConstants; -import com.datastax.oss.protocol.internal.request.Prepare; -import com.datastax.oss.protocol.internal.response.Error; -import com.datastax.oss.protocol.internal.response.Result; -import com.datastax.oss.protocol.internal.response.error.Unprepared; -import com.datastax.oss.protocol.internal.response.result.Rows; -import com.datastax.oss.protocol.internal.response.result.Void; -import com.datastax.oss.protocol.internal.util.Bytes; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import io.netty.handler.codec.EncoderException; -import io.netty.util.Timeout; -import io.netty.util.Timer; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.GenericFutureListener; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.time.Duration; -import java.util.AbstractMap; -import java.util.ArrayDeque; -import java.util.List; -import java.util.Map; -import java.util.Queue; -import java.util.concurrent.CancellationException; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.locks.ReentrantLock; -import net.jcip.annotations.GuardedBy; -import net.jcip.annotations.ThreadSafe; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Handles a request that supports multiple response messages (a.k.a. continuous paging request). - */ -@ThreadSafe -public abstract class ContinuousRequestHandlerBase - implements Throttled { - - private static final Logger LOG = LoggerFactory.getLogger(ContinuousRequestHandlerBase.class); - - protected final String logPrefix; - protected final StatementT initialStatement; - protected final DefaultSession session; - private final CqlIdentifier keyspace; - protected final InternalDriverContext context; - private final Queue queryPlan; - protected final RequestThrottler throttler; - private final boolean protocolBackpressureAvailable; - private final Timer timer; - private final SessionMetricUpdater sessionMetricUpdater; - private final boolean specExecEnabled; - private final SessionMetric clientTimeoutsMetric; - private final SessionMetric continuousRequestsMetric; - private final NodeMetric messagesMetric; - private final List scheduledExecutions; - - // The errors on the nodes that were already tried. - // We don't use a map because nodes can appear multiple times. - protected final List> errors = new CopyOnWriteArrayList<>(); - - /** - * The list of in-flight executions, one per node. Executions may be triggered by speculative - * executions or retries. An execution is added to this list when the write operation completes. - * It is removed from this list when the callback has done reading responses. - */ - private final List inFlightCallbacks = new CopyOnWriteArrayList<>(); - - /** The callback selected to stream results back to the client. */ - private final CompletableFuture chosenCallback = new CompletableFuture<>(); - - /** - * How many speculative executions are currently running (including the initial execution). We - * track this in order to know when to fail the request if all executions have reached the end of - * the query plan. - */ - private final AtomicInteger activeExecutionsCount = new AtomicInteger(0); - - /** - * How many speculative executions have started (excluding the initial execution), whether they - * have completed or not. We track this in order to fill execution info objects with this - * information. - */ - protected final AtomicInteger startedSpeculativeExecutionsCount = new AtomicInteger(0); - - // Set when the execution starts, and is never modified after. - private final long startTimeNanos; - private volatile Timeout globalTimeout; - - private final Class resultSetClass; - - public ContinuousRequestHandlerBase( - @NonNull StatementT statement, - @NonNull DefaultSession session, - @NonNull InternalDriverContext context, - @NonNull String sessionLogPrefix, - @NonNull Class resultSetClass, - boolean specExecEnabled, - SessionMetric clientTimeoutsMetric, - SessionMetric continuousRequestsMetric, - NodeMetric messagesMetric) { - this.resultSetClass = resultSetClass; - - ProtocolVersion protocolVersion = context.getProtocolVersion(); - if (!context - .getProtocolVersionRegistry() - .supports(protocolVersion, DseProtocolFeature.CONTINUOUS_PAGING)) { - throw new IllegalStateException( - "Cannot execute continuous paging requests with protocol version " + protocolVersion); - } - this.clientTimeoutsMetric = clientTimeoutsMetric; - this.continuousRequestsMetric = continuousRequestsMetric; - this.messagesMetric = messagesMetric; - this.logPrefix = sessionLogPrefix + "|" + this.hashCode(); - LOG.trace("[{}] Creating new continuous handler for request {}", logPrefix, statement); - this.initialStatement = statement; - this.session = session; - this.keyspace = session.getKeyspace().orElse(null); - this.context = context; - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(statement, context); - this.queryPlan = - statement.getNode() != null - ? new SimpleQueryPlan(statement.getNode()) - : context - .getLoadBalancingPolicyWrapper() - .newQueryPlan(statement, executionProfile.getName(), session); - this.timer = context.getNettyOptions().getTimer(); - - this.protocolBackpressureAvailable = - protocolVersion.getCode() >= DseProtocolVersion.DSE_V2.getCode(); - this.throttler = context.getRequestThrottler(); - this.sessionMetricUpdater = session.getMetricUpdater(); - this.startTimeNanos = System.nanoTime(); - this.specExecEnabled = specExecEnabled; - this.scheduledExecutions = this.specExecEnabled ? new CopyOnWriteArrayList<>() : null; - } - - @NonNull - protected abstract Duration getGlobalTimeout(); - - @NonNull - protected abstract Duration getPageTimeout(@NonNull StatementT statement, int pageNumber); - - @NonNull - protected abstract Duration getReviseRequestTimeout(@NonNull StatementT statement); - - protected abstract int getMaxEnqueuedPages(@NonNull StatementT statement); - - protected abstract int getMaxPages(@NonNull StatementT statement); - - @NonNull - protected abstract Message getMessage(@NonNull StatementT statement); - - protected abstract boolean isTracingEnabled(@NonNull StatementT statement); - - @NonNull - protected abstract Map createPayload(@NonNull StatementT statement); - - @NonNull - protected abstract ResultSetT createEmptyResultSet(@NonNull ExecutionInfo executionInfo); - - protected abstract int pageNumber(@NonNull ResultSetT resultSet); - - @NonNull - protected abstract ResultSetT createResultSet( - @NonNull StatementT statement, - @NonNull Rows rows, - @NonNull ExecutionInfo executionInfo, - @NonNull ColumnDefinitions columnDefinitions) - throws IOException; - - // MAIN LIFECYCLE - - @Override - public void onThrottleReady(boolean wasDelayed) { - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(initialStatement, context); - if (wasDelayed - // avoid call to nanoTime() if metric is disabled: - && sessionMetricUpdater.isEnabled( - DefaultSessionMetric.THROTTLING_DELAY, executionProfile.getName())) { - session - .getMetricUpdater() - .updateTimer( - DefaultSessionMetric.THROTTLING_DELAY, - executionProfile.getName(), - System.nanoTime() - startTimeNanos, - TimeUnit.NANOSECONDS); - } - activeExecutionsCount.incrementAndGet(); - sendRequest(initialStatement, null, 0, 0, specExecEnabled); - } - - @Override - public void onThrottleFailure(@NonNull RequestThrottlingException error) { - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(initialStatement, context); - session - .getMetricUpdater() - .incrementCounter(DefaultSessionMetric.THROTTLING_ERRORS, executionProfile.getName()); - abortGlobalRequestOrChosenCallback(error); - } - - private boolean abortGlobalRequestOrChosenCallback(@NonNull Throwable error) { - boolean completedChosenCallback = chosenCallback.completeExceptionally(error); - if (!completedChosenCallback) { - chosenCallback.thenAccept(callback -> callback.abort(error, false)); - } - return completedChosenCallback; - } - - public CompletionStage handle() { - globalTimeout = scheduleGlobalTimeout(); - return fetchNextPage(); - } - - /** - * Builds the future that will get returned to the user from the initial execute call or a - * fetchNextPage() on the async API. - */ - public CompletionStage fetchNextPage() { - CompletableFuture result = new CompletableFuture<>(); - - // This is equivalent to - // `chosenCallback.thenCompose(NodeResponseCallback::dequeueOrCreatePending)`, except - // that we need to cancel `result` if `resultSetError` is a CancellationException. - chosenCallback.whenComplete( - (callback, callbackError) -> { - if (callbackError != null) { - result.completeExceptionally(callbackError); - } else { - callback - .dequeueOrCreatePending() - .whenComplete( - (resultSet, resultSetError) -> { - if (resultSetError != null) { - result.completeExceptionally(resultSetError); - } else { - result.complete(resultSet); - } - }); - } - }); - - // If the user cancels the future, propagate to our internal components - result.whenComplete( - (rs, t) -> { - if (t instanceof CancellationException) { - cancel(); - } - }); - - return result; - } - - /** - * Sends the initial request to the next available node. - * - * @param node if not null, it will be attempted first before the rest of the query plan. It - * happens only when we retry on the same host. - * @param currentExecutionIndex 0 for the initial execution, 1 for the first speculative one, etc. - * @param retryCount the number of times that the retry policy was invoked for this execution - * already (note that some internal retries don't go through the policy, and therefore don't - * increment this counter) - * @param scheduleSpeculativeExecution whether to schedule the next speculative execution - */ - private void sendRequest( - StatementT statement, - @Nullable Node node, - int currentExecutionIndex, - int retryCount, - boolean scheduleSpeculativeExecution) { - DriverChannel channel = null; - if (node == null || (channel = session.getChannel(node, logPrefix)) == null) { - while ((node = queryPlan.poll()) != null) { - channel = session.getChannel(node, logPrefix); - if (channel != null) { - break; - } else { - recordError(node, new NodeUnavailableException(node)); - } - } - } - if (channel == null) { - // We've reached the end of the query plan without finding any node to write to; abort the - // continuous paging session. - if (activeExecutionsCount.decrementAndGet() == 0) { - abortGlobalRequestOrChosenCallback(AllNodesFailedException.fromErrors(errors)); - } - } else if (!chosenCallback.isDone()) { - boolean writeSubmitted = false; - Throwable terminalPreWriteFailure = null; - NodeResponseCallback nodeResponseCallback = null; - try { - nodeResponseCallback = - new NodeResponseCallback( - statement, - node, - channel, - currentExecutionIndex, - retryCount, - scheduleSpeculativeExecution, - logPrefix); - inFlightCallbacks.add(nodeResponseCallback); - Future writeFuture = - channel.write( - getMessage(statement), - isTracingEnabled(statement), - createPayload(statement), - nodeResponseCallback); - writeSubmitted = true; - writeFuture.addListener(nodeResponseCallback); - } catch (Throwable t) { - if (!writeSubmitted && activeExecutionsCount.decrementAndGet() == 0) { - if (abortGlobalRequestOrChosenCallback(t)) { - terminalPreWriteFailure = t; - } - } - throw t; - } finally { - if (!writeSubmitted) { - if (nodeResponseCallback != null) { - inFlightCallbacks.remove(nodeResponseCallback); - } - try { - channel.cancelPreAcquireId(); - } finally { - if (terminalPreWriteFailure != null) { - throttler.signalError(this, terminalPreWriteFailure); - } - } - } - } - } else { - channel.cancelPreAcquireId(); - } - } - - private Timeout scheduleGlobalTimeout() { - Duration globalTimeout = getGlobalTimeout(); - if (globalTimeout.toNanos() <= 0) { - return null; - } - LOG.trace("[{}] Scheduling global timeout for pages in {}", logPrefix, globalTimeout); - return timer.newTimeout( - timeout -> { - NodeDiagnostics diagnostics = buildNodeDiagnostics(); - abortGlobalRequestOrChosenCallback( - new DriverTimeoutException("Query timed out after " + globalTimeout, diagnostics)); - }, - globalTimeout.toNanos(), - TimeUnit.NANOSECONDS); - } - - @Nullable - private NodeDiagnostics buildNodeDiagnostics() { - List callbacks = inFlightCallbacks; - if (callbacks.isEmpty()) { - return null; - } - NodeResponseCallback cb = callbacks.get(0); - int channelInFlight = cb.channel.getInFlight(); - ChannelPool pool = session.getPools().get(cb.node); - return NodeDiagnostics.of( - cb.node.getEndPoint(), - cb.node.getState(), - cb.node.getDistance(), - cb.node.getDatacenter(), - channelInFlight, - pool != null ? pool.size() : UNAVAILABLE, - pool != null ? pool.getInFlight() : UNAVAILABLE, - pool != null ? pool.getAvailableIds() : UNAVAILABLE, - pool != null ? pool.getOrphanedIds() : UNAVAILABLE); - } - - /** - * Cancels the continuous paging request. - * - *

Called from user code, see {@link DefaultContinuousAsyncResultSet#cancel()}, or from a - * driver I/O thread. - */ - public void cancel() { - // If chosenCallback is already set, this is a no-op and the chosen callback will be handled by - // cancelScheduledTasks - chosenCallback.cancel(true); - - cancelScheduledTasks(null); - cancelGlobalTimeout(); - throttler.signalCancel(this); - } - - private void cancelGlobalTimeout() { - if (globalTimeout != null) { - globalTimeout.cancel(); - } - } - - /** - * Cancel all pending and scheduled executions, except the one passed as an argument to the - * method. - * - * @param toIgnore An optional execution to ignore (will not be cancelled). - */ - private void cancelScheduledTasks(@Nullable NodeResponseCallback toIgnore) { - if (scheduledExecutions != null) { - for (Timeout scheduledExecution : scheduledExecutions) { - scheduledExecution.cancel(); - } - } - for (NodeResponseCallback callback : inFlightCallbacks) { - if (toIgnore == null || toIgnore != callback) { - callback.cancel(); - } - } - } - - @VisibleForTesting - int getState() { - try { - return chosenCallback.get().getState(); - } catch (CancellationException e) { - // Happens if the test cancels before the callback was chosen - return NodeResponseCallback.STATE_FAILED; - } catch (InterruptedException | ExecutionException e) { - // We never interrupt or fail chosenCallback (other than canceling) - throw new AssertionError("Unexpected error", e); - } - } - - @VisibleForTesting - CompletableFuture getPendingResult() { - try { - return chosenCallback.get().getPendingResult(); - } catch (Exception e) { - // chosenCallback should always be complete by the time tests call this - throw new AssertionError("Expected callback to be chosen at this point"); - } - } - - @VisibleForTesting - int getActiveExecutionsCount() { - return activeExecutionsCount.get(); - } - - @VisibleForTesting - int getInFlightCallbackCount() { - return inFlightCallbacks.size(); - } - - private void recordError(@NonNull Node node, @NonNull Throwable error) { - errors.add(new AbstractMap.SimpleEntry<>(node, error)); - } - - /** - * Handles the interaction with a single node in the query plan. - * - *

An instance of this class is created each time we (re)try a node. The first callback that - * has something ready to enqueue will be allowed to stream results back to the client; the others - * will be cancelled. - */ - private class NodeResponseCallback - implements ResponseCallback, GenericFutureListener> { - - private final long messageStartTimeNanos = System.nanoTime(); - private final StatementT statement; - private final Node node; - private final DriverChannel channel; - // The identifier of the current execution (0 for the initial execution, 1 for the first - // speculative execution, etc.) - private final int executionIndex; - // How many times we've invoked the retry policy and it has returned a "retry" decision (0 for - // the first attempt of each execution). - private final String logPrefix; - private final boolean scheduleSpeculativeExecution; - - private final DriverExecutionProfile executionProfile; - - // Coordinates concurrent accesses between the client and I/O threads - private final ReentrantLock lock = new ReentrantLock(); - - // The page queue, storing responses that we have received and have not been consumed by the - // client yet. We instantiate it lazily to avoid unnecessary allocation; this is also used to - // check if the callback ever tried to enqueue something. - @GuardedBy("lock") - private Queue queue; - - // If the client requests a page and we can't serve it immediately (empty queue), then we create - // this future and have the client wait on it. Otherwise this field is null. - @GuardedBy("lock") - private CompletableFuture pendingResult; - - // How many pages were requested. This is the total number of pages requested from the - // beginning. - // It will be zero if the protocol does not support numPagesRequested (DSE_V1) - @GuardedBy("lock") - private int numPagesRequested; - - // An integer that represents the state of the continuous paging request: - // - if positive, it is the sequence number of the next expected page; - // - if negative, it is a terminal state, identified by the constants below. - @GuardedBy("lock") - private int state = 1; - - // Whether isLastResponse has returned true already - @GuardedBy("lock") - private boolean sawLastResponse; - - @GuardedBy("lock") - private boolean sentCancelRequest; - - private static final int STATE_FINISHED = -1; - private static final int STATE_FAILED = -2; - - @GuardedBy("lock") - private int streamId = -1; - - // These are set when the first page arrives, and are never modified after. - private volatile ColumnDefinitions columnDefinitions; - - private volatile Timeout pageTimeout; - - // How many times we've invoked the retry policy and it has returned a "retry" decision (0 for - // the first attempt, 1 for the first retry, etc.). - private final int retryCount; - - // SpeculativeExecution node metrics should be executed only for the first page (first - // invocation) - private final AtomicBoolean stopNodeMessageTimerReported = new AtomicBoolean(false); - private final AtomicBoolean nodeErrorReported = new AtomicBoolean(false); - private final AtomicBoolean nodeSuccessReported = new AtomicBoolean(false); - - public NodeResponseCallback( - StatementT statement, - Node node, - DriverChannel channel, - int executionIndex, - int retryCount, - boolean scheduleSpeculativeExecution, - String logPrefix) { - this.statement = statement; - this.node = node; - this.channel = channel; - this.executionIndex = executionIndex; - this.retryCount = retryCount; - this.scheduleSpeculativeExecution = scheduleSpeculativeExecution; - this.logPrefix = logPrefix + "|" + executionIndex; - this.executionProfile = Conversions.resolveExecutionProfile(statement, context); - } - - @Override - public void onStreamIdAssigned(int streamId) { - LOG.trace("[{}] Assigned streamId {} on node {}", logPrefix, streamId, node); - lock.lock(); - try { - this.streamId = streamId; - if (state < 0) { - // This happens if we were cancelled before getting the stream id, we have a request in - // flight that needs to be cancelled - releaseStreamId(); - } - } finally { - lock.unlock(); - } - } - - @Override - public boolean isLastResponse(@NonNull Frame responseFrame) { - lock.lock(); - try { - Message message = responseFrame.message; - boolean isLastResponse; - - if (sentCancelRequest) { - // The only response we accept is the SERVER_ERROR triggered by a successful cancellation. - // Otherwise we risk releasing and reusing the stream id while the cancel request is still - // in flight, and it might end up cancelling an unrelated request. - // Note that there is a chance that the request ends normally right after we send the - // cancel request. In that case this method never returns true and the stream id will - // remain orphaned forever. This should be very rare so this is acceptable. - if (message instanceof Error) { - Error error = (Error) message; - isLastResponse = - (error.code == ProtocolConstants.ErrorCode.SERVER_ERROR) - && error.message.contains("Session cancelled by the user"); - } else { - isLastResponse = false; - } - } else if (message instanceof Rows) { - Rows rows = (Rows) message; - DseRowsMetadata metadata = (DseRowsMetadata) rows.getMetadata(); - isLastResponse = metadata.isLastContinuousPage; - } else { - isLastResponse = message instanceof Error; - } - - if (isLastResponse) { - sawLastResponse = true; - } - return isLastResponse; - } finally { - lock.unlock(); - } - } - - /** - * Invoked when the write from {@link #sendRequest} completes. - * - * @param future The future representing the outcome of the write operation. - */ - @Override - public void operationComplete(@NonNull Future future) { - if (!future.isSuccess()) { - Throwable error = future.cause(); - if (error instanceof EncoderException - && error.getCause() instanceof FrameTooLongException) { - trackNodeError(node, error.getCause()); - lock.lock(); - try { - abort(error.getCause(), false); - } finally { - lock.unlock(); - } - } else { - LOG.trace( - "[{}] Failed to send request on {}, trying next node (cause: {})", - logPrefix, - channel, - error); - ((DefaultNode) node) - .getMetricUpdater() - .incrementCounter(DefaultNodeMetric.UNSENT_REQUESTS, executionProfile.getName()); - recordError(node, error); - trackNodeError(node, error.getCause()); - sendRequest(statement, null, executionIndex, retryCount, scheduleSpeculativeExecution); - } - } else { - LOG.trace("[{}] Request sent on {}", logPrefix, channel); - if (scheduleSpeculativeExecution - && Conversions.resolveIdempotence(statement, executionProfile)) { - int nextExecution = executionIndex + 1; - // Note that `node` is the first node of the execution, it might not be the "slow" one - // if there were retries, but in practice retries are rare. - long nextDelay = - Conversions.resolveSpeculativeExecutionPolicy(context, executionProfile) - .nextExecution(node, keyspace, statement, nextExecution); - if (nextDelay >= 0) { - scheduleSpeculativeExecution(nextExecution, nextDelay); - } else { - LOG.trace( - "[{}] Speculative execution policy returned {}, no next execution", - logPrefix, - nextDelay); - } - } - pageTimeout = schedulePageTimeout(1); - } - } - - private void scheduleSpeculativeExecution(int nextExecutionIndex, long delay) { - LOG.trace( - "[{}] Scheduling speculative execution {} in {} ms", - logPrefix, - nextExecutionIndex, - delay); - try { - scheduledExecutions.add( - timer.newTimeout( - (Timeout timeout) -> { - if (!chosenCallback.isDone()) { - LOG.trace( - "[{}] Starting speculative execution {}", logPrefix, nextExecutionIndex); - activeExecutionsCount.incrementAndGet(); - startedSpeculativeExecutionsCount.incrementAndGet(); - NodeMetricUpdater nodeMetricUpdater = ((DefaultNode) node).getMetricUpdater(); - if (nodeMetricUpdater.isEnabled( - DefaultNodeMetric.SPECULATIVE_EXECUTIONS, executionProfile.getName())) { - nodeMetricUpdater.incrementCounter( - DefaultNodeMetric.SPECULATIVE_EXECUTIONS, executionProfile.getName()); - } - sendRequest(statement, null, nextExecutionIndex, 0, true); - } - }, - delay, - TimeUnit.MILLISECONDS)); - } catch (IllegalStateException e) { - logTimeoutSchedulingError(e); - } - } - - private Timeout schedulePageTimeout(int expectedPage) { - if (expectedPage < 0) { - return null; - } - Duration timeout = getPageTimeout(statement, expectedPage); - if (timeout.toNanos() <= 0) { - return null; - } - LOG.trace("[{}] Scheduling timeout for page {} in {}", logPrefix, expectedPage, timeout); - return timer.newTimeout( - t -> onPageTimeout(expectedPage), timeout.toNanos(), TimeUnit.NANOSECONDS); - } - - private void onPageTimeout(int expectedPage) { - lock.lock(); - try { - if (state == expectedPage) { - int channelInFlight = channel.getInFlight(); - ChannelPool pool = session.getPools().get(node); - abort( - new DriverTimeoutException( - "Timed out waiting for page " + expectedPage, - NodeDiagnostics.of( - node.getEndPoint(), - node.getState(), - node.getDistance(), - node.getDatacenter(), - channelInFlight, - pool != null ? pool.size() : UNAVAILABLE, - pool != null ? pool.getInFlight() : UNAVAILABLE, - pool != null ? pool.getAvailableIds() : UNAVAILABLE, - pool != null ? pool.getOrphanedIds() : UNAVAILABLE)), - false); - } else { - // Ignore timeout if the request has moved on in the interim. - LOG.trace( - "[{}] Timeout fired for page {} but query already at state {}, skipping", - logPrefix, - expectedPage, - state); - } - } finally { - lock.unlock(); - } - } - - /** - * Invoked when a continuous paging response is received, either a successful or failed one. - * - *

Delegates further processing to appropriate methods: {@link #processResultResponse(Result, - * Frame)} if the response was successful, or {@link #processErrorResponse(Error)} if it wasn't. - * - * @param response the received {@link Frame}. - */ - @Override - public void onResponse(@NonNull Frame response) { - stopNodeMessageTimer(); - cancelTimeout(pageTimeout); - lock.lock(); - try { - if (state < 0) { - LOG.trace("[{}] Got result but the request has been cancelled, ignoring", logPrefix); - return; - } - try { - Message responseMessage = response.message; - if (responseMessage instanceof Result) { - LOG.trace("[{}] Got result", logPrefix); - processResultResponse((Result) responseMessage, response); - } else if (responseMessage instanceof Error) { - LOG.trace("[{}] Got error response", logPrefix); - processErrorResponse((Error) responseMessage); - } else { - IllegalStateException error = - new IllegalStateException("Unexpected response " + responseMessage); - trackNodeError(node, error); - abort(error, false); - } - } catch (Throwable t) { - trackNodeError(node, t); - abort(t, false); - } - } finally { - lock.unlock(); - } - } - - /** - * Invoked when a continuous paging request hits an unexpected error. - * - *

Delegates further processing to to the retry policy ({@link - * #processRetryVerdict(RetryVerdict, Throwable)}. - * - * @param error the error encountered, usually a network problem. - */ - @Override - public void onFailure(@NonNull Throwable error) { - cancelTimeout(pageTimeout); - LOG.trace(String.format("[%s] Request failure", logPrefix), error); - RetryVerdict verdict; - if (!Conversions.resolveIdempotence(statement, executionProfile) - || error instanceof FrameTooLongException) { - verdict = RetryVerdict.RETHROW; - } else { - try { - RetryPolicy retryPolicy = Conversions.resolveRetryPolicy(context, executionProfile); - verdict = retryPolicy.onRequestAbortedVerdict(statement, error, retryCount); - } catch (Throwable cause) { - abort( - new IllegalStateException("Unexpected error while invoking the retry policy", cause), - false); - return; - } - } - updateErrorMetrics( - ((DefaultNode) node).getMetricUpdater(), - verdict, - DefaultNodeMetric.ABORTED_REQUESTS, - DefaultNodeMetric.RETRIES_ON_ABORTED, - DefaultNodeMetric.IGNORES_ON_ABORTED); - lock.lock(); - try { - processRetryVerdict(verdict, error); - } finally { - lock.unlock(); - } - } - - // PROCESSING METHODS - - /** - * Processes a new result response, creating the corresponding {@link ResultSetT} object and - * then enqueuing it or serving it directly to the user if he was waiting for it. - * - * @param result the result to process. It is normally a {@link Rows} object, but may be a - * {@link Void} object if the retry policy decided to ignore an error. - * @param frame the {@link Frame} (used to create the {@link ExecutionInfo} the first time). - */ - @SuppressWarnings("GuardedBy") // this method is only called with the lock held - private void processResultResponse(@NonNull Result result, @Nullable Frame frame) { - assert lock.isHeldByCurrentThread(); - try { - ExecutionInfo executionInfo = createExecutionInfo(result, frame); - if (result instanceof Rows) { - DseRowsMetadata rowsMetadata = (DseRowsMetadata) ((Rows) result).getMetadata(); - if (columnDefinitions == null) { - // Contrary to ROWS responses from regular queries, - // the first page always includes metadata so we use this - // regardless of whether or not the query was from a prepared statement. - columnDefinitions = Conversions.toColumnDefinitions(rowsMetadata, context); - } - int pageNumber = rowsMetadata.continuousPageNumber; - int currentPage = state; - if (pageNumber != currentPage) { - abort( - new IllegalStateException( - String.format( - "Received page %d but was expecting %d", pageNumber, currentPage)), - false); - } else { - int pageSize = ((Rows) result).getData().size(); - ResultSetT resultSet = - createResultSet(statement, (Rows) result, executionInfo, columnDefinitions); - if (rowsMetadata.isLastContinuousPage) { - LOG.trace("[{}] Received last page ({} - {} rows)", logPrefix, pageNumber, pageSize); - state = STATE_FINISHED; - reenableAutoReadIfNeeded(); - enqueueOrCompletePending(resultSet); - stopGlobalRequestTimer(); - cancelTimeout(globalTimeout); - } else { - LOG.trace("[{}] Received page {} ({} rows)", logPrefix, pageNumber, pageSize); - if (currentPage > 0) { - state = currentPage + 1; - } - enqueueOrCompletePending(resultSet); - } - } - } else { - // Void responses happen only when the retry decision is ignore. - assert result instanceof Void; - ResultSetT resultSet = createEmptyResultSet(executionInfo); - LOG.trace( - "[{}] Continuous paging interrupted by retry policy decision to ignore error", - logPrefix); - state = STATE_FINISHED; - reenableAutoReadIfNeeded(); - enqueueOrCompletePending(resultSet); - stopGlobalRequestTimer(); - cancelTimeout(globalTimeout); - } - } catch (Throwable error) { - abort(error, false); - } - } - - /** - * Processes an unsuccessful response. - * - *

Depending on the error, may trigger: - * - *

    - *
  1. a re-prepare cycle, see {@link #processUnprepared(Unprepared)}; - *
  2. an immediate retry on the next host, bypassing the retry policy, if the host was - * bootstrapping; - *
  3. an immediate abortion if the error is unrecoverable; - *
  4. further processing if the error is recoverable, see {@link - * #processRecoverableError(CoordinatorException)} - *
- * - * @param errorMessage the error message received. - */ - @SuppressWarnings("GuardedBy") // this method is only called with the lock held - private void processErrorResponse(@NonNull Error errorMessage) { - assert lock.isHeldByCurrentThread(); - if (errorMessage instanceof Unprepared) { - processUnprepared((Unprepared) errorMessage); - } else { - CoordinatorException error = DseConversions.toThrowable(node, errorMessage, context); - if (error instanceof BootstrappingException) { - LOG.trace("[{}] {} is bootstrapping, trying next node", logPrefix, node); - recordError(node, error); - trackNodeError(node, error); - sendRequest(statement, null, executionIndex, retryCount, false); - } else if (error instanceof QueryValidationException - || error instanceof FunctionFailureException - || error instanceof ProtocolError - || state > 1) { - // we only process recoverable errors for the first page, - // errors on subsequent pages will always trigger an immediate abortion - LOG.trace("[{}] Unrecoverable error, rethrowing", logPrefix); - NodeMetricUpdater metricUpdater = ((DefaultNode) node).getMetricUpdater(); - metricUpdater.incrementCounter( - DefaultNodeMetric.OTHER_ERRORS, executionProfile.getName()); - trackNodeError(node, error); - abort(error, true); - } else { - try { - processRecoverableError(error); - } catch (Throwable cause) { - abort(cause, false); - } - } - } - } - - /** - * Processes a recoverable error. - * - *

In most cases, delegates to the retry policy and its decision, see {@link - * #processRetryVerdict(RetryVerdict, Throwable)}. - * - * @param error the recoverable error. - */ - private void processRecoverableError(@NonNull CoordinatorException error) { - assert lock.isHeldByCurrentThread(); - NodeMetricUpdater metricUpdater = ((DefaultNode) node).getMetricUpdater(); - RetryVerdict verdict; - RetryPolicy retryPolicy = Conversions.resolveRetryPolicy(context, executionProfile); - if (error instanceof ReadTimeoutException) { - ReadTimeoutException readTimeout = (ReadTimeoutException) error; - verdict = - retryPolicy.onReadTimeoutVerdict( - statement, - readTimeout.getConsistencyLevel(), - readTimeout.getBlockFor(), - readTimeout.getReceived(), - readTimeout.wasDataPresent(), - retryCount); - updateErrorMetrics( - metricUpdater, - verdict, - DefaultNodeMetric.READ_TIMEOUTS, - DefaultNodeMetric.RETRIES_ON_READ_TIMEOUT, - DefaultNodeMetric.IGNORES_ON_READ_TIMEOUT); - } else if (error instanceof WriteTimeoutException) { - WriteTimeoutException writeTimeout = (WriteTimeoutException) error; - if (Conversions.resolveIdempotence(statement, executionProfile)) { - verdict = - retryPolicy.onWriteTimeoutVerdict( - statement, - writeTimeout.getConsistencyLevel(), - writeTimeout.getWriteType(), - writeTimeout.getBlockFor(), - writeTimeout.getReceived(), - retryCount); - } else { - verdict = RetryVerdict.RETHROW; - } - updateErrorMetrics( - metricUpdater, - verdict, - DefaultNodeMetric.WRITE_TIMEOUTS, - DefaultNodeMetric.RETRIES_ON_WRITE_TIMEOUT, - DefaultNodeMetric.IGNORES_ON_WRITE_TIMEOUT); - } else if (error instanceof UnavailableException) { - UnavailableException unavailable = (UnavailableException) error; - verdict = - retryPolicy.onUnavailableVerdict( - statement, - unavailable.getConsistencyLevel(), - unavailable.getRequired(), - unavailable.getAlive(), - retryCount); - updateErrorMetrics( - metricUpdater, - verdict, - DefaultNodeMetric.UNAVAILABLES, - DefaultNodeMetric.RETRIES_ON_UNAVAILABLE, - DefaultNodeMetric.IGNORES_ON_UNAVAILABLE); - } else { - verdict = - Conversions.resolveIdempotence(statement, executionProfile) - ? retryPolicy.onErrorResponseVerdict(statement, error, retryCount) - : RetryVerdict.RETHROW; - updateErrorMetrics( - metricUpdater, - verdict, - DefaultNodeMetric.OTHER_ERRORS, - DefaultNodeMetric.RETRIES_ON_OTHER_ERROR, - DefaultNodeMetric.IGNORES_ON_OTHER_ERROR); - } - processRetryVerdict(verdict, error); - } - - /** - * Processes an {@link Unprepared} error by re-preparing then retrying on the same host. - * - * @param errorMessage the unprepared error message. - */ - @SuppressWarnings("GuardedBy") // this method is only called with the lock held - private void processUnprepared(@NonNull Unprepared errorMessage) { - assert lock.isHeldByCurrentThread(); - ByteBuffer idToReprepare = ByteBuffer.wrap(errorMessage.id); - LOG.trace( - "[{}] Statement {} is not prepared on {}, re-preparing", - logPrefix, - Bytes.toHexString(idToReprepare), - node); - RepreparePayload repreparePayload = session.getRepreparePayloads().get(idToReprepare); - if (repreparePayload == null) { - throw new IllegalStateException( - String.format( - "Tried to execute unprepared query %s but we don't have the data to re-prepare it", - Bytes.toHexString(idToReprepare))); - } - Prepare prepare = repreparePayload.toMessage(); - Duration timeout = executionProfile.getDuration(DefaultDriverOption.REQUEST_TIMEOUT); - ThrottledAdminRequestHandler.prepare( - channel, - true, - prepare, - repreparePayload.customPayload, - timeout, - throttler, - sessionMetricUpdater, - logPrefix) - .start() - .whenComplete( - (repreparedId, exception) -> { - // If we run into an unrecoverable error, surface it to the client instead of - // retrying - Throwable fatalError = null; - if (exception == null) { - if (!repreparedId.equals(idToReprepare)) { - IllegalStateException illegalStateException = - new IllegalStateException( - String.format( - "ID mismatch while trying to reprepare (expected %s, got %s). " - + "This prepared statement won't work anymore. " - + "This usually happens when you run a 'USE...' query after " - + "the statement was prepared.", - Bytes.toHexString(idToReprepare), Bytes.toHexString(repreparedId))); - trackNodeError(node, illegalStateException); - fatalError = illegalStateException; - } else { - LOG.trace( - "[{}] Re-prepare successful, retrying on the same node ({})", - logPrefix, - node); - sendRequest(statement, node, executionIndex, retryCount, false); - } - } else { - if (exception instanceof UnexpectedResponseException) { - Message prepareErrorMessage = ((UnexpectedResponseException) exception).message; - if (prepareErrorMessage instanceof Error) { - CoordinatorException prepareError = - DseConversions.toThrowable(node, (Error) prepareErrorMessage, context); - if (prepareError instanceof QueryValidationException - || prepareError instanceof FunctionFailureException - || prepareError instanceof ProtocolError) { - LOG.trace("[{}] Unrecoverable error on re-prepare, rethrowing", logPrefix); - trackNodeError(node, prepareError); - fatalError = prepareError; - } - } - } else if (exception instanceof RequestThrottlingException) { - trackNodeError(node, exception); - fatalError = exception; - } - if (fatalError == null) { - LOG.trace("[{}] Re-prepare failed, trying next node", logPrefix); - recordError(node, exception); - trackNodeError(node, exception); - sendRequest(statement, null, executionIndex, retryCount, false); - } - } - if (fatalError != null) { - lock.lock(); - try { - abort(fatalError, true); - } finally { - lock.unlock(); - } - } - }); - } - - /** - * Processes the retry decision by triggering a retry, aborting or ignoring; also records the - * failures for further access. - * - * @param verdict the verdict to process. - * @param error the original error. - */ - private void processRetryVerdict(@NonNull RetryVerdict verdict, @NonNull Throwable error) { - assert lock.isHeldByCurrentThread(); - LOG.trace("[{}] Processing retry decision {}", logPrefix, verdict); - switch (verdict.getRetryDecision()) { - case RETRY_SAME: - recordError(node, error); - trackNodeError(node, error); - sendRequest( - verdict.getRetryRequest(statement), node, executionIndex, retryCount + 1, false); - break; - case RETRY_NEXT: - recordError(node, error); - trackNodeError(node, error); - sendRequest( - verdict.getRetryRequest(statement), null, executionIndex, retryCount + 1, false); - break; - case RETHROW: - trackNodeError(node, error); - abort(error, true); - break; - case IGNORE: - processResultResponse(Void.INSTANCE, null); - break; - } - } - - // PAGE HANDLING - - /** - * Enqueues a response or, if the client was already waiting for it, completes the pending - * future. - * - *

Guarded by {@link #lock}. - * - * @param pageOrError the next page, or an error. - */ - @SuppressWarnings("GuardedBy") // this method is only called with the lock held - private void enqueueOrCompletePending(@NonNull Object pageOrError) { - assert lock.isHeldByCurrentThread(); - - if (queue == null) { - // This is the first time this callback tries to stream something back to the client, check - // if it can be selected - if (!chosenCallback.complete(this)) { - if (LOG.isTraceEnabled()) { - LOG.trace( - "[{}] Trying to enqueue {} but another callback was already chosen, aborting", - logPrefix, - asTraceString(pageOrError)); - } - // Discard the data, this callback will be canceled shortly since the chosen callback - // invoked cancelScheduledTasks - return; - } - - queue = new ArrayDeque<>(getMaxEnqueuedPages(statement)); - numPagesRequested = protocolBackpressureAvailable ? getMaxEnqueuedPages(statement) : 0; - cancelScheduledTasks(this); - } - - if (pendingResult != null) { - if (LOG.isTraceEnabled()) { - LOG.trace( - "[{}] Client was waiting on empty queue, completing with {}", - logPrefix, - asTraceString(pageOrError)); - } - CompletableFuture tmp = pendingResult; - // null out pendingResult before completing it because its completion - // may trigger a call to fetchNextPage -> dequeueOrCreatePending, - // which expects pendingResult to be null. - pendingResult = null; - completeResultSetFuture(tmp, pageOrError); - } else { - if (LOG.isTraceEnabled()) { - LOG.trace("[{}] Enqueuing {}", logPrefix, asTraceString(pageOrError)); - } - queue.add(pageOrError); - // Backpressure without protocol support: if the queue grows too large, - // disable auto-read so that the channel eventually becomes - // non-writable on the server side (causing it to back off for a while) - if (!protocolBackpressureAvailable - && queue.size() == getMaxEnqueuedPages(statement) - && state > 0) { - LOG.trace( - "[{}] Exceeded {} queued response pages, disabling auto-read", - logPrefix, - queue.size()); - channel.config().setAutoRead(false); - } - } - } - - /** - * Dequeue a response or, if the queue is empty, create the future that will get notified of the - * next response, when it arrives. - * - *

Called from user code, see {@link ContinuousAsyncResultSet#fetchNextPage()}. - * - * @return the next page's future; never null. - */ - @NonNull - public CompletableFuture dequeueOrCreatePending() { - lock.lock(); - try { - // If the client was already waiting for a page, there's no way it can call this method - // again - // (this is guaranteed by our public API because in order to ask for the next page, - // you need the reference to the previous page). - assert pendingResult == null; - - Object head = null; - if (queue != null) { - head = queue.poll(); - if (!protocolBackpressureAvailable - && head != null - && queue.size() == getMaxEnqueuedPages(statement) - 1) { - LOG.trace( - "[{}] Back to {} queued response pages, re-enabling auto-read", - logPrefix, - queue.size()); - channel.config().setAutoRead(true); - } - maybeRequestMore(); - } - - if (head != null) { - if (state == STATE_FAILED && !(head instanceof Throwable)) { - LOG.trace( - "[{}] Client requested next page on cancelled queue, discarding page and returning cancelled future", - logPrefix); - return cancelledResultSetFuture(); - } else { - if (LOG.isTraceEnabled()) { - LOG.trace( - "[{}] Client requested next page on non-empty queue, returning immediate future of {}", - logPrefix, - asTraceString(head)); - } - return immediateResultSetFuture(head); - } - } else { - if (state == STATE_FAILED) { - LOG.trace( - "[{}] Client requested next page on cancelled empty queue, returning cancelled future", - logPrefix); - return cancelledResultSetFuture(); - } else { - LOG.trace( - "[{}] Client requested next page but queue is empty, installing future", logPrefix); - pendingResult = new CompletableFuture<>(); - // Only schedule a timeout if we're past the first page (the first page's timeout is - // handled in sendRequest). - if (state > 1) { - pageTimeout = schedulePageTimeout(state); - // Note: each new timeout is cancelled when the next response arrives, see - // onResponse(Frame). - } - return pendingResult; - } - } - } finally { - lock.unlock(); - } - } - - /** - * If the total number of results in the queue and in-flight (requested - received) is less than - * half the queue size, then request more pages, unless the {@link #state} is failed, we're - * still waiting for the first page (so maybe still throttled or in the middle of a retry), or - * we don't support backpressure at the protocol level. - */ - @SuppressWarnings("GuardedBy") - private void maybeRequestMore() { - assert lock.isHeldByCurrentThread(); - if (state < 2 || streamId == -1 || !protocolBackpressureAvailable) { - return; - } - // if we have already requested more than the client needs, then no need to request some more - int maxPages = getMaxPages(statement); - if (maxPages > 0 && numPagesRequested >= maxPages) { - return; - } - // the pages received so far, which is the state minus one - int received = state - 1; - int requested = numPagesRequested; - // the pages that fit in the queue, which is the queue free space minus the requests in flight - int freeSpace = getMaxEnqueuedPages(statement) - queue.size(); - int inFlight = requested - received; - int numPagesFittingInQueue = freeSpace - inFlight; - if (numPagesFittingInQueue > 0 - && numPagesFittingInQueue >= getMaxEnqueuedPages(statement) / 2) { - LOG.trace("[{}] Requesting more {} pages", logPrefix, numPagesFittingInQueue); - numPagesRequested = requested + numPagesFittingInQueue; - sendMorePagesRequest(numPagesFittingInQueue); - } - } - - /** - * Sends a request for more pages (a.k.a. backpressure request). - * - * @param nextPages the number of extra pages to request. - */ - @SuppressWarnings("GuardedBy") - private void sendMorePagesRequest(int nextPages) { - assert lock.isHeldByCurrentThread(); - assert channel != null : "expected valid connection in order to request more pages"; - assert protocolBackpressureAvailable; - assert streamId != -1; - - LOG.trace("[{}] Sending request for more pages", logPrefix); - ThrottledAdminRequestHandler.query( - channel, - true, - Revise.requestMoreContinuousPages(streamId, nextPages), - statement.getCustomPayload(), - getReviseRequestTimeout(statement), - throttler, - session.getMetricUpdater(), - logPrefix, - "request " + nextPages + " more pages for id " + streamId) - .start() - .handle( - (result, error) -> { - if (error != null) { - Loggers.warnWithException( - LOG, "[{}] Error requesting more pages, aborting.", logPrefix, error); - lock.lock(); - try { - // Set fromServer to false because we want the callback to still cancel the - // session if possible or else the server will wait on a timeout. - abort(error, false); - } finally { - lock.unlock(); - } - } - return null; - }); - } - - /** Cancels the given timeout, if non null. */ - private void cancelTimeout(Timeout timeout) { - if (timeout != null) { - LOG.trace("[{}] Cancelling timeout", logPrefix); - timeout.cancel(); - } - } - - // CANCELLATION - - public void cancel() { - lock.lock(); - try { - if (state < 0) { - return; - } else { - LOG.trace( - "[{}] Cancelling continuous paging session with state {} on node {}", - logPrefix, - state, - node); - state = STATE_FAILED; - if (pendingResult != null) { - pendingResult.cancel(true); - } - releaseStreamId(); - } - } finally { - lock.unlock(); - } - reenableAutoReadIfNeeded(); - } - - @SuppressWarnings("GuardedBy") - private void releaseStreamId() { - assert lock.isHeldByCurrentThread(); - // If we saw the last response already, InFlightHandler will release the id so no need to - // cancel explicitly - if (streamId >= 0 && !sawLastResponse && !channel.closeFuture().isDone()) { - // This orphans the stream id, but it will still be held until we see the last response: - channel.cancel(this); - // This tells the server to stop streaming, and send a terminal response: - sendCancelRequest(); - } - } - - @SuppressWarnings("GuardedBy") - private void sendCancelRequest() { - assert lock.isHeldByCurrentThread(); - LOG.trace("[{}] Sending cancel request", logPrefix); - ThrottledAdminRequestHandler.query( - channel, - true, - Revise.cancelContinuousPaging(streamId), - statement.getCustomPayload(), - getReviseRequestTimeout(statement), - throttler, - session.getMetricUpdater(), - logPrefix, - "cancel request") - .start() - .handle( - (result, error) -> { - if (error != null) { - Loggers.warnWithException( - LOG, - "[{}] Error sending cancel request. " - + "This is not critical (the request will eventually time out server-side).", - logPrefix, - error); - } else { - LOG.trace("[{}] Continuous paging session cancelled successfully", logPrefix); - } - return null; - }); - sentCancelRequest = true; - } - - // TERMINATION - - private void reenableAutoReadIfNeeded() { - // Make sure we don't leave the channel unreadable - LOG.trace("[{}] Re-enabling auto-read", logPrefix); - if (!protocolBackpressureAvailable) { - channel.config().setAutoRead(true); - } - } - - // ERROR HANDLING - - private void trackNodeError(@NonNull Node node, @NonNull Throwable error) { - if (nodeErrorReported.compareAndSet(false, true)) { - long latencyNanos = System.nanoTime() - this.messageStartTimeNanos; - context - .getRequestTracker() - .onNodeError(this.statement, error, latencyNanos, executionProfile, node, logPrefix); - } - } - - /** - * Aborts the continuous paging session due to an error that can be either from the server or - * the client. - * - * @param error the error that causes the abortion. - * @param fromServer whether the error was triggered by the coordinator or by the driver. - */ - @SuppressWarnings("GuardedBy") // this method is only called with the lock held - private void abort(@NonNull Throwable error, boolean fromServer) { - assert lock.isHeldByCurrentThread(); - LOG.trace( - "[{}] Aborting due to {} ({})", - logPrefix, - error.getClass().getSimpleName(), - error.getMessage()); - if (channel == null) { - // This only happens when sending the initial request, if no host was available - // or if the iterator returned by the LBP threw an exception. - // In either case the write was not even attempted, and - // we set the state right now. - enqueueOrCompletePending(error); - state = STATE_FAILED; - } else if (state > 0) { - enqueueOrCompletePending(error); - if (fromServer) { - // We can safely assume the server won't send any more responses, - // so set the state and call release() right now. - state = STATE_FAILED; - reenableAutoReadIfNeeded(); - } else { - // attempt to cancel first, i.e. ask server to stop sending responses, - // and only then release. - cancel(); - } - } - stopGlobalRequestTimer(); - cancelTimeout(globalTimeout); - } - - // METRICS - - private void stopNodeMessageTimer() { - if (stopNodeMessageTimerReported.compareAndSet(false, true)) { - ((DefaultNode) node) - .getMetricUpdater() - .updateTimer( - messagesMetric, - executionProfile.getName(), - System.nanoTime() - messageStartTimeNanos, - TimeUnit.NANOSECONDS); - } - } - - private void stopGlobalRequestTimer() { - session - .getMetricUpdater() - .updateTimer( - continuousRequestsMetric, - null, - System.nanoTime() - startTimeNanos, - TimeUnit.NANOSECONDS); - } - - private void updateErrorMetrics( - @NonNull NodeMetricUpdater metricUpdater, - @NonNull RetryVerdict verdict, - @NonNull DefaultNodeMetric error, - @NonNull DefaultNodeMetric retriesOnError, - @NonNull DefaultNodeMetric ignoresOnError) { - metricUpdater.incrementCounter(error, executionProfile.getName()); - switch (verdict.getRetryDecision()) { - case RETRY_SAME: - case RETRY_NEXT: - metricUpdater.incrementCounter(DefaultNodeMetric.RETRIES, executionProfile.getName()); - metricUpdater.incrementCounter(retriesOnError, executionProfile.getName()); - break; - case IGNORE: - metricUpdater.incrementCounter(DefaultNodeMetric.IGNORES, executionProfile.getName()); - metricUpdater.incrementCounter(ignoresOnError, executionProfile.getName()); - break; - case RETHROW: - // nothing do do - } - } - - // UTILITY METHODS - - @NonNull - private CompletableFuture immediateResultSetFuture(@NonNull Object pageOrError) { - CompletableFuture future = new CompletableFuture<>(); - completeResultSetFuture(future, pageOrError); - return future; - } - - @NonNull - private CompletableFuture cancelledResultSetFuture() { - return immediateResultSetFuture( - new CancellationException( - "Can't get more results because the continuous query has failed already. " - + "Most likely this is because the query was cancelled")); - } - - private void completeResultSetFuture( - @NonNull CompletableFuture future, @NonNull Object pageOrError) { - long now = System.nanoTime(); - long totalLatencyNanos = now - startTimeNanos; - long nodeLatencyNanos = now - messageStartTimeNanos; - if (resultSetClass.isInstance(pageOrError)) { - if (future.complete(resultSetClass.cast(pageOrError))) { - throttler.signalSuccess(ContinuousRequestHandlerBase.this); - if (nodeSuccessReported.compareAndSet(false, true)) { - context - .getRequestTracker() - .onNodeSuccess(statement, nodeLatencyNanos, executionProfile, node, logPrefix); - } - context - .getRequestTracker() - .onSuccess(statement, totalLatencyNanos, executionProfile, node, logPrefix); - } - } else { - Throwable error = (Throwable) pageOrError; - if (future.completeExceptionally(error)) { - context - .getRequestTracker() - .onError(statement, error, totalLatencyNanos, executionProfile, node, logPrefix); - if (error instanceof DriverTimeoutException) { - throttler.signalTimeout(ContinuousRequestHandlerBase.this); - session - .getMetricUpdater() - .incrementCounter(clientTimeoutsMetric, executionProfile.getName()); - } else if (!(error instanceof RequestThrottlingException)) { - throttler.signalError(ContinuousRequestHandlerBase.this, error); - } - } - } - } - - @NonNull - private ExecutionInfo createExecutionInfo(@NonNull Result result, @Nullable Frame response) { - ByteBuffer pagingState = - result instanceof Rows ? ((Rows) result).getMetadata().pagingState : null; - return new DefaultExecutionInfo( - statement, - node, - startedSpeculativeExecutionsCount.get(), - executionIndex, - errors, - pagingState, - response, - true, - session, - context, - executionProfile); - } - - private void logTimeoutSchedulingError(IllegalStateException timeoutError) { - // If we're racing with session shutdown, the timer might be stopped already. We don't want - // to schedule more executions anyway, so swallow the error. - if (!"cannot be started once stopped".equals(timeoutError.getMessage())) { - Loggers.warnWithException( - LOG, "[{}] Error while scheduling timeout", logPrefix, timeoutError); - } - } - - @NonNull - private String asTraceString(@NonNull Object pageOrError) { - return resultSetClass.isInstance(pageOrError) - ? "page " + pageNumber(resultSetClass.cast(pageOrError)) - : ((Exception) pageOrError).getClass().getSimpleName(); - } - - private int getState() { - lock.lock(); - try { - return state; - } finally { - lock.unlock(); - } - } - - private CompletableFuture getPendingResult() { - lock.lock(); - try { - return pendingResult; - } finally { - lock.unlock(); - } - } - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/cql/continuous/DefaultContinuousAsyncResultSet.java b/core/src/main/java/com/datastax/dse/driver/internal/core/cql/continuous/DefaultContinuousAsyncResultSet.java deleted file mode 100644 index 8562fde5905..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/cql/continuous/DefaultContinuousAsyncResultSet.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.cql.continuous; - -import com.datastax.dse.driver.api.core.cql.continuous.ContinuousAsyncResultSet; -import com.datastax.oss.driver.api.core.cql.ColumnDefinitions; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import com.datastax.oss.driver.api.core.cql.Row; -import com.datastax.oss.driver.internal.core.cql.EmptyColumnDefinitions; -import com.datastax.oss.driver.internal.core.util.CountingIterator; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Collections; -import java.util.concurrent.CompletionStage; -import net.jcip.annotations.NotThreadSafe; - -@NotThreadSafe // wraps a mutable queue -public class DefaultContinuousAsyncResultSet implements ContinuousAsyncResultSet { - - private final Iterable currentPage; - private final ColumnDefinitions columnDefinitions; - private final int pageNumber; - private final boolean hasMorePages; - private final ExecutionInfo executionInfo; - private final ContinuousCqlRequestHandler handler; - private final CountingIterator iterator; - - public DefaultContinuousAsyncResultSet( - CountingIterator iterator, - ColumnDefinitions columnDefinitions, - int pageNumber, - boolean hasMorePages, - ExecutionInfo executionInfo, - ContinuousCqlRequestHandler handler) { - this.columnDefinitions = columnDefinitions; - this.pageNumber = pageNumber; - this.hasMorePages = hasMorePages; - this.executionInfo = executionInfo; - this.handler = handler; - this.iterator = iterator; - this.currentPage = () -> iterator; - } - - @NonNull - @Override - public ColumnDefinitions getColumnDefinitions() { - return columnDefinitions; - } - - @Override - public boolean wasApplied() { - // always return true for non-conditional updates - return true; - } - - @NonNull - @Override - public ExecutionInfo getExecutionInfo() { - return executionInfo; - } - - @Override - public int pageNumber() { - return pageNumber; - } - - @Override - public boolean hasMorePages() { - return hasMorePages; - } - - @NonNull - @Override - public Iterable currentPage() { - return currentPage; - } - - @Override - public int remaining() { - return iterator.remaining(); - } - - @NonNull - @Override - public CompletionStage fetchNextPage() throws IllegalStateException { - if (!hasMorePages()) { - throw new IllegalStateException( - "Can't call fetchNextPage() on the last page (use hasMorePages() to check)"); - } - return handler.fetchNextPage(); - } - - @Override - public void cancel() { - handler.cancel(); - } - - public static ContinuousAsyncResultSet empty(ExecutionInfo executionInfo) { - - return new ContinuousAsyncResultSet() { - - @NonNull - @Override - public ColumnDefinitions getColumnDefinitions() { - return EmptyColumnDefinitions.INSTANCE; - } - - @NonNull - @Override - public ExecutionInfo getExecutionInfo() { - return executionInfo; - } - - @NonNull - @Override - public Iterable currentPage() { - return Collections.emptyList(); - } - - @Override - public int remaining() { - return 0; - } - - @Override - public boolean hasMorePages() { - return false; - } - - @Override - public int pageNumber() { - return 1; - } - - @NonNull - @Override - public CompletionStage fetchNextPage() - throws IllegalStateException { - throw new IllegalStateException( - "Can't call fetchNextPage() on the last page (use hasMorePages() to check)"); - } - - @Override - public void cancel() { - // noop - } - - @Override - public boolean wasApplied() { - // always true - return true; - } - }; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/cql/continuous/DefaultContinuousResultSet.java b/core/src/main/java/com/datastax/dse/driver/internal/core/cql/continuous/DefaultContinuousResultSet.java deleted file mode 100644 index 929400bc7a6..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/cql/continuous/DefaultContinuousResultSet.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.cql.continuous; - -import com.datastax.dse.driver.api.core.cql.continuous.ContinuousAsyncResultSet; -import com.datastax.dse.driver.api.core.cql.continuous.ContinuousResultSet; -import com.datastax.oss.driver.api.core.cql.ColumnDefinitions; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import com.datastax.oss.driver.api.core.cql.Row; -import com.datastax.oss.driver.internal.core.util.CountingIterator; -import com.datastax.oss.driver.internal.core.util.concurrent.BlockingOperation; -import com.datastax.oss.driver.internal.core.util.concurrent.CompletableFutures; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import net.jcip.annotations.NotThreadSafe; - -/** - * This class is roughly equivalent to {@link - * com.datastax.oss.driver.internal.core.cql.MultiPageResultSet}, except that {@link - * RowIterator#maybeMoveToNextPage()} needs to check for cancellation before fetching the next page. - */ -@NotThreadSafe -public class DefaultContinuousResultSet implements ContinuousResultSet { - - private final RowIterator iterator; - private final List executionInfos = new ArrayList<>(); - private final ColumnDefinitions columnDefinitions; - - public DefaultContinuousResultSet(ContinuousAsyncResultSet firstPage) { - iterator = new RowIterator(firstPage); - columnDefinitions = firstPage.getColumnDefinitions(); - executionInfos.add(firstPage.getExecutionInfo()); - } - - @Override - public void cancel() { - iterator.cancel(); - } - - @NonNull - @Override - public ColumnDefinitions getColumnDefinitions() { - return columnDefinitions; - } - - @NonNull - @Override - public List getExecutionInfos() { - return executionInfos; - } - - @NonNull - @Override - public Iterator iterator() { - return iterator; - } - - @Override - public boolean isFullyFetched() { - return iterator.isFullyFetched(); - } - - @Override - public int getAvailableWithoutFetching() { - return iterator.remaining(); - } - - @Override - public boolean wasApplied() { - return iterator.wasApplied(); - } - - private class RowIterator extends CountingIterator { - private ContinuousAsyncResultSet currentPage; - private Iterator currentRows; - private boolean cancelled = false; - - private RowIterator(ContinuousAsyncResultSet firstPage) { - super(firstPage.remaining()); - currentPage = firstPage; - currentRows = firstPage.currentPage().iterator(); - } - - @Override - protected Row computeNext() { - maybeMoveToNextPage(); - return currentRows.hasNext() ? currentRows.next() : endOfData(); - } - - private void maybeMoveToNextPage() { - if (!cancelled && !currentRows.hasNext() && currentPage.hasMorePages()) { - BlockingOperation.checkNotDriverThread(); - ContinuousAsyncResultSet nextPage = - CompletableFutures.getUninterruptibly(currentPage.fetchNextPage()); - currentPage = nextPage; - remaining += currentPage.remaining(); - currentRows = nextPage.currentPage().iterator(); - executionInfos.add(nextPage.getExecutionInfo()); - } - } - - private boolean isFullyFetched() { - return !currentPage.hasMorePages(); - } - - private boolean wasApplied() { - return currentPage.wasApplied(); - } - - private void cancel() { - currentPage.cancel(); - cancelled = true; - } - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/cql/continuous/reactive/ContinuousCqlRequestReactiveProcessor.java b/core/src/main/java/com/datastax/dse/driver/internal/core/cql/continuous/reactive/ContinuousCqlRequestReactiveProcessor.java deleted file mode 100644 index afe0e864181..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/cql/continuous/reactive/ContinuousCqlRequestReactiveProcessor.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.cql.continuous.reactive; - -import com.datastax.dse.driver.api.core.cql.continuous.reactive.ContinuousReactiveResultSet; -import com.datastax.dse.driver.internal.core.cql.continuous.ContinuousCqlRequestAsyncProcessor; -import com.datastax.dse.driver.internal.core.cql.reactive.FailedReactiveResultSet; -import com.datastax.oss.driver.api.core.cql.Statement; -import com.datastax.oss.driver.api.core.session.Request; -import com.datastax.oss.driver.api.core.type.reflect.GenericType; -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import com.datastax.oss.driver.internal.core.session.DefaultSession; -import com.datastax.oss.driver.internal.core.session.RequestProcessor; -import net.jcip.annotations.ThreadSafe; - -@ThreadSafe -public class ContinuousCqlRequestReactiveProcessor - implements RequestProcessor, ContinuousReactiveResultSet> { - - public static final GenericType CONTINUOUS_REACTIVE_RESULT_SET = - GenericType.of(ContinuousReactiveResultSet.class); - - private final ContinuousCqlRequestAsyncProcessor asyncProcessor; - - public ContinuousCqlRequestReactiveProcessor(ContinuousCqlRequestAsyncProcessor asyncProcessor) { - this.asyncProcessor = asyncProcessor; - } - - @Override - public boolean canProcess(Request request, GenericType resultType) { - return request instanceof Statement && resultType.equals(CONTINUOUS_REACTIVE_RESULT_SET); - } - - @Override - public ContinuousReactiveResultSet process( - Statement request, - DefaultSession session, - InternalDriverContext context, - String sessionLogPrefix) { - return new DefaultContinuousReactiveResultSet( - () -> asyncProcessor.process(request, session, context, sessionLogPrefix)); - } - - @Override - public ContinuousReactiveResultSet newFailure(RuntimeException error) { - return new FailedReactiveResultSet(error); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/cql/continuous/reactive/DefaultContinuousReactiveResultSet.java b/core/src/main/java/com/datastax/dse/driver/internal/core/cql/continuous/reactive/DefaultContinuousReactiveResultSet.java deleted file mode 100644 index b3f301edea6..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/cql/continuous/reactive/DefaultContinuousReactiveResultSet.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.cql.continuous.reactive; - -import com.datastax.dse.driver.api.core.cql.continuous.ContinuousAsyncResultSet; -import com.datastax.dse.driver.api.core.cql.continuous.reactive.ContinuousReactiveResultSet; -import com.datastax.dse.driver.internal.core.cql.reactive.ReactiveResultSetBase; -import java.util.concurrent.Callable; -import java.util.concurrent.CompletionStage; -import net.jcip.annotations.ThreadSafe; - -@ThreadSafe -public class DefaultContinuousReactiveResultSet - extends ReactiveResultSetBase implements ContinuousReactiveResultSet { - - public DefaultContinuousReactiveResultSet( - Callable> firstPage) { - super(firstPage); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/cql/reactive/FailedReactiveResultSet.java b/core/src/main/java/com/datastax/dse/driver/internal/core/cql/reactive/FailedReactiveResultSet.java index 31c34d649aa..4926725214f 100644 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/cql/reactive/FailedReactiveResultSet.java +++ b/core/src/main/java/com/datastax/dse/driver/internal/core/cql/reactive/FailedReactiveResultSet.java @@ -17,10 +17,8 @@ */ package com.datastax.dse.driver.internal.core.cql.reactive; -import com.datastax.dse.driver.api.core.cql.continuous.reactive.ContinuousReactiveResultSet; import com.datastax.dse.driver.api.core.cql.reactive.ReactiveResultSet; import com.datastax.dse.driver.api.core.cql.reactive.ReactiveRow; -import com.datastax.dse.driver.internal.core.cql.continuous.reactive.ContinuousCqlRequestReactiveProcessor; import com.datastax.oss.driver.api.core.cql.ColumnDefinitions; import com.datastax.oss.driver.api.core.cql.ExecutionInfo; import edu.umd.cs.findbugs.annotations.NonNull; @@ -31,10 +29,9 @@ * subscribers. * * @see CqlRequestReactiveProcessor#newFailure(java.lang.RuntimeException) - * @see ContinuousCqlRequestReactiveProcessor#newFailure(java.lang.RuntimeException) */ public class FailedReactiveResultSet extends FailedPublisher - implements ReactiveResultSet, ContinuousReactiveResultSet { + implements ReactiveResultSet { public FailedReactiveResultSet(Throwable error) { super(error); diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/cql/reactive/ReactiveResultSetSubscription.java b/core/src/main/java/com/datastax/dse/driver/internal/core/cql/reactive/ReactiveResultSetSubscription.java index 500a291e9d2..0297066c7f1 100644 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/cql/reactive/ReactiveResultSetSubscription.java +++ b/core/src/main/java/com/datastax/dse/driver/internal/core/cql/reactive/ReactiveResultSetSubscription.java @@ -44,8 +44,6 @@ /** * A single-subscriber subscription that executes one single query and emits all the returned rows. - * - *

This class can handle both continuous and non-continuous result sets. */ @ThreadSafe public class ReactiveResultSetSubscription> @@ -474,8 +472,7 @@ CompletionStage fetchNextPage() { } catch (Exception e) { // This is a synchronous failure in the driver. // It can happen in rare cases when the driver throws an exception instead of returning a - // failed future; e.g. if someone tries to execute a continuous paging request but the - // protocol version in use does not support it. + // failed future; e.g. if the next page supplier fails before returning its future. // We treat it as a failed future. return CompletableFutures.failedFuture(e); } diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/data/geometry/DefaultGeometry.java b/core/src/main/java/com/datastax/dse/driver/internal/core/data/geometry/DefaultGeometry.java deleted file mode 100644 index 885d9bd48b7..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/data/geometry/DefaultGeometry.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.data.geometry; - -import com.datastax.dse.driver.api.core.data.geometry.Geometry; -import com.datastax.dse.driver.api.core.data.geometry.Point; -import com.datastax.oss.driver.shaded.guava.common.base.Preconditions; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import com.esri.core.geometry.GeometryException; -import com.esri.core.geometry.SpatialReference; -import com.esri.core.geometry.ogc.OGCGeometry; -import com.esri.core.geometry.ogc.OGCLineString; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.io.InvalidObjectException; -import java.io.ObjectInputStream; -import java.io.Serializable; -import java.nio.ByteBuffer; -import net.jcip.annotations.Immutable; - -@Immutable -public abstract class DefaultGeometry implements Geometry, Serializable { - - private static final long serialVersionUID = 1L; - - /** - * Default spatial reference for Well Known Text / Well Known Binary. - * - *

4326 is the EPSG identifier of the World Geodetic System (WGS) in - * its later revision, WGS 84. - */ - public static final SpatialReference SPATIAL_REFERENCE_4326 = SpatialReference.create(4326); - - @NonNull - public static T fromOgcWellKnownText( - @NonNull String source, @NonNull Class klass) { - OGCGeometry geometry; - try { - geometry = OGCGeometry.fromText(source); - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException(e.getMessage()); - } - validateType(geometry, klass); - return klass.cast(geometry); - } - - @NonNull - public static T fromOgcWellKnownBinary( - @NonNull ByteBuffer source, @NonNull Class klass) { - OGCGeometry geometry; - try { - geometry = OGCGeometry.fromBinary(source); - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException(e.getMessage()); - } - validateType(geometry, klass); - return klass.cast(geometry); - } - - @NonNull - public static T fromOgcGeoJson( - @NonNull String source, @NonNull Class klass) { - OGCGeometry geometry; - try { - geometry = OGCGeometry.fromGeoJson(source); - } catch (Exception e) { - throw new IllegalArgumentException(e.getMessage()); - } - validateType(geometry, klass); - return klass.cast(geometry); - } - - private static void validateType(OGCGeometry geometry, Class klass) { - if (!geometry.getClass().equals(klass)) { - throw new IllegalArgumentException( - String.format( - "%s is not of type %s", geometry.getClass().getSimpleName(), klass.getSimpleName())); - } - } - - private final OGCGeometry ogcGeometry; - - protected DefaultGeometry(@NonNull OGCGeometry ogcGeometry) { - this.ogcGeometry = ogcGeometry; - Preconditions.checkNotNull(ogcGeometry); - validateOgcGeometry(ogcGeometry); - } - - private static void validateOgcGeometry(OGCGeometry geometry) { - try { - if (geometry.is3D()) { - throw new IllegalArgumentException(String.format("'%s' is not 2D", geometry.asText())); - } - if (!geometry.isSimple()) { - throw new IllegalArgumentException( - String.format( - "'%s' is not simple. Points and edges cannot self-intersect.", geometry.asText())); - } - } catch (GeometryException e) { - throw new IllegalArgumentException("Invalid geometry" + e.getMessage()); - } - } - - @NonNull - public static ImmutableList getPoints(@NonNull OGCLineString lineString) { - ImmutableList.Builder builder = ImmutableList.builder(); - for (int i = 0; i < lineString.numPoints(); i++) { - builder.add(new DefaultPoint(lineString.pointN(i))); - } - return builder.build(); - } - - protected static com.esri.core.geometry.Point toEsri(Point p) { - return new com.esri.core.geometry.Point(p.X(), p.Y()); - } - - @NonNull - public OGCGeometry getOgcGeometry() { - return ogcGeometry; - } - - @NonNull - public com.esri.core.geometry.Geometry getEsriGeometry() { - return ogcGeometry.getEsriGeometry(); - } - - @NonNull - @Override - public String asWellKnownText() { - return ogcGeometry.asText(); - } - - @NonNull - @Override - public ByteBuffer asWellKnownBinary() { - return WkbUtil.asLittleEndianBinary(ogcGeometry); - } - - @NonNull - @Override - public String asGeoJson() { - return ogcGeometry.asGeoJson(); - } - - @Override - public boolean contains(@NonNull Geometry other) { - Preconditions.checkNotNull(other); - if (other instanceof DefaultGeometry) { - DefaultGeometry defautlOther = (DefaultGeometry) other; - return getOgcGeometry().contains(defautlOther.getOgcGeometry()); - } - return false; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof DefaultGeometry)) { - return false; - } - DefaultGeometry that = (DefaultGeometry) o; - return this.getOgcGeometry().equals(that.getOgcGeometry()); - } - - @Override - public int hashCode() { - // OGCGeometry subclasses do not overwrite Object.hashCode() - // while com.esri.core.geometry.Geometry subclasses usually do, - // so use these instead; this is consistent with equals - // because OGCGeometry.equals() actually compare between - // com.esri.core.geometry.Geometry objects - return getEsriGeometry().hashCode(); - } - - // Should never be called since we serialize a proxy (see subclasses) - @SuppressWarnings("UnusedVariable") - private void readObject(ObjectInputStream stream) throws InvalidObjectException { - throw new InvalidObjectException("Proxy required"); - } - - @Override - public String toString() { - return asWellKnownText(); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/data/geometry/DefaultLineString.java b/core/src/main/java/com/datastax/dse/driver/internal/core/data/geometry/DefaultLineString.java deleted file mode 100644 index 1cf64bb366d..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/data/geometry/DefaultLineString.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.data.geometry; - -import com.datastax.dse.driver.api.core.data.geometry.LineString; -import com.datastax.dse.driver.api.core.data.geometry.Point; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import com.esri.core.geometry.Polyline; -import com.esri.core.geometry.ogc.OGCLineString; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.List; -import net.jcip.annotations.Immutable; - -@Immutable -public class DefaultLineString extends DefaultGeometry implements LineString { - - private static final long serialVersionUID = 1280189361978382248L; - - private static OGCLineString fromPoints(Point p1, Point p2, Point... pn) { - Polyline polyline = new Polyline(toEsri(p1), toEsri(p2)); - for (Point p : pn) { - polyline.lineTo(toEsri(p)); - } - return new OGCLineString(polyline, 0, DefaultGeometry.SPATIAL_REFERENCE_4326); - } - - private final List points; - - public DefaultLineString(@NonNull Point p1, @NonNull Point p2, @NonNull Point... pn) { - super(fromPoints(p1, p2, pn)); - this.points = ImmutableList.builder().add(p1).add(p2).add(pn).build(); - } - - public DefaultLineString(@NonNull OGCLineString lineString) { - super(lineString); - this.points = getPoints(lineString); - } - - @NonNull - @Override - public List getPoints() { - return points; - } - - /** - * This object gets replaced by an internal proxy for serialization. - * - * @serialData a single byte array containing the Well-Known Binary representation. - */ - private Object writeReplace() { - return new WkbSerializationProxy(this.asWellKnownBinary()); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/data/geometry/DefaultPoint.java b/core/src/main/java/com/datastax/dse/driver/internal/core/data/geometry/DefaultPoint.java deleted file mode 100644 index c9540b10d8a..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/data/geometry/DefaultPoint.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.data.geometry; - -import com.datastax.dse.driver.api.core.data.geometry.Point; -import com.esri.core.geometry.ogc.OGCPoint; -import edu.umd.cs.findbugs.annotations.NonNull; -import net.jcip.annotations.Immutable; - -@Immutable -public class DefaultPoint extends DefaultGeometry implements Point { - - private static final long serialVersionUID = -8337622213980781285L; - - public DefaultPoint(double x, double y) { - this( - new OGCPoint( - new com.esri.core.geometry.Point(x, y), DefaultGeometry.SPATIAL_REFERENCE_4326)); - } - - public DefaultPoint(@NonNull OGCPoint point) { - super(point); - } - - @NonNull - @Override - public OGCPoint getOgcGeometry() { - return (OGCPoint) super.getOgcGeometry(); - } - - @Override - public double X() { - return getOgcGeometry().X(); - } - - @Override - public double Y() { - return getOgcGeometry().Y(); - } - - /** - * This object gets replaced by an internal proxy for serialization. - * - * @serialData a single byte array containing the Well-Known Binary representation. - */ - private Object writeReplace() { - return new WkbSerializationProxy(this.asWellKnownBinary()); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/data/geometry/DefaultPolygon.java b/core/src/main/java/com/datastax/dse/driver/internal/core/data/geometry/DefaultPolygon.java deleted file mode 100644 index 27d375d42b1..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/data/geometry/DefaultPolygon.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.data.geometry; - -import com.datastax.dse.driver.api.core.data.geometry.Point; -import com.datastax.dse.driver.api.core.data.geometry.Polygon; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import com.esri.core.geometry.Operator; -import com.esri.core.geometry.OperatorFactoryLocal; -import com.esri.core.geometry.OperatorSimplifyOGC; -import com.esri.core.geometry.ogc.OGCPolygon; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Collections; -import java.util.List; -import net.jcip.annotations.Immutable; - -@Immutable -public class DefaultPolygon extends DefaultGeometry implements Polygon { - - private static final long serialVersionUID = 3694196802962890314L; - - private final List exteriorRing; - private final List> interiorRings; - - public DefaultPolygon( - @NonNull Point p1, @NonNull Point p2, @NonNull Point p3, @NonNull Point... pn) { - super(fromPoints(p1, p2, p3, pn)); - this.exteriorRing = ImmutableList.builder().add(p1).add(p2).add(p3).add(pn).build(); - this.interiorRings = Collections.emptyList(); - } - - public DefaultPolygon(@NonNull OGCPolygon polygon) { - super(polygon); - if (polygon.isEmpty()) { - this.exteriorRing = ImmutableList.of(); - } else { - this.exteriorRing = getPoints(polygon.exteriorRing()); - } - - ImmutableList.Builder> builder = ImmutableList.builder(); - for (int i = 0; i < polygon.numInteriorRing(); i++) { - builder.add(getPoints(polygon.interiorRingN(i))); - } - this.interiorRings = builder.build(); - } - - @NonNull - @Override - public List getExteriorRing() { - return exteriorRing; - } - - @NonNull - @Override - public List> getInteriorRings() { - return interiorRings; - } - - private static OGCPolygon fromPoints(Point p1, Point p2, Point p3, Point... pn) { - com.esri.core.geometry.Polygon polygon = new com.esri.core.geometry.Polygon(); - addPath(polygon, p1, p2, p3, pn); - return new OGCPolygon(simplify(polygon), DefaultGeometry.SPATIAL_REFERENCE_4326); - } - - private static void addPath( - com.esri.core.geometry.Polygon polygon, Point p1, Point p2, Point p3, Point[] pn) { - - polygon.startPath(toEsri(p1)); - polygon.lineTo(toEsri(p2)); - polygon.lineTo(toEsri(p3)); - for (Point p : pn) { - polygon.lineTo(toEsri(p)); - } - } - - private static com.esri.core.geometry.Polygon simplify(com.esri.core.geometry.Polygon polygon) { - OperatorSimplifyOGC op = - (OperatorSimplifyOGC) - OperatorFactoryLocal.getInstance().getOperator(Operator.Type.SimplifyOGC); - return (com.esri.core.geometry.Polygon) - op.execute(polygon, DefaultGeometry.SPATIAL_REFERENCE_4326, true, null); - } - - /** - * This object gets replaced by an internal proxy for serialization. - * - * @serialData a single byte array containing the Well-Known Binary representation. - */ - private Object writeReplace() { - return new WkbSerializationProxy(this.asWellKnownBinary()); - } - - public static class Builder implements Polygon.Builder { - private final com.esri.core.geometry.Polygon polygon = new com.esri.core.geometry.Polygon(); - - @NonNull - @Override - public Builder addRing( - @NonNull Point p1, @NonNull Point p2, @NonNull Point p3, @NonNull Point... pn) { - addPath(polygon, p1, p2, p3, pn); - return this; - } - - /** - * Builds the polygon. - * - * @return the polygon. - */ - @NonNull - @Override - public Polygon build() { - return new DefaultPolygon( - new OGCPolygon(simplify(polygon), DefaultGeometry.SPATIAL_REFERENCE_4326)); - } - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/data/geometry/Distance.java b/core/src/main/java/com/datastax/dse/driver/internal/core/data/geometry/Distance.java deleted file mode 100644 index 518f6aa1346..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/data/geometry/Distance.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.data.geometry; - -import static java.util.regex.Pattern.CASE_INSENSITIVE; - -import com.datastax.dse.driver.api.core.data.geometry.Geometry; -import com.datastax.dse.driver.api.core.data.geometry.LineString; -import com.datastax.dse.driver.api.core.data.geometry.Point; -import com.datastax.dse.driver.api.core.data.geometry.Polygon; -import com.datastax.dse.driver.api.core.graph.predicates.Geo; -import com.datastax.oss.driver.shaded.guava.common.base.Preconditions; -import com.esri.core.geometry.MultiPath; -import com.esri.core.geometry.ogc.OGCGeometry; -import com.esri.core.geometry.ogc.OGCPoint; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.nio.ByteBuffer; -import java.util.Objects; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import net.jcip.annotations.Immutable; - -/** - * The driver-side representation of DSE's {@code Geo.distance}. - * - *

This is a circle in a two-dimensional XY plane represented by its center point and radius. It - * is used as a search criteria to determine whether or not another geospatial object lies within a - * circular area. - * - *

Note that this shape has no equivalent in the OGC and GeoJSON standards: as a consequence, - * {@link #asWellKnownText()} returns a custom format, and {@link #getOgcGeometry()}, {@link - * #asWellKnownBinary()}, and {@link #asGeoJson()} throw {@link UnsupportedOperationException}. - * - *

Unlike other geo types, this class is never exposed directly to driver clients: it is used - * internally by {@linkplain Geo#inside(Point, double) geo predicates}, but cannot be a column type, - * nor appear in CQL or graph results. Therefore it doesn't have a public-facing interface, nor a - * built-in codec. - */ -@Immutable -public class Distance extends DefaultGeometry { - - private static final Pattern WKT_PATTERN = - Pattern.compile( - "distance *\\( *\\( *([\\d\\.-]+) *([\\d+\\.-]+) *\\) *([\\d+\\.-]+) *\\)", - CASE_INSENSITIVE); - - /** - * Creates a distance from its Well-known - * Text (WKT) representation. - * - * @param source the Well-known Text representation to parse. - * @return the point represented by the WKT. - * @throws IllegalArgumentException if the string does not contain a valid Well-known Text - * representation. - * @see Distance#asWellKnownText() - */ - @NonNull - public static Distance fromWellKnownText(@NonNull String source) { - Matcher matcher = WKT_PATTERN.matcher(source.trim()); - if (matcher.matches() && matcher.groupCount() == 3) { - try { - return new Distance( - new DefaultPoint( - Double.parseDouble(matcher.group(1)), Double.parseDouble(matcher.group(2))), - Double.parseDouble(matcher.group(3))); - } catch (NumberFormatException var3) { - throw new IllegalArgumentException(String.format("Unable to parse %s", source)); - } - } else { - throw new IllegalArgumentException(String.format("Unable to parse %s", source)); - } - } - - private final DefaultPoint center; - - private final double radius; - - /** - * Creates a new distance with the given center and radius. - * - * @param center The center point. - * @param radius The radius of the circle representing distance. - */ - public Distance(@NonNull Point center, double radius) { - super(((DefaultPoint) center).getOgcGeometry()); - Preconditions.checkNotNull(center); - Preconditions.checkArgument(radius >= 0.0D, "Radius must be >= 0 (got %s)", radius); - this.center = ((DefaultPoint) center); - this.radius = radius; - } - - /** @return The center point of the circle representing this distance. */ - @NonNull - public Point getCenter() { - return center; - } - - /** @return The radius of the circle representing this distance. */ - public double getRadius() { - return radius; - } - - /** - * Returns a Well-known Text (WKT) - * representation of this geospatial type. - * - *

Since there is no Well-known Text specification for Distance, this returns a custom format - * of: DISTANCE((center.x center.y) radius) - * - * @return a Well-known Text representation of this object. - */ - @NonNull - @Override - public String asWellKnownText() { - return String.format("DISTANCE((%s %s) %s)", this.center.X(), this.center.Y(), this.radius); - } - - /** - * The distance type has no equivalent in the OGC standard: this method throws an {@link - * UnsupportedOperationException}. - */ - @NonNull - @Override - public OGCGeometry getOgcGeometry() { - throw new UnsupportedOperationException(); - } - - /** - * The distance type has no equivalent in the OGC standard: this method throws an {@link - * UnsupportedOperationException}. - */ - @NonNull - @Override - public ByteBuffer asWellKnownBinary() { - throw new UnsupportedOperationException(); - } - - /** - * The distance type has no equivalent in the GeoJSON standard: this method throws an {@link - * UnsupportedOperationException}. - */ - @Override - @NonNull - public String asGeoJson() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean equals(Object other) { - if (other == this) { - return true; - } else if (other instanceof Distance) { - Distance that = (Distance) other; - return Objects.equals(this.center, that.center) && this.radius == that.radius; - } else { - return false; - } - } - - @Override - public int hashCode() { - return Objects.hash(center, radius); - } - - @SuppressWarnings("SimplifiableConditionalExpression") - @Override - public boolean contains(@NonNull Geometry geometry) { - return geometry instanceof Distance - ? this.containsDistance((Distance) geometry) - : geometry instanceof Point - ? this.containsPoint((Point) geometry) - : geometry instanceof LineString - ? this.containsLineString((LineString) geometry) - : geometry instanceof Polygon ? this.containsPolygon((Polygon) geometry) : false; - } - - private boolean containsDistance(Distance distance) { - return this.center.getOgcGeometry().distance(distance.center.getOgcGeometry()) + distance.radius - <= this.radius; - } - - private boolean containsPoint(Point point) { - return this.containsOGCPoint(((DefaultPoint) point).getOgcGeometry()); - } - - private boolean containsLineString(LineString lineString) { - MultiPath multiPath = - (MultiPath) ((DefaultLineString) lineString).getOgcGeometry().getEsriGeometry(); - return containsMultiPath(multiPath); - } - - private boolean containsPolygon(Polygon polygon) { - MultiPath multiPath = - (com.esri.core.geometry.Polygon) - ((DefaultPolygon) polygon).getOgcGeometry().getEsriGeometry(); - return containsMultiPath(multiPath); - } - - private boolean containsMultiPath(MultiPath multiPath) { - int numPoints = multiPath.getPointCount(); - for (int i = 0; i < numPoints; ++i) { - OGCPoint point = new OGCPoint(multiPath.getPoint(i), DefaultGeometry.SPATIAL_REFERENCE_4326); - if (!this.containsOGCPoint(point)) { - return false; - } - } - return true; - } - - private boolean containsOGCPoint(OGCPoint point) { - return this.center.getOgcGeometry().distance(point) <= this.radius; - } - - /** - * This object gets replaced by an internal proxy for serialization. - * - * @serialData Point (wkb) for center followed by double for radius - */ - private Object writeReplace() { - return new DistanceSerializationProxy(this); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/data/geometry/DistanceSerializationProxy.java b/core/src/main/java/com/datastax/dse/driver/internal/core/data/geometry/DistanceSerializationProxy.java deleted file mode 100644 index 515af121980..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/data/geometry/DistanceSerializationProxy.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.data.geometry; - -import com.datastax.dse.driver.api.core.data.geometry.Point; -import java.io.Serializable; - -/** - * A thin wrapper around {@link Distance}, that gets substituted during the serialization / - * deserialization process. This allows {@link Distance} to be immutable and reference centers' OGC - * counterpart. - */ -public class DistanceSerializationProxy implements Serializable { - - private static final long serialVersionUID = 1L; - - private final Point center; - private final double radius; - - public DistanceSerializationProxy(Distance distance) { - this.center = distance.getCenter(); - this.radius = distance.getRadius(); - } - - private Object readResolve() { - return new Distance(center, radius); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/data/geometry/WkbSerializationProxy.java b/core/src/main/java/com/datastax/dse/driver/internal/core/data/geometry/WkbSerializationProxy.java deleted file mode 100644 index 92c0f6de2d5..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/data/geometry/WkbSerializationProxy.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.data.geometry; - -import com.datastax.dse.driver.api.core.data.geometry.LineString; -import com.datastax.dse.driver.api.core.data.geometry.Point; -import com.datastax.dse.driver.api.core.data.geometry.Polygon; -import com.datastax.oss.protocol.internal.util.Bytes; -import java.io.Serializable; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import net.jcip.annotations.Immutable; - -/** - * A thin wrapper around a Well-Known Binary byte sequence, that gets substituted for {@link - * DefaultGeometry} instances during the serialization / deserialization process. This allows - * immutable geometry classes. - */ -@Immutable -class WkbSerializationProxy implements Serializable { - - private static final long serialVersionUID = 1L; - - private final byte[] wkb; - - WkbSerializationProxy(ByteBuffer wkb) { - this.wkb = Bytes.getArray(wkb); - } - - private Object readResolve() { - ByteBuffer buffer = ByteBuffer.wrap(wkb).order(ByteOrder.nativeOrder()); - int type = buffer.getInt(1); - - if (type == 1) { - return Point.fromWellKnownBinary(buffer); - } else if (type == 2) { - return LineString.fromWellKnownBinary(buffer); - } else if (type == 3) { - return Polygon.fromWellKnownBinary(buffer); - } else { - throw new IllegalArgumentException( - "Unknown geospatial type code in serialized form: " + type); - } - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/data/geometry/WkbUtil.java b/core/src/main/java/com/datastax/dse/driver/internal/core/data/geometry/WkbUtil.java deleted file mode 100644 index 3f18b32fda2..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/data/geometry/WkbUtil.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.data.geometry; - -import com.esri.core.geometry.Geometry; -import com.esri.core.geometry.Operator; -import com.esri.core.geometry.OperatorExportToWkb; -import com.esri.core.geometry.OperatorFactoryLocal; -import com.esri.core.geometry.WkbExportFlags; -import com.esri.core.geometry.ogc.OGCGeometry; -import com.esri.core.geometry.ogc.OGCLineString; -import com.esri.core.geometry.ogc.OGCPoint; -import com.esri.core.geometry.ogc.OGCPolygon; -import java.lang.reflect.Method; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -/** - * Helper class to serialize OGC geometries to Well-Known Binary, forcing the byte order to little - * endian. - * - *

WKB encodes the byte order, so in theory we could send the buffer in any order, even if it is - * different from the server. However DSE server performs an additional validation step server-side: - * it deserializes to Java, serializes back to WKB, and then compares the original buffer to the - * "re-serialized" one. If they don't match, a MarshalException is thrown. So with a client in - * big-endian and a server in little-endian, we would get: - * - *

- * incoming buffer (big endian) --> Java --> reserialized buffer (little endian)
- * 
- * - * Since the two buffers have a different endian-ness, they don't match. - * - *

The ESRI library defaults to the native byte order and doesn't let us change it. Therefore: - * - *

    - *
  • if the native order is little endian (vast majority of cases), this class simply delegates - * to the appropriate public API method; - *
  • if the native order is big endian, it re-implements the serialization code, using - * reflection to get access to a private method. If reflection fails for any reason (updated - * ESRI library, security manager...), a runtime exception will be thrown. - *
- */ -class WkbUtil { - - private static final boolean IS_NATIVE_LITTLE_ENDIAN = - ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN) - && System.getProperty("com.datastax.driver.dse.geometry.FORCE_REFLECTION_WKB") - == null; // only for tests - - static ByteBuffer asLittleEndianBinary(OGCGeometry ogcGeometry) { - if (IS_NATIVE_LITTLE_ENDIAN) { - return ogcGeometry.asBinary(); // the default implementation does what we want - } else { - int exportFlags; - if (ogcGeometry instanceof OGCPoint) { - exportFlags = 0; - } else if (ogcGeometry instanceof OGCLineString) { - exportFlags = WkbExportFlags.wkbExportLineString; - } else if (ogcGeometry instanceof OGCPolygon) { - exportFlags = WkbExportFlags.wkbExportPolygon; - } else { - throw new AssertionError("Unsupported type: " + ogcGeometry.getClass()); - } - - // Copy-pasted from OperatorExportToWkbLocal#execute, except for the flags and order - int size = exportToWKB(exportFlags, ogcGeometry.getEsriGeometry(), null); - ByteBuffer wkbBuffer = ByteBuffer.allocate(size).order(ByteOrder.LITTLE_ENDIAN); - exportToWKB(exportFlags, ogcGeometry.getEsriGeometry(), wkbBuffer); - return wkbBuffer; - } - } - - // Provides reflective access to the private static method OperatorExportToWkbLocal#exportToWKB - private static int exportToWKB(int exportFlags, Geometry geometry, ByteBuffer wkbBuffer) { - assert !IS_NATIVE_LITTLE_ENDIAN; - try { - return (Integer) exportToWKB.invoke(null, exportFlags, geometry, wkbBuffer); - } catch (Exception e) { - throw new RuntimeException( - "Couldn't invoke private method OperatorExportToWkbLocal#exportToWKB", e); - } - } - - private static final Method exportToWKB; - - static { - if (IS_NATIVE_LITTLE_ENDIAN) { - exportToWKB = null; // won't be used - } else { - try { - OperatorExportToWkb op = - (OperatorExportToWkb) - OperatorFactoryLocal.getInstance().getOperator(Operator.Type.ExportToWkb); - exportToWKB = - op.getClass() - .getDeclaredMethod("exportToWKB", int.class, Geometry.class, ByteBuffer.class); - exportToWKB.setAccessible(true); - } catch (NoSuchMethodException e) { - throw new RuntimeException( - "Couldn't get access to private method OperatorExportToWkbLocal#exportToWKB", e); - } - } - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/ByteBufUtil.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/ByteBufUtil.java deleted file mode 100644 index 333ba6099d3..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/ByteBufUtil.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import java.nio.ByteBuffer; - -public class ByteBufUtil { - - // Does not move the reader index of the ByteBuf parameter - public static ByteBuffer toByteBuffer(ByteBuf buffer) { - if (buffer.isDirect()) { - return buffer.nioBuffer(); - } - final byte[] bytes = new byte[buffer.readableBytes()]; - buffer.getBytes(buffer.readerIndex(), bytes); - return ByteBuffer.wrap(bytes); - } - - static ByteBuf toByteBuf(ByteBuffer buffer) { - return Unpooled.wrappedBuffer(buffer); - } - - // read a predefined amount of bytes from the netty buffer and move its readerIndex - public static ByteBuffer readBytes(ByteBuf nettyBuf, int size) { - ByteBuffer res = ByteBuffer.allocate(size); - nettyBuf.readBytes(res); - res.flip(); - return res; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/BytecodeGraphStatement.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/BytecodeGraphStatement.java deleted file mode 100644 index e8e4554e81f..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/BytecodeGraphStatement.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import com.datastax.dse.driver.api.core.graph.FluentGraphStatement; -import com.datastax.oss.driver.api.core.ConsistencyLevel; -import com.datastax.oss.driver.api.core.RequestRoutingType; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.cql.Statement; -import com.datastax.oss.driver.api.core.metadata.Node; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.nio.ByteBuffer; -import java.time.Duration; -import java.util.Collections; -import java.util.Map; -import org.apache.tinkerpop.gremlin.process.traversal.Bytecode; - -/** - * A dedicated statement implementation for implicit traversal execution via a {@link - * DseGraphRemoteConnection}. - * - *

This is a simplified version of {@link FluentGraphStatement} that exposes the bytecode - * directly instead of the traversal. - * - *

This class is for internal use only. - */ -public class BytecodeGraphStatement extends GraphStatementBase { - - private final Bytecode bytecode; - - public BytecodeGraphStatement( - Bytecode bytecode, DriverExecutionProfile executionProfile, String executionProfileName) { - this( - bytecode, - null, - null, - null, - Statement.NO_DEFAULT_TIMESTAMP, - executionProfile, - executionProfileName, - Collections.emptyMap(), - null, - null, - null, - null, - null, - null); - } - - private BytecodeGraphStatement( - Bytecode bytecode, - Boolean isIdempotent, - Duration timeout, - Node node, - long timestamp, - DriverExecutionProfile executionProfile, - String executionProfileName, - Map customPayload, - String graphName, - String traversalSource, - String subProtocol, - ConsistencyLevel consistencyLevel, - ConsistencyLevel readConsistencyLevel, - ConsistencyLevel writeConsistencyLevel) { - super( - isIdempotent, - timeout, - node, - timestamp, - executionProfile, - executionProfileName, - customPayload, - graphName, - traversalSource, - subProtocol, - consistencyLevel, - readConsistencyLevel, - writeConsistencyLevel); - this.bytecode = bytecode; - } - - public Bytecode getBytecode() { - return bytecode; - } - - @Override - protected BytecodeGraphStatement newInstance( - Boolean isIdempotent, - Duration timeout, - Node node, - long timestamp, - DriverExecutionProfile executionProfile, - String executionProfileName, - Map customPayload, - String graphName, - String traversalSource, - String subProtocol, - ConsistencyLevel consistencyLevel, - ConsistencyLevel readConsistencyLevel, - ConsistencyLevel writeConsistencyLevel) { - return new BytecodeGraphStatement( - bytecode, - isIdempotent, - timeout, - node, - timestamp, - executionProfile, - executionProfileName, - customPayload, - graphName, - traversalSource, - subProtocol, - consistencyLevel, - readConsistencyLevel, - writeConsistencyLevel); - } - - @NonNull - @Override - public RequestRoutingType getRequestRoutingType() { - return RequestRoutingType.REGULAR; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/ContinuousAsyncGraphResultSet.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/ContinuousAsyncGraphResultSet.java deleted file mode 100644 index 9c7f773c3a2..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/ContinuousAsyncGraphResultSet.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import com.datastax.dse.driver.api.core.graph.AsyncGraphResultSet; -import com.datastax.dse.driver.api.core.graph.GraphNode; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import com.datastax.oss.driver.internal.core.util.CountingIterator; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Collections; -import java.util.Queue; -import java.util.concurrent.CompletionStage; -import net.jcip.annotations.NotThreadSafe; - -@NotThreadSafe // wraps a mutable queue -public class ContinuousAsyncGraphResultSet implements AsyncGraphResultSet { - - private final CountingIterator iterator; - private final int pageNumber; - private final boolean hasMorePages; - private final ExecutionInfo executionInfo; - private final ContinuousGraphRequestHandler continuousGraphRequestHandler; - private final Iterable currentPage; - - public ContinuousAsyncGraphResultSet( - ExecutionInfo executionInfo, - Queue data, - int pageNumber, - boolean hasMorePages, - ContinuousGraphRequestHandler continuousGraphRequestHandler, - GraphProtocol graphProtocol) { - - this.iterator = new GraphResultIterator(data, graphProtocol); - this.pageNumber = pageNumber; - this.hasMorePages = hasMorePages; - this.executionInfo = executionInfo; - this.continuousGraphRequestHandler = continuousGraphRequestHandler; - this.currentPage = () -> iterator; - } - - @NonNull - @Override - public ExecutionInfo getRequestExecutionInfo() { - return executionInfo; - } - - @NonNull - @Override - @Deprecated - public com.datastax.dse.driver.api.core.graph.GraphExecutionInfo getExecutionInfo() { - return GraphExecutionInfoConverter.convert(executionInfo); - } - - @Override - public int remaining() { - return iterator.remaining(); - } - - @NonNull - @Override - public Iterable currentPage() { - return currentPage; - } - - @Override - public boolean hasMorePages() { - return hasMorePages; - } - - @NonNull - @Override - public CompletionStage fetchNextPage() throws IllegalStateException { - if (!hasMorePages()) { - throw new IllegalStateException( - "Can't call fetchNextPage() on the last page (use hasMorePages() to check)"); - } - return continuousGraphRequestHandler.fetchNextPage(); - } - - @Override - public void cancel() { - continuousGraphRequestHandler.cancel(); - } - - /** Returns the current page's number. Pages are numbered starting from 1. */ - public int pageNumber() { - return pageNumber; - } - - static AsyncGraphResultSet empty(ExecutionInfo executionInfo) { - - return new AsyncGraphResultSet() { - - @NonNull - @Override - public ExecutionInfo getRequestExecutionInfo() { - return executionInfo; - } - - @NonNull - @Override - @Deprecated - public com.datastax.dse.driver.api.core.graph.GraphExecutionInfo getExecutionInfo() { - return GraphExecutionInfoConverter.convert(executionInfo); - } - - @NonNull - @Override - public Iterable currentPage() { - return Collections.emptyList(); - } - - @Override - public int remaining() { - return 0; - } - - @Override - public boolean hasMorePages() { - return false; - } - - @NonNull - @Override - public CompletionStage fetchNextPage() throws IllegalStateException { - throw new IllegalStateException( - "Can't call fetchNextPage() on the last page (use hasMorePages() to check)"); - } - - @Override - public void cancel() { - // noop - } - }; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/ContinuousGraphRequestHandler.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/ContinuousGraphRequestHandler.java deleted file mode 100644 index 07d9e4c84a3..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/ContinuousGraphRequestHandler.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.dse.driver.api.core.graph.AsyncGraphResultSet; -import com.datastax.dse.driver.api.core.graph.GraphNode; -import com.datastax.dse.driver.api.core.graph.GraphStatement; -import com.datastax.dse.driver.api.core.metrics.DseNodeMetric; -import com.datastax.dse.driver.api.core.metrics.DseSessionMetric; -import com.datastax.dse.driver.internal.core.cql.continuous.ContinuousRequestHandlerBase; -import com.datastax.dse.driver.internal.core.graph.binary.GraphBinaryModule; -import com.datastax.dse.protocol.internal.response.result.DseRowsMetadata; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.cql.ColumnDefinitions; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import com.datastax.oss.driver.internal.core.cql.Conversions; -import com.datastax.oss.driver.internal.core.session.DefaultSession; -import com.datastax.oss.driver.shaded.guava.common.base.MoreObjects; -import com.datastax.oss.protocol.internal.Message; -import com.datastax.oss.protocol.internal.response.result.Rows; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.time.Duration; -import java.util.ArrayDeque; -import java.util.List; -import java.util.Map; -import java.util.Queue; -import net.jcip.annotations.ThreadSafe; - -/** - * Handles a Graph request that supports multiple response messages (a.k.a. continuous paging - * request). - */ -@ThreadSafe -public class ContinuousGraphRequestHandler - extends ContinuousRequestHandlerBase, AsyncGraphResultSet> { - - private final GraphBinaryModule graphBinaryModule; - private final GraphSupportChecker graphSupportChecker; - private final Duration globalTimeout; - - ContinuousGraphRequestHandler( - @NonNull GraphStatement statement, - @NonNull DefaultSession session, - @NonNull InternalDriverContext context, - @NonNull String sessionLogPrefix, - @NonNull GraphBinaryModule graphBinaryModule, - @NonNull GraphSupportChecker graphSupportChecker) { - super( - statement, - session, - context, - sessionLogPrefix, - AsyncGraphResultSet.class, - true, - DseSessionMetric.GRAPH_CLIENT_TIMEOUTS, - DseSessionMetric.GRAPH_REQUESTS, - DseNodeMetric.GRAPH_MESSAGES); - this.graphBinaryModule = graphBinaryModule; - this.graphSupportChecker = graphSupportChecker; - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(statement, context); - globalTimeout = - MoreObjects.firstNonNull( - statement.getTimeout(), - executionProfile.getDuration(DseDriverOption.GRAPH_TIMEOUT, Duration.ZERO)); - // NOTE that ordering of the following statement matters. - // We should register this request after all fields have been initialized. - throttler.register(this); - } - - @NonNull - @Override - protected Duration getGlobalTimeout() { - return globalTimeout; - } - - @NonNull - @Override - protected Duration getPageTimeout(@NonNull GraphStatement statement, int pageNumber) { - return Duration.ZERO; - } - - @NonNull - @Override - protected Duration getReviseRequestTimeout(@NonNull GraphStatement statement) { - return Duration.ZERO; - } - - @Override - protected int getMaxEnqueuedPages(@NonNull GraphStatement statement) { - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(statement, context); - return executionProfile.getInt(DseDriverOption.GRAPH_CONTINUOUS_PAGING_MAX_ENQUEUED_PAGES); - } - - @Override - protected int getMaxPages(@NonNull GraphStatement statement) { - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(statement, context); - return executionProfile.getInt(DseDriverOption.GRAPH_CONTINUOUS_PAGING_MAX_PAGES); - } - - @NonNull - @Override - protected Message getMessage(@NonNull GraphStatement statement) { - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(statement, context); - GraphProtocol subProtocol = - graphSupportChecker.inferGraphProtocol(statement, executionProfile, context); - return GraphConversions.createContinuousMessageFromGraphStatement( - statement, subProtocol, executionProfile, context, graphBinaryModule); - } - - @Override - protected boolean isTracingEnabled(@NonNull GraphStatement statement) { - return statement.isTracing(); - } - - @NonNull - @Override - protected Map createPayload(@NonNull GraphStatement statement) { - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(statement, context); - GraphProtocol subProtocol = - graphSupportChecker.inferGraphProtocol(statement, executionProfile, context); - return GraphConversions.createCustomPayload( - statement, subProtocol, executionProfile, context, graphBinaryModule); - } - - @NonNull - @Override - protected AsyncGraphResultSet createEmptyResultSet(@NonNull ExecutionInfo executionInfo) { - return ContinuousAsyncGraphResultSet.empty(executionInfo); - } - - @NonNull - @Override - protected ContinuousAsyncGraphResultSet createResultSet( - @NonNull GraphStatement statement, - @NonNull Rows rows, - @NonNull ExecutionInfo executionInfo, - @NonNull ColumnDefinitions columnDefinitions) - throws IOException { - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(statement, context); - GraphProtocol subProtocol = - graphSupportChecker.inferGraphProtocol(statement, executionProfile, context); - - Queue graphNodes = new ArrayDeque<>(); - for (List row : rows.getData()) { - if (subProtocol.isGraphBinary()) { - graphNodes.offer(GraphConversions.createGraphBinaryGraphNode(row, this.graphBinaryModule)); - } else { - graphNodes.offer(GraphSONUtils.createGraphNode(row, subProtocol)); - } - } - - DseRowsMetadata metadata = (DseRowsMetadata) rows.getMetadata(); - return new ContinuousAsyncGraphResultSet( - executionInfo, - graphNodes, - metadata.continuousPageNumber, - !metadata.isLastContinuousPage, - this, - subProtocol); - } - - @Override - protected int pageNumber(@NonNull AsyncGraphResultSet resultSet) { - return ((ContinuousAsyncGraphResultSet) resultSet).pageNumber(); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/CqlCollectionPredicate.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/CqlCollectionPredicate.java deleted file mode 100644 index 349321da0cf..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/CqlCollectionPredicate.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import com.datastax.oss.driver.shaded.guava.common.base.Preconditions; -import java.util.Collection; -import java.util.Map; -import java.util.Objects; -import org.javatuples.Pair; - -/** Predicates that can be used on CQL Collections. */ -public enum CqlCollectionPredicate implements DsePredicate { - contains { - @Override - public boolean test(Object value, Object condition) { - preEvaluate(condition); - Preconditions.checkArgument(value instanceof Collection); - return ((Collection) value).contains(condition); - } - }, - - containsKey { - @Override - public boolean test(Object value, Object condition) { - preEvaluate(condition); - Preconditions.checkArgument(value instanceof Map); - return ((Map) value).containsKey(condition); - } - }, - - containsValue { - @Override - public boolean test(Object value, Object condition) { - preEvaluate(condition); - Preconditions.checkArgument(value instanceof Map); - return ((Map) value).containsValue(condition); - } - }, - - entryEq { - @Override - public boolean test(Object value, Object condition) { - preEvaluate(condition); - Preconditions.checkArgument(condition instanceof Pair); - Preconditions.checkArgument(value instanceof Map); - Pair pair = (Pair) condition; - Map map = (Map) value; - return Objects.equals(map.get(pair.getValue0()), pair.getValue1()); - } - }; - - @Override - public boolean isValidCondition(Object condition) { - if (condition instanceof Pair) { - Pair pair = (Pair) condition; - return pair.getValue0() != null && pair.getValue1() != null; - } - return condition != null; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/DefaultAsyncGraphResultSet.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/DefaultAsyncGraphResultSet.java deleted file mode 100644 index abc7cc9514e..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/DefaultAsyncGraphResultSet.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import com.datastax.dse.driver.api.core.graph.AsyncGraphResultSet; -import com.datastax.dse.driver.api.core.graph.GraphNode; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import com.datastax.oss.driver.internal.core.util.CountingIterator; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Queue; -import java.util.concurrent.CompletionStage; -import net.jcip.annotations.NotThreadSafe; - -@NotThreadSafe // wraps a mutable queue -public class DefaultAsyncGraphResultSet implements AsyncGraphResultSet { - - private final ExecutionInfo executionInfo; - private final CountingIterator iterator; - private final Iterable currentPage; - - public DefaultAsyncGraphResultSet( - ExecutionInfo executionInfo, Queue data, GraphProtocol graphProtocol) { - this.executionInfo = executionInfo; - this.iterator = new GraphResultIterator(data, graphProtocol); - this.currentPage = () -> iterator; - } - - @NonNull - @Override - public ExecutionInfo getRequestExecutionInfo() { - return executionInfo; - } - - @NonNull - @Override - @Deprecated - public com.datastax.dse.driver.api.core.graph.GraphExecutionInfo getExecutionInfo() { - return GraphExecutionInfoConverter.convert(executionInfo); - } - - @Override - public int remaining() { - return iterator.remaining(); - } - - @NonNull - @Override - public Iterable currentPage() { - return currentPage; - } - - @Override - public boolean hasMorePages() { - return false; - } - - @NonNull - @Override - public CompletionStage fetchNextPage() throws IllegalStateException { - throw new IllegalStateException( - "No next page. Use #hasMorePages before calling this method to avoid this error."); - } - - @Override - public void cancel() { - // nothing to do - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/DefaultBatchGraphStatement.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/DefaultBatchGraphStatement.java deleted file mode 100644 index 632d45e61d6..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/DefaultBatchGraphStatement.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import com.datastax.dse.driver.api.core.graph.BatchGraphStatement; -import com.datastax.oss.driver.api.core.ConsistencyLevel; -import com.datastax.oss.driver.api.core.RequestRoutingType; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.nio.ByteBuffer; -import java.time.Duration; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import net.jcip.annotations.Immutable; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; - -@Immutable -public class DefaultBatchGraphStatement extends GraphStatementBase - implements BatchGraphStatement { - - private final List traversals; - - public DefaultBatchGraphStatement( - Iterable traversals, - Boolean isIdempotent, - Duration timeout, - Node node, - long timestamp, - DriverExecutionProfile executionProfile, - String executionProfileName, - Map customPayload, - String graphName, - String traversalSource, - String subProtocol, - ConsistencyLevel consistencyLevel, - ConsistencyLevel readConsistencyLevel, - ConsistencyLevel writeConsistencyLevel) { - super( - isIdempotent, - timeout, - node, - timestamp, - executionProfile, - executionProfileName, - customPayload, - graphName, - traversalSource, - subProtocol, - consistencyLevel, - readConsistencyLevel, - writeConsistencyLevel); - this.traversals = ImmutableList.copyOf(traversals); - } - - @NonNull - @Override - public DefaultBatchGraphStatement addTraversal(@NonNull GraphTraversal newTraversal) { - return new DefaultBatchGraphStatement( - ImmutableList.builder().addAll(traversals).add(newTraversal).build(), - isIdempotent(), - getTimeout(), - getNode(), - getTimestamp(), - getExecutionProfile(), - getExecutionProfileName(), - getCustomPayload(), - getGraphName(), - getTraversalSource(), - getSubProtocol(), - getConsistencyLevel(), - getReadConsistencyLevel(), - getWriteConsistencyLevel()); - } - - @NonNull - @Override - public DefaultBatchGraphStatement addTraversals(@NonNull Iterable newTraversals) { - return new DefaultBatchGraphStatement( - ImmutableList.builder().addAll(traversals).addAll(newTraversals).build(), - isIdempotent(), - getTimeout(), - getNode(), - getTimestamp(), - getExecutionProfile(), - getExecutionProfileName(), - getCustomPayload(), - getGraphName(), - getTraversalSource(), - getSubProtocol(), - getConsistencyLevel(), - getReadConsistencyLevel(), - getWriteConsistencyLevel()); - } - - @Override - public int size() { - return this.traversals.size(); - } - - @Override - protected BatchGraphStatement newInstance( - Boolean isIdempotent, - Duration timeout, - Node node, - long timestamp, - DriverExecutionProfile executionProfile, - String executionProfileName, - Map customPayload, - String graphName, - String traversalSource, - String subProtocol, - ConsistencyLevel consistencyLevel, - ConsistencyLevel readConsistencyLevel, - ConsistencyLevel writeConsistencyLevel) { - return new DefaultBatchGraphStatement( - traversals, - isIdempotent, - timeout, - node, - timestamp, - executionProfile, - executionProfileName, - customPayload, - graphName, - traversalSource, - subProtocol, - consistencyLevel, - readConsistencyLevel, - writeConsistencyLevel); - } - - @NonNull - @Override - public Iterator iterator() { - return this.traversals.iterator(); - } - - @NonNull - @Override - public RequestRoutingType getRequestRoutingType() { - return RequestRoutingType.REGULAR; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/DefaultDseRemoteConnectionBuilder.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/DefaultDseRemoteConnectionBuilder.java deleted file mode 100644 index 146e8e17ea2..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/DefaultDseRemoteConnectionBuilder.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import com.datastax.dse.driver.api.core.graph.DseGraphRemoteConnectionBuilder; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import net.jcip.annotations.NotThreadSafe; -import org.apache.tinkerpop.gremlin.process.remote.RemoteConnection; - -@NotThreadSafe -public class DefaultDseRemoteConnectionBuilder implements DseGraphRemoteConnectionBuilder { - - private final CqlSession session; - private DriverExecutionProfile executionProfile; - private String executionProfileName; - - public DefaultDseRemoteConnectionBuilder(CqlSession session) { - this.session = session; - } - - @Override - public RemoteConnection build() { - return new DseGraphRemoteConnection(session, executionProfile, executionProfileName); - } - - @Override - public DseGraphRemoteConnectionBuilder withExecutionProfile( - DriverExecutionProfile executionProfile) { - this.executionProfile = executionProfile; - return this; - } - - @Override - public DseGraphRemoteConnectionBuilder withExecutionProfileName(String executionProfileName) { - this.executionProfileName = executionProfileName; - return this; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/DefaultFluentGraphStatement.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/DefaultFluentGraphStatement.java deleted file mode 100644 index 44fa9e41853..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/DefaultFluentGraphStatement.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import com.datastax.dse.driver.api.core.graph.FluentGraphStatement; -import com.datastax.oss.driver.api.core.ConsistencyLevel; -import com.datastax.oss.driver.api.core.RequestRoutingType; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.metadata.Node; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.nio.ByteBuffer; -import java.time.Duration; -import java.util.Map; -import net.jcip.annotations.Immutable; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; - -@Immutable -public class DefaultFluentGraphStatement extends GraphStatementBase - implements FluentGraphStatement { - - private final GraphTraversal traversal; - - public DefaultFluentGraphStatement( - GraphTraversal traversal, - Boolean isIdempotent, - Duration timeout, - Node node, - long timestamp, - DriverExecutionProfile executionProfile, - String executionProfileName, - Map customPayload, - String graphName, - String traversalSource, - String subProtocol, - ConsistencyLevel consistencyLevel, - ConsistencyLevel readConsistencyLevel, - ConsistencyLevel writeConsistencyLevel) { - super( - isIdempotent, - timeout, - node, - timestamp, - executionProfile, - executionProfileName, - customPayload, - graphName, - traversalSource, - subProtocol, - consistencyLevel, - readConsistencyLevel, - writeConsistencyLevel); - this.traversal = traversal; - } - - @Override - protected FluentGraphStatement newInstance( - Boolean isIdempotent, - Duration timeout, - Node node, - long timestamp, - DriverExecutionProfile executionProfile, - String executionProfileName, - Map customPayload, - String graphName, - String traversalSource, - String subProtocol, - ConsistencyLevel consistencyLevel, - ConsistencyLevel readConsistencyLevel, - ConsistencyLevel writeConsistencyLevel) { - return new DefaultFluentGraphStatement( - traversal, - isIdempotent, - timeout, - node, - timestamp, - executionProfile, - executionProfileName, - customPayload, - graphName, - traversalSource, - subProtocol, - consistencyLevel, - readConsistencyLevel, - writeConsistencyLevel); - } - - @NonNull - @Override - public GraphTraversal getTraversal() { - return traversal; - } - - @NonNull - @Override - public RequestRoutingType getRequestRoutingType() { - return RequestRoutingType.REGULAR; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/DefaultScriptGraphStatement.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/DefaultScriptGraphStatement.java deleted file mode 100644 index 587e1221b41..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/DefaultScriptGraphStatement.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import com.datastax.dse.driver.api.core.graph.ScriptGraphStatement; -import com.datastax.oss.driver.api.core.ConsistencyLevel; -import com.datastax.oss.driver.api.core.RequestRoutingType; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.datastax.oss.protocol.internal.util.collection.NullAllowingImmutableMap; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.nio.ByteBuffer; -import java.time.Duration; -import java.util.Map; -import net.jcip.annotations.Immutable; - -@Immutable -public class DefaultScriptGraphStatement extends GraphStatementBase - implements ScriptGraphStatement { - - private final String script; - private final Boolean isSystemQuery; - private final NullAllowingImmutableMap queryParams; - - public DefaultScriptGraphStatement( - String script, - Map queryParams, - Boolean isSystemQuery, - Boolean isIdempotent, - Duration timeout, - Node node, - long timestamp, - DriverExecutionProfile executionProfile, - String executionProfileName, - Map customPayload, - String graphName, - String traversalSource, - String subProtocol, - ConsistencyLevel consistencyLevel, - ConsistencyLevel readConsistencyLevel, - ConsistencyLevel writeConsistencyLevel) { - super( - isIdempotent, - timeout, - node, - timestamp, - executionProfile, - executionProfileName, - customPayload, - graphName, - traversalSource, - subProtocol, - consistencyLevel, - readConsistencyLevel, - writeConsistencyLevel); - this.script = script; - this.isSystemQuery = isSystemQuery; - this.queryParams = NullAllowingImmutableMap.copyOf(queryParams); - } - - //// Script GraphStatement level options - - @NonNull - @Override - public String getScript() { - return script; - } - - @NonNull - @Override - public ScriptGraphStatement setSystemQuery(@Nullable Boolean newValue) { - return new DefaultScriptGraphStatement( - script, - queryParams, - newValue, - isIdempotent(), - getTimeout(), - getNode(), - getTimestamp(), - getExecutionProfile(), - getExecutionProfileName(), - getCustomPayload(), - getGraphName(), - getTraversalSource(), - getSubProtocol(), - getConsistencyLevel(), - getReadConsistencyLevel(), - getWriteConsistencyLevel()); - } - - @Nullable - @Override - public Boolean isSystemQuery() { - return isSystemQuery; - } - - @NonNull - @Override - public Map getQueryParams() { - return this.queryParams; - } - - @NonNull - @Override - public ScriptGraphStatement setQueryParam(@NonNull String name, @Nullable Object value) { - NullAllowingImmutableMap.Builder newQueryParamsBuilder = - NullAllowingImmutableMap.builder(); - for (Map.Entry entry : queryParams.entrySet()) { - if (!entry.getKey().equals(name)) { - newQueryParamsBuilder.put(entry.getKey(), entry.getValue()); - } - } - newQueryParamsBuilder.put(name, value); - return setQueryParams(newQueryParamsBuilder.build()); - } - - @NonNull - @Override - public ScriptGraphStatement removeQueryParam(@NonNull String name) { - if (!queryParams.containsKey(name)) { - return this; - } else { - NullAllowingImmutableMap.Builder newQueryParamsBuilder = - NullAllowingImmutableMap.builder(); - for (Map.Entry entry : queryParams.entrySet()) { - if (!entry.getKey().equals(name)) { - newQueryParamsBuilder.put(entry.getKey(), entry.getValue()); - } - } - return setQueryParams(newQueryParamsBuilder.build()); - } - } - - private ScriptGraphStatement setQueryParams(Map newQueryParams) { - return new DefaultScriptGraphStatement( - script, - newQueryParams, - isSystemQuery, - isIdempotent(), - getTimeout(), - getNode(), - getTimestamp(), - getExecutionProfile(), - getExecutionProfileName(), - getCustomPayload(), - getGraphName(), - getTraversalSource(), - getSubProtocol(), - getConsistencyLevel(), - getReadConsistencyLevel(), - getWriteConsistencyLevel()); - } - - @Override - protected ScriptGraphStatement newInstance( - Boolean isIdempotent, - Duration timeout, - Node node, - long timestamp, - DriverExecutionProfile executionProfile, - String executionProfileName, - Map customPayload, - String graphName, - String traversalSource, - String subProtocol, - ConsistencyLevel consistencyLevel, - ConsistencyLevel readConsistencyLevel, - ConsistencyLevel writeConsistencyLevel) { - return new DefaultScriptGraphStatement( - script, - queryParams, - isSystemQuery, - isIdempotent, - timeout, - node, - timestamp, - executionProfile, - executionProfileName, - customPayload, - graphName, - traversalSource, - subProtocol, - consistencyLevel, - readConsistencyLevel, - writeConsistencyLevel); - } - - @Override - public String toString() { - return String.format("ScriptGraphStatement['%s', params: %s]", this.script, this.queryParams); - } - - @NonNull - @Override - public RequestRoutingType getRequestRoutingType() { - return RequestRoutingType.REGULAR; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/DseGraphRemoteConnection.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/DseGraphRemoteConnection.java deleted file mode 100644 index a5ec0a1d115..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/DseGraphRemoteConnection.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import java.util.concurrent.CompletableFuture; -import net.jcip.annotations.Immutable; -import org.apache.tinkerpop.gremlin.process.remote.RemoteConnection; -import org.apache.tinkerpop.gremlin.process.remote.traversal.RemoteTraversal; -import org.apache.tinkerpop.gremlin.process.traversal.Bytecode; - -@Immutable -public class DseGraphRemoteConnection implements RemoteConnection { - - private final CqlSession session; - private final DriverExecutionProfile executionProfile; - private final String executionProfileName; - - public DseGraphRemoteConnection( - CqlSession session, DriverExecutionProfile executionProfile, String executionProfileName) { - this.session = session; - this.executionProfile = executionProfile; - this.executionProfileName = executionProfileName; - } - - @Override - public CompletableFuture> submitAsync(Bytecode bytecode) { - return session - .executeAsync(new BytecodeGraphStatement(bytecode, executionProfile, executionProfileName)) - .toCompletableFuture() - .thenApply(DseGraphTraversal::new); - } - - @Override - public void close() throws Exception { - // do not close the DseSession here. - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/DseGraphTraversal.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/DseGraphTraversal.java deleted file mode 100644 index e0a5cf2d675..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/DseGraphTraversal.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import com.datastax.dse.driver.api.core.graph.AsyncGraphResultSet; -import com.datastax.dse.driver.api.core.graph.GraphNode; -import java.util.Iterator; -import java.util.NoSuchElementException; -import net.jcip.annotations.NotThreadSafe; -import org.apache.tinkerpop.gremlin.process.remote.traversal.AbstractRemoteTraversal; -import org.apache.tinkerpop.gremlin.process.remote.traversal.DefaultRemoteTraverser; -import org.apache.tinkerpop.gremlin.process.traversal.Traverser; - -@NotThreadSafe -class DseGraphTraversal extends AbstractRemoteTraversal { - - private final Iterator graphNodeIterator; - - public DseGraphTraversal(AsyncGraphResultSet firstPage) { - this.graphNodeIterator = GraphResultSets.toSync(firstPage).iterator(); - } - - @Override - public boolean hasNext() { - return graphNodeIterator.hasNext(); - } - - @Override - public E next() { - return nextTraverser().get(); - } - - @Override - @SuppressWarnings("unchecked") - public Traverser.Admin nextTraverser() { - if (hasNext()) { - GraphNode nextGraphNode = graphNodeIterator.next(); - - // get the Raw object from the ObjectGraphNode, create a new remote Traverser - // with bulk = 1 because bulk is not supported yet. Casting should be ok - // because we have been able to deserialize into the right type. - return new DefaultRemoteTraverser<>((E) nextGraphNode.as(Object.class), 1); - } else { - // finished iterating/nothing to iterate. Normal behaviour. - throw new NoSuchElementException(); - } - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/DsePredicate.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/DsePredicate.java deleted file mode 100644 index b5f8c30fd8c..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/DsePredicate.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import com.datastax.oss.driver.shaded.guava.common.base.Preconditions; -import java.util.function.BiPredicate; - -/** - * An extension of TinkerPop's {@link BiPredicate} adding simple pre-condition checking methods that - * have to be written in the implementations. - */ -public interface DsePredicate extends BiPredicate { - - default void preEvaluate(Object condition) { - Preconditions.checkArgument( - this.isValidCondition(condition), "Invalid condition provided: %s", condition); - } - - boolean isValidCondition(Object condition); -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/EditDistance.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/EditDistance.java deleted file mode 100644 index 5ab836babbf..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/EditDistance.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import com.datastax.oss.driver.shaded.guava.common.base.Objects; -import com.datastax.oss.driver.shaded.guava.common.base.Preconditions; -import java.io.Serializable; -import net.jcip.annotations.Immutable; - -/** - * A container for a term and maximum edit distance. - * - *

The context in which this is used determines the semantics of the edit distance. For instance, - * it might indicate single-character edits if used with fuzzy search queries or whole word - * movements if used with phrase proximity queries. - */ -@Immutable -public class EditDistance implements Serializable { - - private static final long serialVersionUID = 1L; - - public static final int DEFAULT_EDIT_DISTANCE = 0; - - public final String query; - public final int distance; - - public EditDistance(String query) { - this(query, DEFAULT_EDIT_DISTANCE); - } - - public EditDistance(String query, int distance) { - Preconditions.checkNotNull(query, "Query cannot be null."); - Preconditions.checkArgument(distance >= 0, "Edit distance cannot be negative."); - this.query = query; - this.distance = distance; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof EditDistance)) { - return false; - } - EditDistance that = (EditDistance) o; - return distance == that.distance && Objects.equal(query, that.query); - } - - @Override - public int hashCode() { - return Objects.hashCode(query, distance); - } - - @Override - public String toString() { - return "EditDistance{" + "query='" + query + '\'' + ", distance=" + distance + '}'; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GeoPredicate.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GeoPredicate.java deleted file mode 100644 index 39949e97198..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GeoPredicate.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import com.datastax.dse.driver.api.core.data.geometry.Geometry; -import com.datastax.dse.driver.api.core.data.geometry.LineString; -import com.datastax.dse.driver.api.core.data.geometry.Point; -import com.datastax.dse.driver.api.core.data.geometry.Polygon; -import com.datastax.dse.driver.api.core.graph.predicates.Geo; -import com.datastax.dse.driver.internal.core.data.geometry.Distance; -import com.datastax.oss.driver.shaded.guava.common.base.Preconditions; - -/** - * List of predicates for geolocation usage with DseGraph and Search indexes. Should not be accessed - * directly but through the {@link Geo} static methods. - */ -public enum GeoPredicate implements DsePredicate { - - /** Matches values within the distance specified by the condition over a Haversine geometry. */ - inside { - @Override - public boolean test(Object value, Object condition) { - preEvaluate(condition); - if (value == null) { - return false; - } - Preconditions.checkArgument(value instanceof Geometry); - Distance distance = (Distance) condition; - if (value instanceof Point) { - return haversineDistanceInDegrees(distance.getCenter(), (Point) value) - <= distance.getRadius(); - } else if (value instanceof Polygon) { - for (Point point : ((Polygon) value).getExteriorRing()) { - if (haversineDistanceInDegrees(distance.getCenter(), point) > distance.getRadius()) { - return false; - } - } - } else if (value instanceof LineString) { - for (Point point : ((LineString) value).getPoints()) { - if (haversineDistanceInDegrees(distance.getCenter(), point) > distance.getRadius()) { - return false; - } - } - } else { - throw new UnsupportedOperationException( - String.format("Value type '%s' unsupported", value.getClass().getName())); - } - - return true; - } - - @Override - public String toString() { - return "inside"; - } - }, - - /** - * Matches values contained in the geometric entity specified by the condition on a 2D Euclidean - * plane. - */ - insideCartesian { - @Override - public boolean test(Object value, Object condition) { - preEvaluate(condition); - if (value == null) { - return false; - } - Preconditions.checkArgument(value instanceof Geometry); - return ((Geometry) condition).contains((Geometry) value); - } - - @Override - public String toString() { - return "insideCartesian"; - } - }; - - @Override - public boolean isValidCondition(Object condition) { - return condition != null; - } - - static double haversineDistanceInDegrees(Point p1, Point p2) { - double dLat = Math.toRadians(p2.Y() - p1.Y()); - double dLon = Math.toRadians(p2.X() - p1.X()); - double lat1 = Math.toRadians(p1.Y()); - double lat2 = Math.toRadians(p2.Y()); - - double a = - Math.pow(Math.sin(dLat / 2), 2) - + Math.pow(Math.sin(dLon / 2), 2) * Math.cos(lat1) * Math.cos(lat2); - double c = 2 * Math.asin(Math.sqrt(a)); - return Math.toDegrees(c); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GeoUtils.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GeoUtils.java deleted file mode 100644 index 80d55dac69d..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GeoUtils.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -public class GeoUtils { - private static final double DEGREES_TO_RADIANS = Math.PI / 180; - private static final double EARTH_MEAN_RADIUS_KM = 6371.0087714; - private static final double DEG_TO_KM = DEGREES_TO_RADIANS * EARTH_MEAN_RADIUS_KM; - private static final double KM_TO_MILES = 0.621371192; - public static final double KM_TO_DEG = 1 / DEG_TO_KM; - public static final double MILES_TO_KM = 1 / KM_TO_MILES; -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphConversions.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphConversions.java deleted file mode 100644 index c95b26b2e26..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphConversions.java +++ /dev/null @@ -1,410 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import static java.nio.charset.StandardCharsets.UTF_8; - -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.dse.driver.api.core.graph.BatchGraphStatement; -import com.datastax.dse.driver.api.core.graph.FluentGraphStatement; -import com.datastax.dse.driver.api.core.graph.GraphNode; -import com.datastax.dse.driver.api.core.graph.GraphStatement; -import com.datastax.dse.driver.api.core.graph.ScriptGraphStatement; -import com.datastax.dse.driver.internal.core.graph.binary.GraphBinaryModule; -import com.datastax.dse.driver.internal.core.graph.binary.buffer.DseNettyBufferFactory; -import com.datastax.dse.protocol.internal.request.RawBytesQuery; -import com.datastax.dse.protocol.internal.request.query.ContinuousPagingOptions; -import com.datastax.dse.protocol.internal.request.query.DseQueryOptions; -import com.datastax.oss.driver.api.core.ConsistencyLevel; -import com.datastax.oss.driver.api.core.DefaultConsistencyLevel; -import com.datastax.oss.driver.api.core.ProtocolVersion; -import com.datastax.oss.driver.api.core.config.DefaultDriverOption; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.cql.Statement; -import com.datastax.oss.driver.api.core.type.codec.TypeCodecs; -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import com.datastax.oss.driver.internal.core.cql.Conversions; -import com.datastax.oss.driver.shaded.guava.common.annotations.VisibleForTesting; -import com.datastax.oss.driver.shaded.guava.common.base.Preconditions; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import com.datastax.oss.driver.shaded.guava.common.collect.Iterators; -import com.datastax.oss.protocol.internal.Message; -import com.datastax.oss.protocol.internal.ProtocolConstants; -import com.datastax.oss.protocol.internal.request.Query; -import com.datastax.oss.protocol.internal.util.collection.NullAllowingImmutableMap; -import io.netty.buffer.ByteBuf; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.ByteBuffer; -import java.time.Duration; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import org.apache.tinkerpop.gremlin.process.traversal.Traverser; -import org.apache.tinkerpop.gremlin.structure.io.Buffer; -import org.apache.tinkerpop.gremlin.structure.io.BufferFactory; - -/** - * Utility class to move boilerplate out of {@link GraphRequestHandler}. - * - *

We extend {@link Conversions} only for methods that can be directly reused as-is; if something - * needs to be customized, it will be duplicated here instead of making the parent method - * "pluggable". - */ -public class GraphConversions extends Conversions { - - static final String GRAPH_LANG_OPTION_KEY = "graph-language"; - static final String GRAPH_NAME_OPTION_KEY = "graph-name"; - static final String GRAPH_SOURCE_OPTION_KEY = "graph-source"; - static final String GRAPH_READ_CONSISTENCY_LEVEL_OPTION_KEY = "graph-read-consistency"; - static final String GRAPH_WRITE_CONSISTENCY_LEVEL_OPTION_KEY = "graph-write-consistency"; - static final String GRAPH_RESULTS_OPTION_KEY = "graph-results"; - static final String GRAPH_TIMEOUT_OPTION_KEY = "request-timeout"; - static final String GRAPH_BINARY_QUERY_OPTION_KEY = "graph-binary-query"; - - static final String LANGUAGE_GROOVY = "gremlin-groovy"; - static final String LANGUAGE_BYTECODE = "bytecode-json"; - - private static final BufferFactory FACTORY = new DseNettyBufferFactory(); - - @VisibleForTesting static final byte[] EMPTY_STRING_QUERY = "".getBytes(UTF_8); - - public static Message createContinuousMessageFromGraphStatement( - GraphStatement statement, - GraphProtocol subProtocol, - DriverExecutionProfile config, - InternalDriverContext context, - GraphBinaryModule graphBinaryModule) { - - final List encodedQueryParams; - if (!(statement instanceof ScriptGraphStatement) - || ((ScriptGraphStatement) statement).getQueryParams().isEmpty()) { - encodedQueryParams = Collections.emptyList(); - } else { - try { - Map queryParams = ((ScriptGraphStatement) statement).getQueryParams(); - if (subProtocol.isGraphBinary()) { - Buffer graphBinaryParams = graphBinaryModule.serialize(queryParams); - encodedQueryParams = Collections.singletonList(graphBinaryParams.nioBuffer()); - graphBinaryParams.release(); - } else { - encodedQueryParams = - Collections.singletonList( - GraphSONUtils.serializeToByteBuffer(queryParams, subProtocol)); - } - } catch (IOException e) { - throw new UncheckedIOException( - "Couldn't serialize parameters for GraphStatement: " + statement, e); - } - } - - int consistencyLevel = - DefaultConsistencyLevel.valueOf(config.getString(DefaultDriverOption.REQUEST_CONSISTENCY)) - .getProtocolCode(); - - long timestamp = statement.getTimestamp(); - if (timestamp == Statement.NO_DEFAULT_TIMESTAMP) { - timestamp = context.getTimestampGenerator().next(); - } - - int pageSize = config.getInt(DseDriverOption.GRAPH_CONTINUOUS_PAGING_PAGE_SIZE); - int maxPages = config.getInt(DseDriverOption.GRAPH_CONTINUOUS_PAGING_MAX_PAGES); - int maxPagesPerSecond = - config.getInt(DseDriverOption.GRAPH_CONTINUOUS_PAGING_MAX_PAGES_PER_SECOND); - int maxEnqueuedPages = - config.getInt(DseDriverOption.GRAPH_CONTINUOUS_PAGING_MAX_ENQUEUED_PAGES); - ContinuousPagingOptions options = - new ContinuousPagingOptions(maxPages, maxPagesPerSecond, maxEnqueuedPages); - - DseQueryOptions queryOptions = - new DseQueryOptions( - consistencyLevel, - encodedQueryParams, - Collections.emptyMap(), // ignored by the DSE Graph server - true, // also ignored - pageSize, - null, - ProtocolConstants.ConsistencyLevel.LOCAL_SERIAL, // also ignored - timestamp, - null, // also ignored - false, // graph CP does not support sizeInBytes - options); - - if (statement instanceof ScriptGraphStatement) { - return new Query(((ScriptGraphStatement) statement).getScript(), queryOptions); - } else { - return new RawBytesQuery(getQueryBytes(statement, subProtocol), queryOptions); - } - } - - static Message createMessageFromGraphStatement( - GraphStatement statement, - GraphProtocol subProtocol, - DriverExecutionProfile config, - InternalDriverContext context, - GraphBinaryModule graphBinaryModule) { - - final List encodedQueryParams; - if (!(statement instanceof ScriptGraphStatement) - || ((ScriptGraphStatement) statement).getQueryParams().isEmpty()) { - encodedQueryParams = Collections.emptyList(); - } else { - try { - Map queryParams = ((ScriptGraphStatement) statement).getQueryParams(); - if (subProtocol.isGraphBinary()) { - Buffer graphBinaryParams = graphBinaryModule.serialize(queryParams); - encodedQueryParams = Collections.singletonList(graphBinaryParams.nioBuffer()); - graphBinaryParams.release(); - } else { - encodedQueryParams = - Collections.singletonList( - GraphSONUtils.serializeToByteBuffer(queryParams, subProtocol)); - } - } catch (IOException e) { - throw new UncheckedIOException( - "Couldn't serialize parameters for GraphStatement: " + statement, e); - } - } - - ConsistencyLevel consistency = statement.getConsistencyLevel(); - int consistencyLevel = - (consistency == null) - ? context - .getConsistencyLevelRegistry() - .nameToCode(config.getString(DefaultDriverOption.REQUEST_CONSISTENCY)) - : consistency.getProtocolCode(); - - long timestamp = statement.getTimestamp(); - if (timestamp == Statement.NO_DEFAULT_TIMESTAMP) { - timestamp = context.getTimestampGenerator().next(); - } - - DseQueryOptions queryOptions = - new DseQueryOptions( - consistencyLevel, - encodedQueryParams, - Collections.emptyMap(), // ignored by the DSE Graph server - true, // also ignored - 50, // also ignored - null, // also ignored - ProtocolConstants.ConsistencyLevel.LOCAL_SERIAL, // also ignored - timestamp, - null, // also ignored - false, // also ignored - null // also ignored - ); - - if (statement instanceof ScriptGraphStatement) { - return new Query(((ScriptGraphStatement) statement).getScript(), queryOptions); - } else { - return new RawBytesQuery(getQueryBytes(statement, subProtocol), queryOptions); - } - } - - // This method returns either a Bytecode object, or a List if the statement is a - // BatchGraphStatement - @VisibleForTesting - public static Object bytecodeToSerialize(GraphStatement statement) { - Preconditions.checkArgument( - statement instanceof FluentGraphStatement - || statement instanceof BatchGraphStatement - || statement instanceof BytecodeGraphStatement, - "To serialize bytecode the query must be a fluent or batch statement, but was: %s", - statement.getClass()); - - Object toSerialize; - if (statement instanceof FluentGraphStatement) { - toSerialize = ((FluentGraphStatement) statement).getTraversal().asAdmin().getBytecode(); - } else if (statement instanceof BatchGraphStatement) { - // transform the Iterator to List - toSerialize = - ImmutableList.copyOf( - Iterators.transform( - ((BatchGraphStatement) statement).iterator(), - traversal -> traversal.asAdmin().getBytecode())); - } else { - toSerialize = ((BytecodeGraphStatement) statement).getBytecode(); - } - return toSerialize; - } - - private static byte[] getQueryBytes(GraphStatement statement, GraphProtocol graphSubProtocol) { - try { - return graphSubProtocol.isGraphBinary() - // if GraphBinary, the query is encoded in the custom payload, and not in the query field - // see GraphConversions#createCustomPayload() - ? EMPTY_STRING_QUERY - : GraphSONUtils.serializeToBytes(bytecodeToSerialize(statement), graphSubProtocol); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - - public static Map createCustomPayload( - GraphStatement statement, - GraphProtocol subProtocol, - DriverExecutionProfile config, - InternalDriverContext context, - GraphBinaryModule graphBinaryModule) { - - ProtocolVersion protocolVersion = context.getProtocolVersion(); - - NullAllowingImmutableMap.Builder payload = - NullAllowingImmutableMap.builder(); - Map statementOptions = statement.getCustomPayload(); - payload.putAll(statementOptions); - - final String graphLanguage; - - // Don't override anything that's already provided at the statement level - if (!statementOptions.containsKey(GRAPH_LANG_OPTION_KEY)) { - graphLanguage = - statement instanceof ScriptGraphStatement ? LANGUAGE_GROOVY : LANGUAGE_BYTECODE; - payload.put(GRAPH_LANG_OPTION_KEY, TypeCodecs.TEXT.encode(graphLanguage, protocolVersion)); - } else { - graphLanguage = - TypeCodecs.TEXT.decode(statementOptions.get(GRAPH_LANG_OPTION_KEY), protocolVersion); - Preconditions.checkNotNull( - graphLanguage, "A null value was set for the graph-language custom payload key."); - } - - if (!isSystemQuery(statement, config)) { - if (!statementOptions.containsKey(GRAPH_NAME_OPTION_KEY)) { - String graphName = statement.getGraphName(); - if (graphName == null) { - graphName = config.getString(DseDriverOption.GRAPH_NAME, null); - } - if (graphName != null) { - payload.put(GRAPH_NAME_OPTION_KEY, TypeCodecs.TEXT.encode(graphName, protocolVersion)); - } - } - if (!statementOptions.containsKey(GRAPH_SOURCE_OPTION_KEY)) { - String traversalSource = statement.getTraversalSource(); - if (traversalSource == null) { - traversalSource = config.getString(DseDriverOption.GRAPH_TRAVERSAL_SOURCE, null); - } - if (traversalSource != null) { - payload.put( - GRAPH_SOURCE_OPTION_KEY, TypeCodecs.TEXT.encode(traversalSource, protocolVersion)); - } - } - } - - // the payload allows null entry values so doing a get directly here and checking for null - final ByteBuffer payloadInitialProtocol = statementOptions.get(GRAPH_RESULTS_OPTION_KEY); - if (payloadInitialProtocol == null) { - Preconditions.checkNotNull(subProtocol); - payload.put( - GRAPH_RESULTS_OPTION_KEY, - TypeCodecs.TEXT.encode(subProtocol.toInternalCode(), protocolVersion)); - } else { - subProtocol = - GraphProtocol.fromString(TypeCodecs.TEXT.decode(payloadInitialProtocol, protocolVersion)); - } - - if (subProtocol.isGraphBinary() && graphLanguage.equals(LANGUAGE_BYTECODE)) { - Object bytecodeQuery = bytecodeToSerialize(statement); - try { - Buffer bytecodeByteBuf = graphBinaryModule.serialize(bytecodeQuery); - payload.put(GRAPH_BINARY_QUERY_OPTION_KEY, bytecodeByteBuf.nioBuffer()); - bytecodeByteBuf.release(); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - - if (!statementOptions.containsKey(GRAPH_READ_CONSISTENCY_LEVEL_OPTION_KEY)) { - ConsistencyLevel readCl = statement.getReadConsistencyLevel(); - String readClString = - readCl != null - ? readCl.name() - : config.getString(DseDriverOption.GRAPH_READ_CONSISTENCY_LEVEL, null); - if (readClString != null) { - payload.put( - GRAPH_READ_CONSISTENCY_LEVEL_OPTION_KEY, - TypeCodecs.TEXT.encode(readClString, protocolVersion)); - } - } - - if (!statementOptions.containsKey(GRAPH_WRITE_CONSISTENCY_LEVEL_OPTION_KEY)) { - ConsistencyLevel writeCl = statement.getWriteConsistencyLevel(); - String writeClString = - writeCl != null - ? writeCl.name() - : config.getString(DseDriverOption.GRAPH_WRITE_CONSISTENCY_LEVEL, null); - if (writeClString != null) { - payload.put( - GRAPH_WRITE_CONSISTENCY_LEVEL_OPTION_KEY, - TypeCodecs.TEXT.encode(writeClString, protocolVersion)); - } - } - - if (!statementOptions.containsKey(GRAPH_TIMEOUT_OPTION_KEY)) { - Duration timeout = statement.getTimeout(); - if (timeout == null) { - timeout = config.getDuration(DseDriverOption.GRAPH_TIMEOUT, Duration.ZERO); - } - if (timeout != null && !timeout.isZero()) { - payload.put( - GRAPH_TIMEOUT_OPTION_KEY, - TypeCodecs.BIGINT.encode(timeout.toMillis(), protocolVersion)); - } - } - return payload.build(); - } - - private static boolean isSystemQuery(GraphStatement statement, DriverExecutionProfile config) { - if (statement instanceof ScriptGraphStatement) { - Boolean statementValue = ((ScriptGraphStatement) statement).isSystemQuery(); - if (statementValue != null) { - return statementValue; - } - } - return config.getBoolean(DseDriverOption.GRAPH_IS_SYSTEM_QUERY, false); - } - - public static GraphNode createGraphBinaryGraphNode( - List data, GraphBinaryModule graphBinaryModule) throws IOException { - // there should be only one column in the given row - Preconditions.checkArgument(data.size() == 1, "Invalid row given to deserialize"); - - Buffer toDeserialize = FACTORY.wrap(data.get(0)); - Object deserializedObject = graphBinaryModule.deserialize(toDeserialize); - toDeserialize.release(); - assert deserializedObject instanceof Traverser - : "Graph protocol error. Received object should be a Traverser but it is not."; - return new ObjectGraphNode(deserializedObject); - } - - public static Duration resolveGraphRequestTimeout( - GraphStatement statement, InternalDriverContext context) { - DriverExecutionProfile executionProfile = resolveExecutionProfile(statement, context); - return statement.getTimeout() != null - ? statement.getTimeout() - : executionProfile.getDuration(DseDriverOption.GRAPH_TIMEOUT); - } - - public static GraphProtocol resolveGraphSubProtocol( - GraphStatement statement, - GraphSupportChecker graphSupportChecker, - InternalDriverContext context) { - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(statement, context); - return graphSupportChecker.inferGraphProtocol(statement, executionProfile, context); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphExecutionInfoConverter.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphExecutionInfoConverter.java deleted file mode 100644 index b6472f690d3..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphExecutionInfoConverter.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import com.datastax.dse.driver.api.core.graph.GraphStatement; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import com.datastax.oss.driver.api.core.cql.QueryTrace; -import com.datastax.oss.driver.api.core.cql.Statement; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.datastax.oss.driver.api.core.session.Request; -import com.datastax.oss.driver.internal.core.util.concurrent.CompletableFutures; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.nio.ByteBuffer; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.UUID; -import java.util.concurrent.CompletionStage; - -/** - * Handles conversions from / to GraphExecutionInfo and ExecutionInfo since GraphExecutionInfo has - * been deprecated by JAVA-2556. - */ -public class GraphExecutionInfoConverter { - - /** - * Called exclusively from default methods in API interfaces {@link - * com.datastax.dse.driver.api.core.graph.GraphResultSet} and {@link - * com.datastax.dse.driver.api.core.graph.AsyncGraphResultSet}. Graph result set implementations - * do not use this method but rather the other one below. - */ - @SuppressWarnings("deprecation") - public static ExecutionInfo convert( - com.datastax.dse.driver.api.core.graph.GraphExecutionInfo graphExecutionInfo) { - return new ExecutionInfo() { - - @NonNull - @Override - public Request getRequest() { - return graphExecutionInfo.getStatement(); - } - - @NonNull - @Override - public Statement getStatement() { - throw new ClassCastException("GraphStatement cannot be cast to Statement"); - } - - @Nullable - @Override - public Node getCoordinator() { - return graphExecutionInfo.getCoordinator(); - } - - @Override - public int getSpeculativeExecutionCount() { - return graphExecutionInfo.getSpeculativeExecutionCount(); - } - - @Override - public int getSuccessfulExecutionIndex() { - return graphExecutionInfo.getSuccessfulExecutionIndex(); - } - - @NonNull - @Override - public List> getErrors() { - return graphExecutionInfo.getErrors(); - } - - @Nullable - @Override - public ByteBuffer getPagingState() { - return null; - } - - @NonNull - @Override - public List getWarnings() { - return graphExecutionInfo.getWarnings(); - } - - @NonNull - @Override - public Map getIncomingPayload() { - return graphExecutionInfo.getIncomingPayload(); - } - - @Override - public boolean isSchemaInAgreement() { - return true; - } - - @Nullable - @Override - public UUID getTracingId() { - return null; - } - - @NonNull - @Override - public CompletionStage getQueryTraceAsync() { - return CompletableFutures.failedFuture( - new IllegalStateException("Tracing was disabled for this request")); - } - - @Override - public int getResponseSizeInBytes() { - return -1; - } - - @Override - public int getCompressedResponseSizeInBytes() { - return -1; - } - }; - } - - /** - * Called from graph result set implementations, to convert the original {@link ExecutionInfo} - * produced by request handlers into the (deprecated) type GraphExecutionInfo. - */ - @SuppressWarnings("deprecation") - public static com.datastax.dse.driver.api.core.graph.GraphExecutionInfo convert( - ExecutionInfo executionInfo) { - return new com.datastax.dse.driver.api.core.graph.GraphExecutionInfo() { - - @Override - public GraphStatement getStatement() { - return (GraphStatement) executionInfo.getRequest(); - } - - @Override - public Node getCoordinator() { - return executionInfo.getCoordinator(); - } - - @Override - public int getSpeculativeExecutionCount() { - return executionInfo.getSpeculativeExecutionCount(); - } - - @Override - public int getSuccessfulExecutionIndex() { - return executionInfo.getSuccessfulExecutionIndex(); - } - - @Override - public List> getErrors() { - return executionInfo.getErrors(); - } - - @Override - public List getWarnings() { - return executionInfo.getWarnings(); - } - - @Override - public Map getIncomingPayload() { - return executionInfo.getIncomingPayload(); - } - }; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphProtocol.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphProtocol.java deleted file mode 100644 index 6b7a9f4c430..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphProtocol.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -public enum GraphProtocol { - GRAPHSON_1_0("graphson-1.0"), - GRAPHSON_2_0("graphson-2.0"), - GRAPH_BINARY_1_0("graph-binary-1.0"), - ; - - private static final Map BY_CODE; - - static { - Map tmp = new HashMap<>(); - for (GraphProtocol value : values()) { - tmp.put(value.stringRepresentation, value); - } - BY_CODE = Collections.unmodifiableMap(tmp); - } - - private final String stringRepresentation; - - GraphProtocol(String stringRepresentation) { - this.stringRepresentation = stringRepresentation; - } - - @NonNull - public String toInternalCode() { - return stringRepresentation; - } - - @NonNull - public static GraphProtocol fromString(@Nullable String stringRepresentation) { - if (stringRepresentation == null || !BY_CODE.containsKey(stringRepresentation)) { - StringBuilder sb = - new StringBuilder( - String.format( - "Graph protocol used [\"%s\"] unknown. Possible values are: [ \"%s\"", - stringRepresentation, GraphProtocol.values()[0].toInternalCode())); - for (int i = 1; i < GraphProtocol.values().length; i++) { - sb.append(String.format(", \"%s\"", GraphProtocol.values()[i].toInternalCode())); - } - sb.append("]"); - throw new IllegalArgumentException(sb.toString()); - } - return BY_CODE.get(stringRepresentation); - } - - public boolean isGraphBinary() { - return this == GRAPH_BINARY_1_0; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphRequestAsyncProcessor.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphRequestAsyncProcessor.java deleted file mode 100644 index 050b03c66f4..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphRequestAsyncProcessor.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import com.datastax.dse.driver.api.core.graph.AsyncGraphResultSet; -import com.datastax.dse.driver.api.core.graph.BatchGraphStatement; -import com.datastax.dse.driver.api.core.graph.FluentGraphStatement; -import com.datastax.dse.driver.api.core.graph.GraphStatement; -import com.datastax.dse.driver.api.core.graph.ScriptGraphStatement; -import com.datastax.dse.driver.internal.core.graph.binary.GraphBinaryModule; -import com.datastax.oss.driver.api.core.session.Request; -import com.datastax.oss.driver.api.core.type.reflect.GenericType; -import com.datastax.oss.driver.internal.core.context.DefaultDriverContext; -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import com.datastax.oss.driver.internal.core.session.DefaultSession; -import com.datastax.oss.driver.internal.core.session.RequestProcessor; -import com.datastax.oss.driver.internal.core.util.concurrent.CompletableFutures; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.concurrent.CompletionStage; -import net.jcip.annotations.ThreadSafe; -import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryReader; -import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryWriter; -import org.apache.tinkerpop.gremlin.structure.io.binary.TypeSerializerRegistry; - -@ThreadSafe -public class GraphRequestAsyncProcessor - implements RequestProcessor, CompletionStage> { - - private final GraphBinaryModule graphBinaryModule; - private final GraphSupportChecker graphSupportChecker; - - public GraphRequestAsyncProcessor( - DefaultDriverContext context, GraphSupportChecker graphSupportChecker) { - TypeSerializerRegistry typeSerializerRegistry = - GraphBinaryModule.createDseTypeSerializerRegistry(context); - this.graphBinaryModule = - new GraphBinaryModule( - new GraphBinaryReader(typeSerializerRegistry), - new GraphBinaryWriter(typeSerializerRegistry)); - this.graphSupportChecker = graphSupportChecker; - } - - @NonNull - public GraphBinaryModule getGraphBinaryModule() { - return graphBinaryModule; - } - - @Override - public boolean canProcess(Request request, GenericType resultType) { - return (request instanceof ScriptGraphStatement - || request instanceof FluentGraphStatement - || request instanceof BatchGraphStatement - || request instanceof BytecodeGraphStatement) - && resultType.equals(GraphStatement.ASYNC); - } - - @Override - public CompletionStage process( - GraphStatement request, - DefaultSession session, - InternalDriverContext context, - String sessionLogPrefix) { - - if (graphSupportChecker.isPagingEnabled(request, context)) { - return new ContinuousGraphRequestHandler( - request, - session, - context, - sessionLogPrefix, - getGraphBinaryModule(), - graphSupportChecker) - .handle(); - } else { - return new GraphRequestHandler( - request, - session, - context, - sessionLogPrefix, - getGraphBinaryModule(), - graphSupportChecker) - .handle(); - } - } - - @Override - public CompletionStage newFailure(RuntimeException error) { - return CompletableFutures.failedFuture(error); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphRequestHandler.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphRequestHandler.java deleted file mode 100644 index cf6875dd362..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphRequestHandler.java +++ /dev/null @@ -1,908 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import static com.datastax.oss.driver.api.core.DriverTimeoutException.UNAVAILABLE; - -import com.datastax.dse.driver.api.core.graph.AsyncGraphResultSet; -import com.datastax.dse.driver.api.core.graph.GraphNode; -import com.datastax.dse.driver.api.core.graph.GraphStatement; -import com.datastax.dse.driver.api.core.metrics.DseNodeMetric; -import com.datastax.dse.driver.api.core.metrics.DseSessionMetric; -import com.datastax.dse.driver.internal.core.graph.binary.GraphBinaryModule; -import com.datastax.oss.driver.api.core.AllNodesFailedException; -import com.datastax.oss.driver.api.core.DriverException; -import com.datastax.oss.driver.api.core.DriverTimeoutException; -import com.datastax.oss.driver.api.core.DriverTimeoutException.NodeDiagnostics; -import com.datastax.oss.driver.api.core.NodeUnavailableException; -import com.datastax.oss.driver.api.core.RequestThrottlingException; -import com.datastax.oss.driver.api.core.config.DefaultDriverOption; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.connection.FrameTooLongException; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.datastax.oss.driver.api.core.metrics.DefaultNodeMetric; -import com.datastax.oss.driver.api.core.metrics.DefaultSessionMetric; -import com.datastax.oss.driver.api.core.retry.RetryPolicy; -import com.datastax.oss.driver.api.core.retry.RetryVerdict; -import com.datastax.oss.driver.api.core.servererrors.BootstrappingException; -import com.datastax.oss.driver.api.core.servererrors.CoordinatorException; -import com.datastax.oss.driver.api.core.servererrors.FunctionFailureException; -import com.datastax.oss.driver.api.core.servererrors.ProtocolError; -import com.datastax.oss.driver.api.core.servererrors.QueryValidationException; -import com.datastax.oss.driver.api.core.servererrors.ReadTimeoutException; -import com.datastax.oss.driver.api.core.servererrors.UnavailableException; -import com.datastax.oss.driver.api.core.servererrors.WriteTimeoutException; -import com.datastax.oss.driver.api.core.session.throttling.RequestThrottler; -import com.datastax.oss.driver.api.core.session.throttling.Throttled; -import com.datastax.oss.driver.api.core.tracker.RequestTracker; -import com.datastax.oss.driver.internal.core.channel.DriverChannel; -import com.datastax.oss.driver.internal.core.channel.ResponseCallback; -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import com.datastax.oss.driver.internal.core.cql.Conversions; -import com.datastax.oss.driver.internal.core.cql.DefaultExecutionInfo; -import com.datastax.oss.driver.internal.core.metadata.DefaultNode; -import com.datastax.oss.driver.internal.core.metrics.NodeMetricUpdater; -import com.datastax.oss.driver.internal.core.metrics.SessionMetricUpdater; -import com.datastax.oss.driver.internal.core.pool.ChannelPool; -import com.datastax.oss.driver.internal.core.session.DefaultSession; -import com.datastax.oss.driver.internal.core.tracker.NoopRequestTracker; -import com.datastax.oss.driver.internal.core.tracker.RequestLogger; -import com.datastax.oss.driver.internal.core.util.Loggers; -import com.datastax.oss.driver.internal.core.util.collection.SimpleQueryPlan; -import com.datastax.oss.protocol.internal.Frame; -import com.datastax.oss.protocol.internal.Message; -import com.datastax.oss.protocol.internal.response.Error; -import com.datastax.oss.protocol.internal.response.Result; -import com.datastax.oss.protocol.internal.response.result.Rows; -import com.datastax.oss.protocol.internal.response.result.Void; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import io.netty.handler.codec.EncoderException; -import io.netty.util.Timeout; -import io.netty.util.Timer; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.GenericFutureListener; -import java.nio.ByteBuffer; -import java.time.Duration; -import java.util.AbstractMap; -import java.util.ArrayDeque; -import java.util.List; -import java.util.Map; -import java.util.Queue; -import java.util.concurrent.CancellationException; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import net.jcip.annotations.ThreadSafe; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@ThreadSafe -public class GraphRequestHandler implements Throttled { - - private static final Logger LOG = LoggerFactory.getLogger(GraphRequestHandler.class); - - private static final long NANOTIME_NOT_MEASURED_YET = -1; - private static final int NO_SUCCESSFUL_EXECUTION = -1; - - private final long startTimeNanos; - private final String logPrefix; - private final GraphStatement initialStatement; - private final DefaultSession session; - private final InternalDriverContext context; - protected final CompletableFuture result; - private final Timer timer; - - /** - * How many speculative executions are currently running (including the initial execution). We - * track this in order to know when to fail the request if all executions have reached the end of - * the query plan. - */ - private final AtomicInteger activeExecutionsCount; - - /** - * How many speculative executions have started (excluding the initial execution), whether they - * have completed or not. We track this in order to fill {@link - * ExecutionInfo#getSpeculativeExecutionCount()}. - */ - private final AtomicInteger startedSpeculativeExecutionsCount; - - private final Timeout scheduledTimeout; - private final List scheduledExecutions; - private final List inFlightCallbacks; - private final RequestThrottler throttler; - private final RequestTracker requestTracker; - private final SessionMetricUpdater sessionMetricUpdater; - private final GraphBinaryModule graphBinaryModule; - private final GraphSupportChecker graphSupportChecker; - - // The errors on the nodes that were already tried (lazily initialized on the first error). - // We don't use a map because nodes can appear multiple times. - private volatile List> errors; - - GraphRequestHandler( - @NonNull GraphStatement statement, - @NonNull DefaultSession dseSession, - @NonNull InternalDriverContext context, - @NonNull String sessionLogPrefix, - @NonNull GraphBinaryModule graphBinaryModule, - @NonNull GraphSupportChecker graphSupportChecker) { - this.startTimeNanos = System.nanoTime(); - this.logPrefix = sessionLogPrefix + "|" + this.hashCode(); - LOG.trace("[{}] Creating new Graph request handler for request {}", logPrefix, statement); - this.initialStatement = statement; - this.session = dseSession; - this.context = context; - this.graphSupportChecker = graphSupportChecker; - this.result = new CompletableFuture<>(); - this.result.exceptionally( - t -> { - try { - if (t instanceof CancellationException) { - cancelScheduledTasks(); - context.getRequestThrottler().signalCancel(this); - } - } catch (Throwable t2) { - Loggers.warnWithException(LOG, "[{}] Uncaught exception", logPrefix, t2); - } - return null; - }); - this.graphBinaryModule = graphBinaryModule; - this.timer = context.getNettyOptions().getTimer(); - - this.activeExecutionsCount = new AtomicInteger(1); - this.startedSpeculativeExecutionsCount = new AtomicInteger(0); - this.scheduledExecutions = new CopyOnWriteArrayList<>(); - this.inFlightCallbacks = new CopyOnWriteArrayList<>(); - - this.requestTracker = context.getRequestTracker(); - this.sessionMetricUpdater = session.getMetricUpdater(); - - Duration timeout = GraphConversions.resolveGraphRequestTimeout(statement, context); - this.scheduledTimeout = scheduleTimeout(timeout); - - this.throttler = context.getRequestThrottler(); - this.throttler.register(this); - } - - @Override - public void onThrottleReady(boolean wasDelayed) { - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(initialStatement, context); - if (wasDelayed - // avoid call to nanoTime() if metric is disabled: - && sessionMetricUpdater.isEnabled( - DefaultSessionMetric.THROTTLING_DELAY, executionProfile.getName())) { - sessionMetricUpdater.updateTimer( - DefaultSessionMetric.THROTTLING_DELAY, - executionProfile.getName(), - System.nanoTime() - startTimeNanos, - TimeUnit.NANOSECONDS); - } - Queue queryPlan = - initialStatement.getNode() != null - ? new SimpleQueryPlan(initialStatement.getNode()) - : context - .getLoadBalancingPolicyWrapper() - .newQueryPlan(initialStatement, executionProfile.getName(), session); - sendRequest(initialStatement, null, queryPlan, 0, 0, true); - } - - public CompletionStage handle() { - return result; - } - - private Timeout scheduleTimeout(Duration timeoutDuration) { - if (timeoutDuration != null && timeoutDuration.toNanos() > 0) { - try { - return this.timer.newTimeout( - (Timeout timeout1) -> { - NodeDiagnostics diagnostics = buildNodeDiagnostics(); - setFinalError( - initialStatement, - new DriverTimeoutException( - "Query timed out after " + timeoutDuration, diagnostics), - null, - NO_SUCCESSFUL_EXECUTION); - }, - timeoutDuration.toNanos(), - TimeUnit.NANOSECONDS); - } catch (IllegalStateException e) { - // If we raced with session shutdown the timer might be closed already, rethrow with a more - // explicit message - result.completeExceptionally( - "cannot be started once stopped".equals(e.getMessage()) - ? new IllegalStateException("Session is closed") - : e); - } - } - return null; - } - - @Nullable - private NodeDiagnostics buildNodeDiagnostics() { - List callbacks = inFlightCallbacks; - if (callbacks.isEmpty()) { - return null; - } - NodeResponseCallback cb = callbacks.get(0); - int channelInFlight = cb.channel.getInFlight(); - ChannelPool pool = session.getPools().get(cb.node); - return NodeDiagnostics.of( - cb.node.getEndPoint(), - cb.node.getState(), - cb.node.getDistance(), - cb.node.getDatacenter(), - channelInFlight, - pool != null ? pool.size() : UNAVAILABLE, - pool != null ? pool.getInFlight() : UNAVAILABLE, - pool != null ? pool.getAvailableIds() : UNAVAILABLE, - pool != null ? pool.getOrphanedIds() : UNAVAILABLE); - } - - /** - * Sends the request to the next available node. - * - * @param retriedNode if not null, it will be attempted first before the rest of the query plan. - * @param queryPlan the list of nodes to try (shared with all other executions) - * @param currentExecutionIndex 0 for the initial execution, 1 for the first speculative one, etc. - * @param retryCount the number of times that the retry policy was invoked for this execution - * already (note that some internal retries don't go through the policy, and therefore don't - * increment this counter) - * @param scheduleNextExecution whether to schedule the next speculative execution - */ - private void sendRequest( - GraphStatement statement, - Node retriedNode, - Queue queryPlan, - int currentExecutionIndex, - int retryCount, - boolean scheduleNextExecution) { - if (result.isDone()) { - return; - } - Node node = retriedNode; - DriverChannel channel = null; - if (node == null || (channel = session.getChannel(node, logPrefix)) == null) { - while (!result.isDone() && (node = queryPlan.poll()) != null) { - channel = session.getChannel(node, logPrefix); - if (channel != null) { - break; - } else { - recordError(node, new NodeUnavailableException(node)); - } - } - } - if (channel == null) { - // We've reached the end of the query plan without finding any node to write to - if (!result.isDone() && activeExecutionsCount.decrementAndGet() == 0) { - // We're the last execution so fail the result - setFinalError( - statement, - AllNodesFailedException.fromErrors(this.errors), - null, - NO_SUCCESSFUL_EXECUTION); - } - } else { - boolean writeSubmitted = false; - try { - NodeResponseCallback nodeResponseCallback = - new NodeResponseCallback( - statement, - node, - queryPlan, - channel, - currentExecutionIndex, - retryCount, - scheduleNextExecution, - logPrefix); - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(statement, context); - GraphProtocol graphSubProtocol = - GraphConversions.resolveGraphSubProtocol(statement, graphSupportChecker, context); - Message message = - GraphConversions.createMessageFromGraphStatement( - statement, graphSubProtocol, executionProfile, context, graphBinaryModule); - Map customPayload = - GraphConversions.createCustomPayload( - statement, graphSubProtocol, executionProfile, context, graphBinaryModule); - Future writeFuture = - channel.write(message, statement.isTracing(), customPayload, nodeResponseCallback); - writeSubmitted = true; - writeFuture.addListener(nodeResponseCallback); - } finally { - if (!writeSubmitted) { - channel.cancelPreAcquireId(); - } - } - } - } - - private void recordError(Node node, Throwable error) { - // Use a local variable to do only a single single volatile read in the nominal case - List> errorsSnapshot = this.errors; - if (errorsSnapshot == null) { - synchronized (GraphRequestHandler.this) { - errorsSnapshot = this.errors; - if (errorsSnapshot == null) { - this.errors = errorsSnapshot = new CopyOnWriteArrayList<>(); - } - } - } - errorsSnapshot.add(new AbstractMap.SimpleEntry<>(node, error)); - } - - private void cancelScheduledTasks() { - if (this.scheduledTimeout != null) { - this.scheduledTimeout.cancel(); - } - if (scheduledExecutions != null) { - for (Timeout scheduledExecution : scheduledExecutions) { - scheduledExecution.cancel(); - } - } - for (NodeResponseCallback callback : inFlightCallbacks) { - callback.cancel(); - } - } - - private void setFinalResult( - Result resultMessage, Frame responseFrame, NodeResponseCallback callback) { - try { - ExecutionInfo executionInfo = buildExecutionInfo(callback, responseFrame); - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(callback.statement, context); - GraphProtocol subProtocol = - GraphConversions.resolveGraphSubProtocol( - callback.statement, graphSupportChecker, context); - Queue graphNodes = new ArrayDeque<>(); - for (List row : ((Rows) resultMessage).getData()) { - if (subProtocol.isGraphBinary()) { - graphNodes.offer( - GraphConversions.createGraphBinaryGraphNode( - row, GraphRequestHandler.this.graphBinaryModule)); - } else { - graphNodes.offer(GraphSONUtils.createGraphNode(row, subProtocol)); - } - } - - DefaultAsyncGraphResultSet resultSet = - new DefaultAsyncGraphResultSet(executionInfo, graphNodes, subProtocol); - if (result.complete(resultSet)) { - cancelScheduledTasks(); - throttler.signalSuccess(this); - - // Only call nanoTime() if we're actually going to use it - long completionTimeNanos = NANOTIME_NOT_MEASURED_YET, - totalLatencyNanos = NANOTIME_NOT_MEASURED_YET; - if (!(requestTracker instanceof NoopRequestTracker)) { - completionTimeNanos = System.nanoTime(); - totalLatencyNanos = completionTimeNanos - startTimeNanos; - long nodeLatencyNanos = completionTimeNanos - callback.nodeStartTimeNanos; - requestTracker.onNodeSuccess( - callback.statement, nodeLatencyNanos, executionProfile, callback.node, logPrefix); - requestTracker.onSuccess( - callback.statement, totalLatencyNanos, executionProfile, callback.node, logPrefix); - } - if (sessionMetricUpdater.isEnabled( - DseSessionMetric.GRAPH_REQUESTS, executionProfile.getName())) { - if (completionTimeNanos == NANOTIME_NOT_MEASURED_YET) { - completionTimeNanos = System.nanoTime(); - totalLatencyNanos = completionTimeNanos - startTimeNanos; - } - sessionMetricUpdater.updateTimer( - DseSessionMetric.GRAPH_REQUESTS, - executionProfile.getName(), - totalLatencyNanos, - TimeUnit.NANOSECONDS); - } - } - // log the warnings if they have NOT been disabled - if (!executionInfo.getWarnings().isEmpty() - && executionProfile.getBoolean(DefaultDriverOption.REQUEST_LOG_WARNINGS) - && LOG.isWarnEnabled()) { - logServerWarnings(callback.statement, executionInfo.getWarnings()); - } - } catch (Throwable error) { - setFinalError(callback.statement, error, callback.node, NO_SUCCESSFUL_EXECUTION); - } - } - - private void logServerWarnings(GraphStatement statement, List warnings) { - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(statement, context); - // use the RequestLogFormatter to format the query - StringBuilder statementString = new StringBuilder(); - context - .getRequestLogFormatter() - .appendRequest( - statement, - executionProfile.getInt( - DefaultDriverOption.REQUEST_LOGGER_MAX_QUERY_LENGTH, - RequestLogger.DEFAULT_REQUEST_LOGGER_MAX_QUERY_LENGTH), - executionProfile.getBoolean( - DefaultDriverOption.REQUEST_LOGGER_VALUES, - RequestLogger.DEFAULT_REQUEST_LOGGER_SHOW_VALUES), - executionProfile.getInt( - DefaultDriverOption.REQUEST_LOGGER_MAX_VALUES, - RequestLogger.DEFAULT_REQUEST_LOGGER_MAX_VALUES), - executionProfile.getInt( - DefaultDriverOption.REQUEST_LOGGER_MAX_VALUE_LENGTH, - RequestLogger.DEFAULT_REQUEST_LOGGER_MAX_VALUE_LENGTH), - statementString); - // log each warning separately - warnings.forEach( - (warning) -> - LOG.warn("Query '{}' generated server side warning(s): {}", statementString, warning)); - } - - private ExecutionInfo buildExecutionInfo(NodeResponseCallback callback, Frame responseFrame) { - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(callback.statement, context); - return new DefaultExecutionInfo( - callback.statement, - callback.node, - startedSpeculativeExecutionsCount.get(), - callback.execution, - errors, - null, - responseFrame, - true, - session, - context, - executionProfile); - } - - @Override - public void onThrottleFailure(@NonNull RequestThrottlingException error) { - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(initialStatement, context); - sessionMetricUpdater.incrementCounter( - DefaultSessionMetric.THROTTLING_ERRORS, executionProfile.getName()); - setFinalError(initialStatement, error, null, NO_SUCCESSFUL_EXECUTION); - } - - private void setFinalError( - GraphStatement statement, Throwable error, Node node, int execution) { - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(statement, context); - if (error instanceof DriverException) { - ((DriverException) error) - .setExecutionInfo( - new DefaultExecutionInfo( - statement, - node, - startedSpeculativeExecutionsCount.get(), - execution, - errors, - null, - null, - true, - session, - context, - executionProfile)); - } - if (result.completeExceptionally(error)) { - cancelScheduledTasks(); - if (!(requestTracker instanceof NoopRequestTracker)) { - long latencyNanos = System.nanoTime() - startTimeNanos; - requestTracker.onError(statement, error, latencyNanos, executionProfile, node, logPrefix); - } - if (error instanceof DriverTimeoutException) { - throttler.signalTimeout(this); - sessionMetricUpdater.incrementCounter( - DseSessionMetric.GRAPH_CLIENT_TIMEOUTS, executionProfile.getName()); - } else if (!(error instanceof RequestThrottlingException)) { - throttler.signalError(this, error); - } - } - } - - /** - * Handles the interaction with a single node in the query plan. - * - *

An instance of this class is created each time we (re)try a node. - */ - private class NodeResponseCallback - implements ResponseCallback, GenericFutureListener> { - - private final long nodeStartTimeNanos = System.nanoTime(); - private final GraphStatement statement; - private final Node node; - private final Queue queryPlan; - private final DriverChannel channel; - // The identifier of the current execution (0 for the initial execution, 1 for the first - // speculative execution, etc.) - private final int execution; - // How many times we've invoked the retry policy and it has returned a "retry" decision (0 for - // the first attempt of each execution). - private final int retryCount; - private final boolean scheduleNextExecution; - private final String logPrefix; - private final DriverExecutionProfile executionProfile; - - private NodeResponseCallback( - GraphStatement statement, - Node node, - Queue queryPlan, - DriverChannel channel, - int execution, - int retryCount, - boolean scheduleNextExecution, - String logPrefix) { - this.statement = statement; - this.node = node; - this.queryPlan = queryPlan; - this.channel = channel; - this.execution = execution; - this.retryCount = retryCount; - this.scheduleNextExecution = scheduleNextExecution; - this.logPrefix = logPrefix + "|" + execution; - this.executionProfile = Conversions.resolveExecutionProfile(statement, context); - } - - // this gets invoked once the write completes. - @Override - public void operationComplete(Future future) { - if (!future.isSuccess()) { - Throwable error = future.cause(); - if (error instanceof EncoderException - && error.getCause() instanceof FrameTooLongException) { - trackNodeError(node, error.getCause(), NANOTIME_NOT_MEASURED_YET); - setFinalError(statement, error.getCause(), node, execution); - } else { - LOG.trace( - "[{}] Failed to send request on {}, trying next node (cause: {})", - logPrefix, - channel, - error); - recordError(node, error); - trackNodeError(node, error, NANOTIME_NOT_MEASURED_YET); - ((DefaultNode) node) - .getMetricUpdater() - .incrementCounter(DefaultNodeMetric.UNSENT_REQUESTS, executionProfile.getName()); - sendRequest( - statement, - null, - queryPlan, - execution, - retryCount, - scheduleNextExecution); // try next node - } - } else { - LOG.trace("[{}] Request sent on {}", logPrefix, channel); - if (result.isDone()) { - // If the handler completed since the last time we checked, cancel directly because we - // don't know if cancelScheduledTasks() has run yet - cancel(); - } else { - inFlightCallbacks.add(this); - if (scheduleNextExecution - && Conversions.resolveIdempotence(statement, executionProfile)) { - int nextExecution = execution + 1; - long nextDelay; - try { - nextDelay = - Conversions.resolveSpeculativeExecutionPolicy(context, executionProfile) - .nextExecution(node, null, statement, nextExecution); - } catch (Throwable cause) { - // This is a bug in the policy, but not fatal since we have at least one other - // execution already running. Don't fail the whole request. - LOG.error( - "[{}] Unexpected error while invoking the speculative execution policy", - logPrefix, - cause); - return; - } - if (nextDelay >= 0) { - scheduleSpeculativeExecution(nextExecution, nextDelay); - } else { - LOG.trace( - "[{}] Speculative execution policy returned {}, no next execution", - logPrefix, - nextDelay); - } - } - } - } - } - - private void scheduleSpeculativeExecution(int index, long delay) { - LOG.trace("[{}] Scheduling speculative execution {} in {} ms", logPrefix, index, delay); - try { - scheduledExecutions.add( - timer.newTimeout( - (Timeout timeout1) -> { - if (!result.isDone()) { - LOG.trace( - "[{}] Starting speculative execution {}", - GraphRequestHandler.this.logPrefix, - index); - activeExecutionsCount.incrementAndGet(); - startedSpeculativeExecutionsCount.incrementAndGet(); - // Note that `node` is the first node of the execution, it might not be the - // "slow" one if there were retries, but in practice retries are rare. - ((DefaultNode) node) - .getMetricUpdater() - .incrementCounter( - DefaultNodeMetric.SPECULATIVE_EXECUTIONS, executionProfile.getName()); - sendRequest(statement, null, queryPlan, index, 0, true); - } - }, - delay, - TimeUnit.MILLISECONDS)); - } catch (IllegalStateException e) { - // If we're racing with session shutdown, the timer might be stopped already. We don't want - // to schedule more executions anyway, so swallow the error. - if (!"cannot be started once stopped".equals(e.getMessage())) { - Loggers.warnWithException( - LOG, "[{}] Error while scheduling speculative execution", logPrefix, e); - } - } - } - - @Override - public void onResponse(Frame responseFrame) { - long nodeResponseTimeNanos = NANOTIME_NOT_MEASURED_YET; - NodeMetricUpdater nodeMetricUpdater = ((DefaultNode) node).getMetricUpdater(); - if (nodeMetricUpdater.isEnabled(DseNodeMetric.GRAPH_MESSAGES, executionProfile.getName())) { - nodeResponseTimeNanos = System.nanoTime(); - long nodeLatency = System.nanoTime() - nodeStartTimeNanos; - nodeMetricUpdater.updateTimer( - DseNodeMetric.GRAPH_MESSAGES, - executionProfile.getName(), - nodeLatency, - TimeUnit.NANOSECONDS); - } - inFlightCallbacks.remove(this); - if (result.isDone()) { - return; - } - try { - Message responseMessage = responseFrame.message; - if (responseMessage instanceof Result) { - LOG.trace("[{}] Got result, completing", logPrefix); - setFinalResult((Result) responseMessage, responseFrame, this); - } else if (responseMessage instanceof Error) { - LOG.trace("[{}] Got error response, processing", logPrefix); - processErrorResponse((Error) responseMessage); - } else { - trackNodeError( - node, - new IllegalStateException("Unexpected response " + responseMessage), - nodeResponseTimeNanos); - setFinalError( - statement, - new IllegalStateException("Unexpected response " + responseMessage), - node, - execution); - } - } catch (Throwable t) { - trackNodeError(node, t, nodeResponseTimeNanos); - setFinalError(statement, t, node, execution); - } - } - - private void processErrorResponse(Error errorMessage) { - CoordinatorException error = Conversions.toThrowable(node, errorMessage, context); - NodeMetricUpdater metricUpdater = ((DefaultNode) node).getMetricUpdater(); - if (error instanceof BootstrappingException) { - LOG.trace("[{}] {} is bootstrapping, trying next node", logPrefix, node); - recordError(node, error); - trackNodeError(node, error, NANOTIME_NOT_MEASURED_YET); - sendRequest(statement, null, queryPlan, execution, retryCount, false); - } else if (error instanceof QueryValidationException - || error instanceof FunctionFailureException - || error instanceof ProtocolError) { - LOG.trace("[{}] Unrecoverable error, rethrowing", logPrefix); - metricUpdater.incrementCounter(DefaultNodeMetric.OTHER_ERRORS, executionProfile.getName()); - trackNodeError(node, error, NANOTIME_NOT_MEASURED_YET); - setFinalError(statement, error, node, execution); - } else { - RetryPolicy retryPolicy = Conversions.resolveRetryPolicy(context, executionProfile); - RetryVerdict verdict; - if (error instanceof ReadTimeoutException) { - ReadTimeoutException readTimeout = (ReadTimeoutException) error; - verdict = - retryPolicy.onReadTimeoutVerdict( - statement, - readTimeout.getConsistencyLevel(), - readTimeout.getBlockFor(), - readTimeout.getReceived(), - readTimeout.wasDataPresent(), - retryCount); - updateErrorMetrics( - metricUpdater, - verdict, - DefaultNodeMetric.READ_TIMEOUTS, - DefaultNodeMetric.RETRIES_ON_READ_TIMEOUT, - DefaultNodeMetric.IGNORES_ON_READ_TIMEOUT); - } else if (error instanceof WriteTimeoutException) { - WriteTimeoutException writeTimeout = (WriteTimeoutException) error; - verdict = - Conversions.resolveIdempotence(statement, executionProfile) - ? retryPolicy.onWriteTimeoutVerdict( - statement, - writeTimeout.getConsistencyLevel(), - writeTimeout.getWriteType(), - writeTimeout.getBlockFor(), - writeTimeout.getReceived(), - retryCount) - : RetryVerdict.RETHROW; - updateErrorMetrics( - metricUpdater, - verdict, - DefaultNodeMetric.WRITE_TIMEOUTS, - DefaultNodeMetric.RETRIES_ON_WRITE_TIMEOUT, - DefaultNodeMetric.IGNORES_ON_WRITE_TIMEOUT); - } else if (error instanceof UnavailableException) { - UnavailableException unavailable = (UnavailableException) error; - verdict = - retryPolicy.onUnavailableVerdict( - statement, - unavailable.getConsistencyLevel(), - unavailable.getRequired(), - unavailable.getAlive(), - retryCount); - updateErrorMetrics( - metricUpdater, - verdict, - DefaultNodeMetric.UNAVAILABLES, - DefaultNodeMetric.RETRIES_ON_UNAVAILABLE, - DefaultNodeMetric.IGNORES_ON_UNAVAILABLE); - } else { - verdict = - Conversions.resolveIdempotence(statement, executionProfile) - ? retryPolicy.onErrorResponseVerdict(statement, error, retryCount) - : RetryVerdict.RETHROW; - updateErrorMetrics( - metricUpdater, - verdict, - DefaultNodeMetric.OTHER_ERRORS, - DefaultNodeMetric.RETRIES_ON_OTHER_ERROR, - DefaultNodeMetric.IGNORES_ON_OTHER_ERROR); - } - processRetryVerdict(verdict, error); - } - } - - private void processRetryVerdict(RetryVerdict verdict, Throwable error) { - LOG.trace("[{}] Processing retry decision {}", logPrefix, verdict); - switch (verdict.getRetryDecision()) { - case RETRY_SAME: - recordError(node, error); - trackNodeError(node, error, NANOTIME_NOT_MEASURED_YET); - sendRequest( - verdict.getRetryRequest(statement), - node, - queryPlan, - execution, - retryCount + 1, - false); - break; - case RETRY_NEXT: - recordError(node, error); - trackNodeError(node, error, NANOTIME_NOT_MEASURED_YET); - sendRequest( - verdict.getRetryRequest(statement), - null, - queryPlan, - execution, - retryCount + 1, - false); - break; - case RETHROW: - trackNodeError(node, error, NANOTIME_NOT_MEASURED_YET); - setFinalError(statement, error, node, execution); - break; - case IGNORE: - setFinalResult(Void.INSTANCE, null, this); - break; - } - } - - private void updateErrorMetrics( - NodeMetricUpdater metricUpdater, - RetryVerdict verdict, - DefaultNodeMetric error, - DefaultNodeMetric retriesOnError, - DefaultNodeMetric ignoresOnError) { - metricUpdater.incrementCounter(error, executionProfile.getName()); - switch (verdict.getRetryDecision()) { - case RETRY_SAME: - case RETRY_NEXT: - metricUpdater.incrementCounter(DefaultNodeMetric.RETRIES, executionProfile.getName()); - metricUpdater.incrementCounter(retriesOnError, executionProfile.getName()); - break; - case IGNORE: - metricUpdater.incrementCounter(DefaultNodeMetric.IGNORES, executionProfile.getName()); - metricUpdater.incrementCounter(ignoresOnError, executionProfile.getName()); - break; - case RETHROW: - // nothing do do - } - } - - @Override - public void onFailure(Throwable error) { - inFlightCallbacks.remove(this); - if (result.isDone()) { - return; - } - LOG.trace("[{}] Request failure, processing: {}", logPrefix, error); - RetryVerdict verdict; - if (!Conversions.resolveIdempotence(statement, executionProfile) - || error instanceof FrameTooLongException) { - verdict = RetryVerdict.RETHROW; - } else { - try { - RetryPolicy retryPolicy = Conversions.resolveRetryPolicy(context, executionProfile); - verdict = retryPolicy.onRequestAbortedVerdict(statement, error, retryCount); - } catch (Throwable cause) { - setFinalError( - statement, - new IllegalStateException("Unexpected error while invoking the retry policy", cause), - node, - NO_SUCCESSFUL_EXECUTION); - return; - } - } - processRetryVerdict(verdict, error); - updateErrorMetrics( - ((DefaultNode) node).getMetricUpdater(), - verdict, - DefaultNodeMetric.ABORTED_REQUESTS, - DefaultNodeMetric.RETRIES_ON_ABORTED, - DefaultNodeMetric.IGNORES_ON_ABORTED); - } - - void cancel() { - try { - if (!channel.closeFuture().isDone()) { - this.channel.cancel(this); - } - } catch (Throwable t) { - Loggers.warnWithException(LOG, "[{}] Error cancelling", logPrefix, t); - } - } - - /** - * @param nodeResponseTimeNanos the time we received the response, if it's already been - * measured. If {@link #NANOTIME_NOT_MEASURED_YET}, it hasn't and we need to measure it now - * (this is to avoid unnecessary calls to System.nanoTime) - */ - private void trackNodeError(Node node, Throwable error, long nodeResponseTimeNanos) { - if (requestTracker instanceof NoopRequestTracker) { - return; - } - if (nodeResponseTimeNanos == NANOTIME_NOT_MEASURED_YET) { - nodeResponseTimeNanos = System.nanoTime(); - } - long latencyNanos = nodeResponseTimeNanos - this.nodeStartTimeNanos; - requestTracker.onNodeError(statement, error, latencyNanos, executionProfile, node, logPrefix); - } - - @Override - public String toString() { - return logPrefix; - } - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphRequestSyncProcessor.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphRequestSyncProcessor.java deleted file mode 100644 index bc2381482a8..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphRequestSyncProcessor.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import com.datastax.dse.driver.api.core.graph.AsyncGraphResultSet; -import com.datastax.dse.driver.api.core.graph.BatchGraphStatement; -import com.datastax.dse.driver.api.core.graph.FluentGraphStatement; -import com.datastax.dse.driver.api.core.graph.GraphResultSet; -import com.datastax.dse.driver.api.core.graph.GraphStatement; -import com.datastax.dse.driver.api.core.graph.ScriptGraphStatement; -import com.datastax.oss.driver.api.core.session.Request; -import com.datastax.oss.driver.api.core.type.reflect.GenericType; -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import com.datastax.oss.driver.internal.core.session.DefaultSession; -import com.datastax.oss.driver.internal.core.session.RequestProcessor; -import com.datastax.oss.driver.internal.core.util.concurrent.BlockingOperation; -import com.datastax.oss.driver.internal.core.util.concurrent.CompletableFutures; -import net.jcip.annotations.ThreadSafe; - -@ThreadSafe -public class GraphRequestSyncProcessor - implements RequestProcessor, GraphResultSet> { - - private final GraphRequestAsyncProcessor asyncProcessor; - - public GraphRequestSyncProcessor(GraphRequestAsyncProcessor asyncProcessor) { - this.asyncProcessor = asyncProcessor; - } - - @Override - public boolean canProcess(Request request, GenericType resultType) { - return (request instanceof ScriptGraphStatement - || request instanceof FluentGraphStatement - || request instanceof BatchGraphStatement - || request instanceof BytecodeGraphStatement) - && resultType.equals(GraphStatement.SYNC); - } - - @Override - public GraphResultSet process( - GraphStatement request, - DefaultSession session, - InternalDriverContext context, - String sessionLogPrefix) { - BlockingOperation.checkNotDriverThread(); - AsyncGraphResultSet firstPage = - CompletableFutures.getUninterruptibly( - asyncProcessor.process(request, session, context, sessionLogPrefix)); - return GraphResultSets.toSync(firstPage); - } - - @Override - public GraphResultSet newFailure(RuntimeException error) { - throw error; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphResultIterator.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphResultIterator.java deleted file mode 100644 index 7e9043affec..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphResultIterator.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import com.datastax.dse.driver.api.core.graph.GraphNode; -import com.datastax.oss.driver.internal.core.util.CountingIterator; -import com.datastax.oss.driver.shaded.guava.common.base.Preconditions; -import java.util.Queue; -import net.jcip.annotations.NotThreadSafe; -import org.apache.tinkerpop.gremlin.process.traversal.Traverser; - -@NotThreadSafe // wraps a mutable queue -class GraphResultIterator extends CountingIterator { - - private final Queue data; - private final GraphProtocol graphProtocol; - - // Sometimes a traversal can yield the same result multiple times consecutively. To avoid - // duplicating the data, DSE graph sends it only once with a counter indicating how many times - // it's repeated. - private long repeat = 0; - private GraphNode lastGraphNode = null; - - GraphResultIterator(Queue data, GraphProtocol graphProtocol) { - super(data.size()); - this.data = data; - this.graphProtocol = graphProtocol; - } - - @Override - protected GraphNode computeNext() { - if (repeat > 1) { - repeat -= 1; - // Note that we don't make a defensive copy, we assume the client won't mutate the node - return lastGraphNode; - } - - GraphNode container = data.poll(); - if (container == null) { - return endOfData(); - } - - if (graphProtocol.isGraphBinary()) { - // results are contained in a Traverser object and not a Map if the protocol - // is GraphBinary - Preconditions.checkState( - container.as(Object.class) instanceof Traverser, - "Graph protocol error. Received object should be a Traverser but it is not."); - Traverser t = container.as(Traverser.class); - this.repeat = t.bulk(); - this.lastGraphNode = new ObjectGraphNode(t.get()); - return lastGraphNode; - } else { - // The repeat counter is called "bulk" in the JSON payload - GraphNode b = container.getByKey("bulk"); - if (b != null) { - this.repeat = b.asLong(); - } - - lastGraphNode = container.getByKey("result"); - return lastGraphNode; - } - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphResultSets.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphResultSets.java deleted file mode 100644 index fb21f857cfa..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphResultSets.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import com.datastax.dse.driver.api.core.graph.AsyncGraphResultSet; -import com.datastax.dse.driver.api.core.graph.GraphResultSet; - -public class GraphResultSets { - - public static GraphResultSet toSync(AsyncGraphResultSet firstPage) { - if (firstPage.hasMorePages()) { - return new MultiPageGraphResultSet(firstPage); - } else { - return new SinglePageGraphResultSet(firstPage); - } - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphSON1SerdeTP.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphSON1SerdeTP.java deleted file mode 100644 index f880bca3764..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphSON1SerdeTP.java +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import com.datastax.dse.driver.api.core.data.geometry.Geometry; -import com.datastax.dse.driver.api.core.data.geometry.LineString; -import com.datastax.dse.driver.api.core.data.geometry.Point; -import com.datastax.dse.driver.api.core.data.geometry.Polygon; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import com.datastax.oss.driver.shaded.guava.common.net.InetAddresses; -import java.io.IOException; -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.util.List; -import java.util.Map; -import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator; -import org.apache.tinkerpop.shaded.jackson.core.JsonParseException; -import org.apache.tinkerpop.shaded.jackson.core.JsonParser; -import org.apache.tinkerpop.shaded.jackson.core.Version; -import org.apache.tinkerpop.shaded.jackson.databind.DeserializationContext; -import org.apache.tinkerpop.shaded.jackson.databind.JsonDeserializer; -import org.apache.tinkerpop.shaded.jackson.databind.JsonSerializer; -import org.apache.tinkerpop.shaded.jackson.databind.SerializerProvider; -import org.apache.tinkerpop.shaded.jackson.databind.deser.std.StdDeserializer; -import org.apache.tinkerpop.shaded.jackson.databind.module.SimpleModule; -import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer; - -public class GraphSON1SerdeTP { - - //////////////////////// DESERIALIZERS //////////////////////// - - /** - * Default deserializer used by the driver for {@link InetAddress} instances. The actual subclass - * returned by this deserializer depends on the type of address: {@link Inet4Address IPV4} or - * {@link Inet6Address IPV6}. - */ - static class DefaultInetAddressDeserializer extends StdDeserializer { - - private static final long serialVersionUID = 1L; - - private final Class inetClass; - - DefaultInetAddressDeserializer(Class inetClass) { - super(inetClass); - this.inetClass = inetClass; - } - - @Override - public T deserialize(JsonParser parser, DeserializationContext ctx) throws IOException { - String ip = parser.readValueAs(String.class); - try { - InetAddress inet = InetAddresses.forString(ip); - return inetClass.cast(inet); - } catch (ClassCastException e) { - throw new JsonParseException( - parser, - String.format("Inet address cannot be cast to %s: %s", inetClass.getSimpleName(), ip), - e); - } catch (IllegalArgumentException e) { - throw new JsonParseException(parser, String.format("Expected inet address, got %s", ip), e); - } - } - } - - /** - * Default deserializer used by the driver for geospatial types. It deserializes such types into - * {@link Geometry} instances. The actual subclass depends on the type being deserialized. - */ - static class DefaultGeometryDeserializer extends StdDeserializer { - - private static final long serialVersionUID = 1L; - - private final Class geometryClass; - - DefaultGeometryDeserializer(Class geometryClass) { - super(geometryClass); - this.geometryClass = geometryClass; - } - - @Override - public T deserialize(JsonParser parser, DeserializationContext ctx) throws IOException { - String wkt = parser.readValueAs(String.class); - Geometry geometry; - if (wkt.startsWith("POINT")) geometry = Point.fromWellKnownText(wkt); - else if (wkt.startsWith("LINESTRING")) geometry = LineString.fromWellKnownText(wkt); - else if (wkt.startsWith("POLYGON")) geometry = Polygon.fromWellKnownText(wkt); - else throw new JsonParseException(parser, "Unknown geometry type: " + wkt); - return geometryClass.cast(geometry); - } - } - - /** Base class for serializing the {@code java.time.*} types to ISO-8061 formats. */ - abstract static class AbstractJavaTimeSerializer extends StdSerializer { - - private static final long serialVersionUID = 1L; - - AbstractJavaTimeSerializer(final Class clazz) { - super(clazz); - } - - @Override - public void serialize( - final T value, final JsonGenerator gen, final SerializerProvider serializerProvider) - throws IOException { - gen.writeString(value.toString()); - } - } - - /** Base class for deserializing the {@code java.time.*} types from ISO-8061 formats. */ - abstract static class AbstractJavaTimeJacksonDeserializer extends StdDeserializer { - - private static final long serialVersionUID = 1L; - - AbstractJavaTimeJacksonDeserializer(final Class clazz) { - super(clazz); - } - - abstract T parse(final String val); - - @Override - public T deserialize( - final JsonParser jsonParser, final DeserializationContext deserializationContext) - throws IOException { - return parse(jsonParser.getText()); - } - } - - static final class DurationJacksonSerializer - extends AbstractJavaTimeSerializer { - - private static final long serialVersionUID = 1L; - - DurationJacksonSerializer() { - super(java.time.Duration.class); - } - } - - static final class DurationJacksonDeserializer - extends AbstractJavaTimeJacksonDeserializer { - - private static final long serialVersionUID = 1L; - - DurationJacksonDeserializer() { - super(java.time.Duration.class); - } - - @Override - public java.time.Duration parse(final String val) { - return java.time.Duration.parse(val); - } - } - - static final class InstantJacksonSerializer - extends AbstractJavaTimeSerializer { - - private static final long serialVersionUID = 1L; - - InstantJacksonSerializer() { - super(java.time.Instant.class); - } - } - - static final class InstantJacksonDeserializer - extends AbstractJavaTimeJacksonDeserializer { - - private static final long serialVersionUID = 1L; - - InstantJacksonDeserializer() { - super(java.time.Instant.class); - } - - @Override - public java.time.Instant parse(final String val) { - return java.time.Instant.parse(val); - } - } - - static final class LocalDateJacksonSerializer - extends AbstractJavaTimeSerializer { - - private static final long serialVersionUID = 1L; - - LocalDateJacksonSerializer() { - super(java.time.LocalDate.class); - } - } - - static final class LocalDateJacksonDeserializer - extends AbstractJavaTimeJacksonDeserializer { - - private static final long serialVersionUID = 1L; - - LocalDateJacksonDeserializer() { - super(java.time.LocalDate.class); - } - - @Override - public java.time.LocalDate parse(final String val) { - return java.time.LocalDate.parse(val); - } - } - - static final class LocalTimeJacksonSerializer - extends AbstractJavaTimeSerializer { - - private static final long serialVersionUID = 1L; - - LocalTimeJacksonSerializer() { - super(java.time.LocalTime.class); - } - } - - static final class LocalTimeJacksonDeserializer - extends AbstractJavaTimeJacksonDeserializer { - - private static final long serialVersionUID = 1L; - - LocalTimeJacksonDeserializer() { - super(java.time.LocalTime.class); - } - - @Override - public java.time.LocalTime parse(final String val) { - return java.time.LocalTime.parse(val); - } - } - - //////////////////////// SERIALIZERS //////////////////////// - - /** Default serializer used by the driver for {@link LegacyGraphNode} instances. */ - static class DefaultGraphNodeSerializer extends StdSerializer { - - private static final long serialVersionUID = 1L; - - DefaultGraphNodeSerializer() { - super(LegacyGraphNode.class); - } - - @Override - public void serialize( - LegacyGraphNode value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) - throws IOException { - jsonGenerator.writeTree(value.getDelegate()); - } - } - - /** - * Default serializer used by the driver for geospatial types. It serializes {@link Geometry} - * instances into their Well-Known Text (WKT) equivalent. - */ - static class DefaultGeometrySerializer extends StdSerializer { - - private static final long serialVersionUID = 1L; - - DefaultGeometrySerializer() { - super(Geometry.class); - } - - @Override - public void serialize( - Geometry value, JsonGenerator jsonGenerator, SerializerProvider serializers) - throws IOException { - jsonGenerator.writeString(value.asWellKnownText()); - } - } - - /** The default Jackson module used by DSE Graph. */ - static class GraphSON1DefaultModule extends SimpleModule { - - private static final long serialVersionUID = 1L; - - GraphSON1DefaultModule(String name, Version version) { - super(name, version, createDeserializers(), createSerializers()); - } - - private static Map, JsonDeserializer> createDeserializers() { - - return ImmutableMap., JsonDeserializer>builder() - - // Inet (there is no built-in deserializer for InetAddress and subclasses) - .put(InetAddress.class, new DefaultInetAddressDeserializer<>(InetAddress.class)) - .put(Inet4Address.class, new DefaultInetAddressDeserializer<>(Inet4Address.class)) - .put(Inet6Address.class, new DefaultInetAddressDeserializer<>(Inet6Address.class)) - - // Geospatial types - .put(Geometry.class, new DefaultGeometryDeserializer<>(Geometry.class)) - .put(Point.class, new DefaultGeometryDeserializer<>(Point.class)) - .put(LineString.class, new DefaultGeometryDeserializer<>(LineString.class)) - .put(Polygon.class, new DefaultGeometryDeserializer<>(Polygon.class)) - .build(); - } - - private static List> createSerializers() { - return ImmutableList.>builder() - .add(new DefaultGraphNodeSerializer()) - .add(new DefaultGeometrySerializer()) - .build(); - } - } - - /** Serializers and deserializers for JSR 310 {@code java.time.*}. */ - static class GraphSON1JavaTimeModule extends SimpleModule { - - private static final long serialVersionUID = 1L; - - GraphSON1JavaTimeModule(String name, Version version) { - super(name, version, createDeserializers(), createSerializers()); - } - - private static Map, JsonDeserializer> createDeserializers() { - - return ImmutableMap., JsonDeserializer>builder() - .put(java.time.Duration.class, new DurationJacksonDeserializer()) - .put(java.time.Instant.class, new InstantJacksonDeserializer()) - .put(java.time.LocalDate.class, new LocalDateJacksonDeserializer()) - .put(java.time.LocalTime.class, new LocalTimeJacksonDeserializer()) - .build(); - } - - private static List> createSerializers() { - return ImmutableList.>builder() - .add(new DurationJacksonSerializer()) - .add(new InstantJacksonSerializer()) - .add(new LocalDateJacksonSerializer()) - .add(new LocalTimeJacksonSerializer()) - .build(); - } - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphSON2SerdeTP.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphSON2SerdeTP.java deleted file mode 100644 index 05e09b018ab..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphSON2SerdeTP.java +++ /dev/null @@ -1,430 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import com.datastax.dse.driver.api.core.data.geometry.Geometry; -import com.datastax.dse.driver.api.core.data.geometry.LineString; -import com.datastax.dse.driver.api.core.data.geometry.Point; -import com.datastax.dse.driver.api.core.data.geometry.Polygon; -import com.datastax.dse.driver.api.core.graph.predicates.Geo; -import com.datastax.dse.driver.api.core.graph.predicates.Search; -import com.datastax.dse.driver.internal.core.data.geometry.DefaultLineString; -import com.datastax.dse.driver.internal.core.data.geometry.DefaultPoint; -import com.datastax.dse.driver.internal.core.data.geometry.DefaultPolygon; -import com.datastax.dse.driver.internal.core.data.geometry.Distance; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import java.io.IOException; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.apache.tinkerpop.gremlin.process.traversal.P; -import org.apache.tinkerpop.gremlin.process.traversal.util.AndP; -import org.apache.tinkerpop.gremlin.process.traversal.util.ConnectiveP; -import org.apache.tinkerpop.gremlin.process.traversal.util.OrP; -import org.apache.tinkerpop.gremlin.structure.io.graphson.AbstractObjectDeserializer; -import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTokens; -import org.apache.tinkerpop.gremlin.structure.io.graphson.TinkerPopJacksonModule; -import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator; -import org.apache.tinkerpop.shaded.jackson.core.JsonParser; -import org.apache.tinkerpop.shaded.jackson.databind.DeserializationContext; -import org.apache.tinkerpop.shaded.jackson.databind.SerializerProvider; -import org.apache.tinkerpop.shaded.jackson.databind.deser.std.StdDeserializer; -import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer; -import org.apache.tinkerpop.shaded.jackson.databind.module.SimpleModule; -import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdScalarSerializer; -import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer; - -public class GraphSON2SerdeTP { - - /** - * A Jackson Module to use for TinkerPop serialization/deserialization. It extends {@link - * org.apache.tinkerpop.gremlin.structure.io.graphson.TinkerPopJacksonModule} because of the - * specific typing format used in GraphSON. - */ - public static class DseGraphModule extends TinkerPopJacksonModule { - - private static final long serialVersionUID = 1L; - - public DseGraphModule() { - super("dse-driver-2.0"); - addSerializer(DefaultPoint.class, new PointGeometrySerializer()); - addSerializer(DefaultLineString.class, new LineStringGeometrySerializer()); - addSerializer(DefaultPolygon.class, new PolygonGeometrySerializer()); - addSerializer(Distance.class, new DistanceGeometrySerializer()); - // override TinkerPop's P predicates because of DSE's Search and Geo predicates - addSerializer(P.class, new DsePJacksonSerializer()); - addSerializer(EditDistance.class, new EditDistanceSerializer()); - - addDeserializer(DefaultLineString.class, new LineStringGeometryDeserializer()); - addDeserializer(DefaultPoint.class, new PointGeometryDeserializer()); - addDeserializer(DefaultPolygon.class, new PolygonGeometryDeserializer()); - addDeserializer(Distance.class, new DistanceGeometryDeserializer()); - // override TinkerPop's P predicates because of DSE's Search and Geo predicates - addDeserializer(P.class, new DsePJacksonDeserializer()); - } - - @SuppressWarnings("rawtypes") - @Override - public Map getTypeDefinitions() { - Map definitions = new HashMap<>(); - definitions.put(DefaultLineString.class, "LineString"); - definitions.put(DefaultPoint.class, "Point"); - definitions.put(DefaultPolygon.class, "Polygon"); - definitions.put(byte[].class, "Blob"); - definitions.put(Distance.class, "Distance"); - definitions.put(P.class, "P"); - return definitions; - } - - @Override - public String getTypeNamespace() { - return "dse"; - } - - abstract static class AbstractGeometryJacksonDeserializer - extends StdDeserializer { - - private static final long serialVersionUID = 1L; - - AbstractGeometryJacksonDeserializer(final Class clazz) { - super(clazz); - } - - public abstract T parse(final String val); - - @Override - public T deserialize( - final JsonParser jsonParser, final DeserializationContext deserializationContext) - throws IOException { - return parse(jsonParser.getText()); - } - } - - abstract static class AbstractGeometryJacksonSerializer - extends StdScalarSerializer { - - private static final long serialVersionUID = 1L; - - AbstractGeometryJacksonSerializer(final Class clazz) { - super(clazz); - } - - @Override - public void serialize( - final T value, final JsonGenerator gen, final SerializerProvider serializerProvider) - throws IOException { - gen.writeString(value.asWellKnownText()); - } - } - - public static class LineStringGeometrySerializer - extends AbstractGeometryJacksonSerializer { - - private static final long serialVersionUID = 1L; - - LineStringGeometrySerializer() { - super(LineString.class); - } - } - - public static class LineStringGeometryDeserializer - extends AbstractGeometryJacksonDeserializer { - - private static final long serialVersionUID = 1L; - - LineStringGeometryDeserializer() { - super(DefaultLineString.class); - } - - @Override - public DefaultLineString parse(final String val) { - return (DefaultLineString) LineString.fromWellKnownText(val); - } - } - - public static class PolygonGeometrySerializer - extends AbstractGeometryJacksonSerializer { - - private static final long serialVersionUID = 1L; - - PolygonGeometrySerializer() { - super(Polygon.class); - } - } - - public static class PolygonGeometryDeserializer - extends AbstractGeometryJacksonDeserializer { - - private static final long serialVersionUID = 1L; - - PolygonGeometryDeserializer() { - super(DefaultPolygon.class); - } - - @Override - public DefaultPolygon parse(final String val) { - return (DefaultPolygon) Polygon.fromWellKnownText(val); - } - } - - public static class PointGeometrySerializer extends AbstractGeometryJacksonSerializer { - - private static final long serialVersionUID = 1L; - - PointGeometrySerializer() { - super(Point.class); - } - } - - public static class PointGeometryDeserializer - extends AbstractGeometryJacksonDeserializer { - - private static final long serialVersionUID = 1L; - - PointGeometryDeserializer() { - super(DefaultPoint.class); - } - - @Override - public DefaultPoint parse(final String val) { - return (DefaultPoint) Point.fromWellKnownText(val); - } - } - - public static class DistanceGeometrySerializer - extends AbstractGeometryJacksonSerializer { - - private static final long serialVersionUID = 1L; - - DistanceGeometrySerializer() { - super(Distance.class); - } - } - - public static class DistanceGeometryDeserializer - extends AbstractGeometryJacksonDeserializer { - - private static final long serialVersionUID = 1L; - - DistanceGeometryDeserializer() { - super(Distance.class); - } - - @Override - public Distance parse(final String val) { - return Distance.fromWellKnownText(val); - } - } - - @SuppressWarnings("rawtypes") - static final class DsePJacksonSerializer extends StdScalarSerializer

{ - - private static final long serialVersionUID = 1L; - - DsePJacksonSerializer() { - super(P.class); - } - - @Override - public void serialize( - final P p, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider) - throws IOException { - jsonGenerator.writeStartObject(); - jsonGenerator.writeStringField("predicateType", getPredicateType(p)); - jsonGenerator.writeStringField( - GraphSONTokens.PREDICATE, - p instanceof ConnectiveP - ? p instanceof AndP ? GraphSONTokens.AND : GraphSONTokens.OR - : p.getBiPredicate().toString()); - if (p instanceof ConnectiveP) { - jsonGenerator.writeArrayFieldStart(GraphSONTokens.VALUE); - for (final P predicate : ((ConnectiveP) p).getPredicates()) { - jsonGenerator.writeObject(predicate); - } - jsonGenerator.writeEndArray(); - } else { - if (p.getValue() instanceof Collection) { - jsonGenerator.writeArrayFieldStart(GraphSONTokens.VALUE); - for (final Object object : (Collection) p.getValue()) { - jsonGenerator.writeObject(object); - } - jsonGenerator.writeEndArray(); - } else { - jsonGenerator.writeObjectField(GraphSONTokens.VALUE, p.getValue()); - } - } - jsonGenerator.writeEndObject(); - } - - private String getPredicateType(P p) { - if (p.getBiPredicate() instanceof SearchPredicate) { - return Search.class.getSimpleName(); - } else if (p.getBiPredicate() instanceof GeoPredicate) { - return Geo.class.getSimpleName(); - } else { - return P.class.getSimpleName(); - } - } - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - static final class DsePJacksonDeserializer extends AbstractObjectDeserializer

{ - - private static final long serialVersionUID = 1L; - - DsePJacksonDeserializer() { - super(P.class); - } - - @Override - public P createObject(final Map data) { - final String predicate = (String) data.get(GraphSONTokens.PREDICATE); - final String predicateType = (String) data.get("predicateType"); - final Object value = data.get(GraphSONTokens.VALUE); - if (predicate.equals(GraphSONTokens.AND) || predicate.equals(GraphSONTokens.OR)) { - return predicate.equals(GraphSONTokens.AND) - ? new AndP((List

) value) - : new OrP((List

) value); - } else { - try { - if (value instanceof Collection) { - if (predicate.equals("between")) { - return P.between(((List) value).get(0), ((List) value).get(1)); - } else if (predicateType.equals(P.class.getSimpleName()) - && predicate.equals("inside")) { - return P.between(((List) value).get(0), ((List) value).get(1)); - } else if (predicate.equals("outside")) { - return P.outside(((List) value).get(0), ((List) value).get(1)); - } else if (predicate.equals("within")) { - return P.within((Collection) value); - } else if (predicate.equals("without")) { - return P.without((Collection) value); - } else { - return (P) - P.class.getMethod(predicate, Collection.class).invoke(null, (Collection) value); - } - } else { - if (predicate.equals(SearchPredicate.prefix.name())) { - return Search.prefix((String) value); - } else if (predicate.equals(SearchPredicate.tokenPrefix.name())) { - return Search.tokenPrefix((String) value); - } else if (predicate.equals(SearchPredicate.regex.name())) { - return Search.regex((String) value); - } else if (predicate.equals(SearchPredicate.tokenRegex.name())) { - return Search.tokenRegex((String) value); - } else if (predicate.equals(SearchPredicate.token.name())) { - return Search.token((String) value); - } else if (predicate.equals(SearchPredicate.fuzzy.name())) { - Map arguments = (Map) value; - return Search.fuzzy( - (String) arguments.get("query"), (int) arguments.get("distance")); - } else if (predicate.equals(SearchPredicate.tokenFuzzy.name())) { - Map arguments = (Map) value; - return Search.tokenFuzzy( - (String) arguments.get("query"), (int) arguments.get("distance")); - } else if (predicate.equals(SearchPredicate.phrase.name())) { - Map arguments = (Map) value; - return Search.phrase( - (String) arguments.get("query"), (int) arguments.get("distance")); - } else if (predicateType.equals(Geo.class.getSimpleName()) - && predicate.equals(GeoPredicate.inside.name())) { - return Geo.inside( - ((Distance) value).getCenter(), - ((Distance) value).getRadius(), - Geo.Unit.DEGREES); - } else if (predicateType.equals(Geo.class.getSimpleName()) - && predicate.equals(GeoPredicate.insideCartesian.name())) { - return Geo.inside(((Distance) value).getCenter(), ((Distance) value).getRadius()); - } else { - return (P) P.class.getMethod(predicate, Object.class).invoke(null, value); - } - } - } catch (final Exception e) { - throw new IllegalStateException(e.getMessage(), e); - } - } - } - } - - public static class EditDistanceSerializer extends StdSerializer { - - private static final long serialVersionUID = 1L; - - EditDistanceSerializer() { - super(EditDistance.class); - } - - @Override - public void serialize( - EditDistance editDistance, JsonGenerator generator, SerializerProvider provider) - throws IOException { - generator.writeObject( - ImmutableMap.of("query", editDistance.query, "distance", editDistance.distance)); - } - - @Override - public void serializeWithType( - EditDistance editDistance, - JsonGenerator generator, - SerializerProvider provider, - TypeSerializer serializer) - throws IOException { - serialize(editDistance, generator, provider); - } - } - } - - public static class DriverObjectsModule extends SimpleModule { - - private static final long serialVersionUID = 1L; - - public DriverObjectsModule() { - super("datastax-driver-module"); - addSerializer(ObjectGraphNode.class, new ObjectGraphNodeGraphSON2Serializer()); - } - - static final class ObjectGraphNodeGraphSON2Serializer extends StdSerializer { - - private static final long serialVersionUID = 1L; - - ObjectGraphNodeGraphSON2Serializer() { - super(ObjectGraphNode.class); - } - - @Override - public void serialize( - ObjectGraphNode objectGraphNode, - JsonGenerator jsonGenerator, - SerializerProvider serializerProvider) - throws IOException { - jsonGenerator.writeObject(objectGraphNode.as(Object.class)); - } - - @Override - public void serializeWithType( - ObjectGraphNode objectGraphNode, - JsonGenerator jsonGenerator, - SerializerProvider serializerProvider, - TypeSerializer typeSerializer) - throws IOException { - serialize(objectGraphNode, jsonGenerator, serializerProvider); - } - } - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphSONUtils.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphSONUtils.java deleted file mode 100644 index 02b35f7ee36..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphSONUtils.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import com.datastax.dse.driver.api.core.graph.GraphNode; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.shaded.guava.common.base.Suppliers; -import com.datastax.oss.driver.shaded.guava.common.base.Throwables; -import com.datastax.oss.driver.shaded.guava.common.cache.CacheBuilder; -import com.datastax.oss.driver.shaded.guava.common.cache.CacheLoader; -import com.datastax.oss.driver.shaded.guava.common.cache.LoadingCache; -import com.datastax.oss.protocol.internal.util.Bytes; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.function.Supplier; -import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONMapper; -import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONReader; -import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONVersion; -import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONXModuleV2d0; -import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV2d0; -import org.apache.tinkerpop.shaded.jackson.core.Version; -import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper; - -public class GraphSONUtils { - - private static final LoadingCache OBJECT_MAPPERS = - CacheBuilder.newBuilder() - .build( - new CacheLoader() { - @Override - public ObjectMapper load(@NonNull GraphProtocol graphSubProtocol) throws Exception { - switch (graphSubProtocol) { - case GRAPHSON_1_0: - com.datastax.oss.driver.api.core.Version driverVersion = - CqlSession.OSS_DRIVER_COORDINATES.getVersion(); - Version driverJacksonVersion = - new Version( - driverVersion.getMajor(), - driverVersion.getMinor(), - driverVersion.getPatch(), - driverVersion.getPreReleaseLabels() != null - && driverVersion.getPreReleaseLabels().contains("SNAPSHOT") - ? "SNAPSHOT" - : null, - "com.datastax.dse", - "dse-java-driver-core"); - - ObjectMapper mapper = - GraphSONMapper.build() - .version(GraphSONVersion.V1_0) - .create() - .createMapper(); - mapper.registerModule( - new GraphSON1SerdeTP.GraphSON1DefaultModule( - "graph-graphson1default", driverJacksonVersion)); - mapper.registerModule( - new GraphSON1SerdeTP.GraphSON1JavaTimeModule( - "graph-graphson1javatime", driverJacksonVersion)); - - return mapper; - case GRAPHSON_2_0: - return GraphSONMapper.build() - .version(GraphSONVersion.V2_0) - .addCustomModule(GraphSONXModuleV2d0.build().create(false)) - .addRegistry(TinkerIoRegistryV2d0.instance()) - .addCustomModule(new GraphSON2SerdeTP.DseGraphModule()) - .addCustomModule(new GraphSON2SerdeTP.DriverObjectsModule()) - .create() - .createMapper(); - - default: - throw new IllegalStateException( - String.format("GraphSON sub-protocol unknown: {%s}", graphSubProtocol)); - } - } - }); - - static final Supplier GRAPHSON1_READER = - Suppliers.memoize( - () -> - GraphSONReader.build() - .mapper(GraphSONMapper.build().version(GraphSONVersion.V1_0).create()) - .create()); - - public static ByteBuffer serializeToByteBuffer(Object object, GraphProtocol graphSubProtocol) - throws IOException { - return ByteBuffer.wrap(serializeToBytes(object, graphSubProtocol)); - } - - static byte[] serializeToBytes(Object object, GraphProtocol graphSubProtocol) throws IOException { - try { - return OBJECT_MAPPERS.get(graphSubProtocol).writeValueAsBytes(object); - } catch (ExecutionException e) { - Throwables.throwIfUnchecked(e); - throw new RuntimeException(e); - } - } - - public static GraphNode createGraphNode(List data, GraphProtocol graphSubProtocol) - throws IOException { - try { - ObjectMapper mapper = OBJECT_MAPPERS.get(graphSubProtocol); - switch (graphSubProtocol) { - case GRAPHSON_1_0: - return new LegacyGraphNode(mapper.readTree(Bytes.getArray(data.get(0))), mapper); - case GRAPHSON_2_0: - return new ObjectGraphNode(mapper.readValue(Bytes.getArray(data.get(0)), Object.class)); - default: - // Should already be caught when we lookup in the cache - throw new AssertionError( - String.format("Unknown GraphSON sub-protocol: {%s}", graphSubProtocol)); - } - } catch (ExecutionException e) { - Throwables.throwIfUnchecked(e); - throw new RuntimeException(e); - } - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphStatementBase.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphStatementBase.java deleted file mode 100644 index b8baa2f5e49..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphStatementBase.java +++ /dev/null @@ -1,413 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import com.datastax.dse.driver.api.core.graph.GraphStatement; -import com.datastax.oss.driver.api.core.ConsistencyLevel; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.metadata.Node; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.nio.ByteBuffer; -import java.time.Duration; -import java.util.Map; -import net.jcip.annotations.Immutable; - -@Immutable -public abstract class GraphStatementBase> - implements GraphStatement { - private final Boolean isIdempotent; - private final Duration timeout; - private final Node node; - private final long timestamp; - private final DriverExecutionProfile executionProfile; - private final String executionProfileName; - private final Map customPayload; - private final String graphName; - private final String traversalSource; - private final String subProtocol; - private final ConsistencyLevel consistencyLevel; - private final ConsistencyLevel readConsistencyLevel; - private final ConsistencyLevel writeConsistencyLevel; - - protected GraphStatementBase( - Boolean isIdempotent, - Duration timeout, - Node node, - long timestamp, - DriverExecutionProfile executionProfile, - String executionProfileName, - Map customPayload, - String graphName, - String traversalSource, - String subProtocol, - ConsistencyLevel consistencyLevel, - ConsistencyLevel readConsistencyLevel, - ConsistencyLevel writeConsistencyLevel) { - this.isIdempotent = isIdempotent; - this.timeout = timeout; - this.node = node; - this.timestamp = timestamp; - this.executionProfile = executionProfile; - this.executionProfileName = executionProfileName; - this.customPayload = customPayload; - this.graphName = graphName; - this.traversalSource = traversalSource; - this.subProtocol = subProtocol; - this.consistencyLevel = consistencyLevel; - this.readConsistencyLevel = readConsistencyLevel; - this.writeConsistencyLevel = writeConsistencyLevel; - } - - protected abstract SelfT newInstance( - Boolean isIdempotent, - Duration timeout, - Node node, - long timestamp, - DriverExecutionProfile executionProfile, - String executionProfileName, - Map customPayload, - String graphName, - String traversalSource, - String subProtocol, - ConsistencyLevel consistencyLevel, - ConsistencyLevel readConsistencyLevel, - ConsistencyLevel writeConsistencyLevel); - - @Override - public Boolean isIdempotent() { - return isIdempotent; - } - - @NonNull - @Override - public SelfT setIdempotent(@Nullable Boolean newIdempotence) { - return newInstance( - newIdempotence, - timeout, - node, - timestamp, - executionProfile, - executionProfileName, - customPayload, - graphName, - traversalSource, - subProtocol, - consistencyLevel, - readConsistencyLevel, - writeConsistencyLevel); - } - - @Nullable - @Override - public Duration getTimeout() { - return timeout; - } - - @NonNull - @Override - public SelfT setTimeout(@Nullable Duration newTimeout) { - return newInstance( - isIdempotent, - newTimeout, - node, - timestamp, - executionProfile, - executionProfileName, - customPayload, - graphName, - traversalSource, - subProtocol, - consistencyLevel, - readConsistencyLevel, - writeConsistencyLevel); - } - - @Nullable - @Override - public Node getNode() { - return node; - } - - @NonNull - @Override - public SelfT setNode(@Nullable Node newNode) { - return newInstance( - isIdempotent, - timeout, - newNode, - timestamp, - executionProfile, - executionProfileName, - customPayload, - graphName, - traversalSource, - subProtocol, - consistencyLevel, - readConsistencyLevel, - writeConsistencyLevel); - } - - @Override - public long getTimestamp() { - return this.timestamp; - } - - @NonNull - @Override - public SelfT setTimestamp(long newTimestamp) { - return newInstance( - isIdempotent, - timeout, - node, - newTimestamp, - executionProfile, - executionProfileName, - customPayload, - graphName, - traversalSource, - subProtocol, - consistencyLevel, - readConsistencyLevel, - writeConsistencyLevel); - } - - @Nullable - @Override - public DriverExecutionProfile getExecutionProfile() { - return executionProfile; - } - - @NonNull - @Override - public SelfT setExecutionProfile(@Nullable DriverExecutionProfile newExecutionProfile) { - return newInstance( - isIdempotent, - timeout, - node, - timestamp, - newExecutionProfile, - executionProfileName, - customPayload, - graphName, - traversalSource, - subProtocol, - consistencyLevel, - readConsistencyLevel, - writeConsistencyLevel); - } - - @Nullable - @Override - public String getExecutionProfileName() { - return executionProfileName; - } - - @NonNull - @Override - public SelfT setExecutionProfileName(@Nullable String newExecutionProfileName) { - return newInstance( - isIdempotent, - timeout, - node, - timestamp, - executionProfile, - newExecutionProfileName, - customPayload, - graphName, - traversalSource, - subProtocol, - consistencyLevel, - readConsistencyLevel, - writeConsistencyLevel); - } - - @NonNull - @Override - public Map getCustomPayload() { - return customPayload; - } - - @NonNull - @Override - public SelfT setCustomPayload(@NonNull Map newCustomPayload) { - return newInstance( - isIdempotent, - timeout, - node, - timestamp, - executionProfile, - executionProfileName, - newCustomPayload, - graphName, - traversalSource, - subProtocol, - consistencyLevel, - readConsistencyLevel, - writeConsistencyLevel); - } - - @Nullable - @Override - public String getGraphName() { - return graphName; - } - - @NonNull - @Override - public SelfT setGraphName(@Nullable String newGraphName) { - return newInstance( - isIdempotent, - timeout, - node, - timestamp, - executionProfile, - executionProfileName, - customPayload, - newGraphName, - traversalSource, - subProtocol, - consistencyLevel, - readConsistencyLevel, - writeConsistencyLevel); - } - - @Nullable - @Override - public String getTraversalSource() { - return traversalSource; - } - - @NonNull - @Override - public SelfT setTraversalSource(@Nullable String newTraversalSource) { - return newInstance( - isIdempotent, - timeout, - node, - timestamp, - executionProfile, - executionProfileName, - customPayload, - graphName, - newTraversalSource, - subProtocol, - consistencyLevel, - readConsistencyLevel, - writeConsistencyLevel); - } - - @Nullable - @Override - public String getSubProtocol() { - return subProtocol; - } - - @NonNull - @Override - public SelfT setSubProtocol(@Nullable String newSubProtocol) { - return newInstance( - isIdempotent, - timeout, - node, - timestamp, - executionProfile, - executionProfileName, - customPayload, - graphName, - traversalSource, - newSubProtocol, - consistencyLevel, - readConsistencyLevel, - writeConsistencyLevel); - } - - @Nullable - @Override - public ConsistencyLevel getConsistencyLevel() { - return consistencyLevel; - } - - @Override - public SelfT setConsistencyLevel(@Nullable ConsistencyLevel newConsistencyLevel) { - return newInstance( - isIdempotent, - timeout, - node, - timestamp, - executionProfile, - executionProfileName, - customPayload, - graphName, - traversalSource, - subProtocol, - newConsistencyLevel, - readConsistencyLevel, - writeConsistencyLevel); - } - - @Nullable - @Override - public ConsistencyLevel getReadConsistencyLevel() { - return readConsistencyLevel; - } - - @NonNull - @Override - public SelfT setReadConsistencyLevel(@Nullable ConsistencyLevel newReadConsistencyLevel) { - return newInstance( - isIdempotent, - timeout, - node, - timestamp, - executionProfile, - executionProfileName, - customPayload, - graphName, - traversalSource, - subProtocol, - consistencyLevel, - newReadConsistencyLevel, - writeConsistencyLevel); - } - - @Nullable - @Override - public ConsistencyLevel getWriteConsistencyLevel() { - return writeConsistencyLevel; - } - - @NonNull - @Override - public SelfT setWriteConsistencyLevel(@Nullable ConsistencyLevel newWriteConsistencyLevel) { - return newInstance( - isIdempotent, - timeout, - node, - timestamp, - executionProfile, - executionProfileName, - customPayload, - graphName, - traversalSource, - subProtocol, - consistencyLevel, - readConsistencyLevel, - newWriteConsistencyLevel); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphSupportChecker.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphSupportChecker.java deleted file mode 100644 index 6e586bbcf3f..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/GraphSupportChecker.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.dse.driver.api.core.graph.GraphStatement; -import com.datastax.dse.driver.api.core.graph.PagingEnabledOptions; -import com.datastax.dse.driver.api.core.metadata.DseNodeProperties; -import com.datastax.dse.driver.internal.core.DseProtocolFeature; -import com.datastax.oss.driver.api.core.ProtocolVersion; -import com.datastax.oss.driver.api.core.Version; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import com.datastax.oss.driver.internal.core.cql.Conversions; -import com.datastax.oss.driver.shaded.guava.common.annotations.VisibleForTesting; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Collection; -import java.util.Objects; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class GraphSupportChecker { - - private static final Logger LOG = LoggerFactory.getLogger(GraphSupportChecker.class); - - /** - * The minimum DSE version supporting both graph paging and the GraphBinary sub-protocol is DSE - * 6.8. - */ - private static final Version MIN_DSE_VERSION_GRAPH_BINARY_AND_PAGING = - Objects.requireNonNull(Version.parse("6.8.0")); - - private volatile Boolean contextGraphPagingEnabled; - private volatile Boolean isDse68OrAbove; - - /** - * Checks whether graph paging is available. - * - *

Graph paging is available if: - * - *

    - *
  1. Continuous paging is generally available (this implies protocol version {@link - * com.datastax.dse.driver.api.core.DseProtocolVersion#DSE_V1 DSE_V1} or higher); - *
  2. Graph paging is set to ENABLED or AUTO in the configuration - * with {@link DseDriverOption#GRAPH_PAGING_ENABLED}; - *
  3. If graph paging is set to AUTO, then a check will be performed to verify - * that all hosts are running DSE 6.8+; if that is the case, then graph paging will be - * assumed to be available. - *
- * - * Note that the hosts check will be done only once, then memoized; if other hosts join the - * cluster later and do not support graph paging, the user has to manually disable graph paging. - */ - public boolean isPagingEnabled( - @NonNull GraphStatement graphStatement, @NonNull InternalDriverContext context) { - DriverExecutionProfile driverExecutionProfile = - Conversions.resolveExecutionProfile(graphStatement, context); - PagingEnabledOptions pagingEnabledOptions = - PagingEnabledOptions.valueOf( - driverExecutionProfile.getString(DseDriverOption.GRAPH_PAGING_ENABLED)); - if (LOG.isTraceEnabled()) { - LOG.trace("GRAPH_PAGING_ENABLED: {}", pagingEnabledOptions); - } - if (pagingEnabledOptions == PagingEnabledOptions.DISABLED) { - return false; - } else if (pagingEnabledOptions == PagingEnabledOptions.ENABLED) { - return true; - } else { - return isContextGraphPagingEnabled(context); - } - } - - /** - * Infers the {@link GraphProtocol} to use to execute the given statement. - * - *

The graph protocol is computed as follows: - * - *

    - *
  1. If the statement declares the protocol to use with {@link - * GraphStatement#getSubProtocol()}, then that protocol is returned. - *
  2. If the driver configuration explicitly defines the protocol to use (see {@link - * DseDriverOption#GRAPH_SUB_PROTOCOL} and reference.conf), then that protocol is returned. - *
  3. Otherwise, the graph protocol to use is determined by the DSE version of hosts in the - * cluster. If any host has DSE version 6.7.x or lower, the default graph protocol is {@link - * GraphProtocol#GRAPHSON_2_0}. If all hosts have DSE version 6.8.0 or higher, the default - * graph protocol is {@link GraphProtocol#GRAPH_BINARY_1_0}. - *
- * - * Note that the hosts check will be done only once, then memoized; if other hosts join the and do - * not support the computed graph protocol, the user has to manually set the graph protocol to - * use. - * - *

Also note that GRAPH_BINARY_1_0 can only be used with "core" graph engines; if - * you are targeting a "classic" graph engine instead, the user has to manually set the graph - * protocol to something else. - */ - @NonNull - public GraphProtocol inferGraphProtocol( - @NonNull GraphStatement statement, - @NonNull DriverExecutionProfile config, - @NonNull InternalDriverContext context) { - String graphProtocol = statement.getSubProtocol(); - if (graphProtocol == null) { - // use the protocol specified in configuration, otherwise get the default from the context - graphProtocol = - config.isDefined(DseDriverOption.GRAPH_SUB_PROTOCOL) - ? config.getString(DseDriverOption.GRAPH_SUB_PROTOCOL) - : getDefaultGraphProtocol(context).toInternalCode(); - } - // should not be null because we call config.getString() with a default value - Objects.requireNonNull( - graphProtocol, - "Could not determine the graph protocol for the query. This is a bug, please report."); - - return GraphProtocol.fromString(graphProtocol); - } - - private boolean isContextGraphPagingEnabled(InternalDriverContext context) { - if (contextGraphPagingEnabled == null) { - ProtocolVersion protocolVersion = context.getProtocolVersion(); - if (!context - .getProtocolVersionRegistry() - .supports(protocolVersion, DseProtocolFeature.CONTINUOUS_PAGING)) { - contextGraphPagingEnabled = false; - } else { - if (isDse68OrAbove == null) { - isDse68OrAbove = checkIsDse68OrAbove(context); - } - contextGraphPagingEnabled = isDse68OrAbove; - } - } - return contextGraphPagingEnabled; - } - - /** - * Determines the default {@link GraphProtocol} for the given context. - * - * @return The default GraphProtocol to used based on the provided context. - */ - @VisibleForTesting - GraphProtocol getDefaultGraphProtocol(@NonNull InternalDriverContext context) { - if (isDse68OrAbove == null) { - isDse68OrAbove = checkIsDse68OrAbove(context); - } - // if the DSE version can't be determined, default to GraphSON 2.0 - return isDse68OrAbove ? GraphProtocol.GRAPH_BINARY_1_0 : GraphProtocol.GRAPHSON_2_0; - } - - private boolean checkIsDse68OrAbove(@NonNull InternalDriverContext context) { - Collection nodes = context.getMetadataManager().getMetadata().getNodes().values(); - - for (Node node : nodes) { - Version dseVersion = (Version) node.getExtras().get(DseNodeProperties.DSE_VERSION); - if (dseVersion == null || dseVersion.compareTo(MIN_DSE_VERSION_GRAPH_BINARY_AND_PAGING) < 0) { - return false; - } - } - return true; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/LegacyGraphNode.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/LegacyGraphNode.java deleted file mode 100644 index 1749bf00873..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/LegacyGraphNode.java +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import com.datastax.dse.driver.api.core.graph.GraphNode; -import com.datastax.oss.driver.api.core.type.reflect.GenericType; -import com.datastax.oss.driver.shaded.guava.common.base.Objects; -import com.datastax.oss.driver.shaded.guava.common.base.Preconditions; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.charset.StandardCharsets; -import java.util.List; -import java.util.Map; -import java.util.Set; -import net.jcip.annotations.Immutable; -import org.apache.tinkerpop.gremlin.process.traversal.Path; -import org.apache.tinkerpop.gremlin.structure.Edge; -import org.apache.tinkerpop.gremlin.structure.Property; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.apache.tinkerpop.gremlin.structure.VertexProperty; -import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTokens; -import org.apache.tinkerpop.gremlin.structure.util.Attachable; -import org.apache.tinkerpop.shaded.jackson.core.JsonParser; -import org.apache.tinkerpop.shaded.jackson.databind.JavaType; -import org.apache.tinkerpop.shaded.jackson.databind.JsonNode; -import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper; - -/** - * Legacy implementation for GraphSON 1 results. - * - *

The server returns plain JSON with no type information. The driver works with the JSON - * representation directly. - */ -@Immutable -public class LegacyGraphNode implements GraphNode { - private static final String TYPE = "type"; - private static final String VERTEX_TYPE = "vertex"; - private static final String EDGE_TYPE = "edge"; - - private static final GenericType> LIST_TYPE = GenericType.listOf(Object.class); - private static final GenericType> MAP_TYPE = - GenericType.mapOf(String.class, Object.class); - - private final JsonNode delegate; - private final ObjectMapper objectMapper; - - public LegacyGraphNode(JsonNode delegate, ObjectMapper objectMapper) { - Preconditions.checkNotNull(delegate); - Preconditions.checkNotNull(objectMapper); - this.delegate = delegate; - this.objectMapper = objectMapper; - } - - /** - * The underlying JSON representation. - * - *

This is an implementation detail, it's only exposed through the internal API. - */ - public JsonNode getDelegate() { - return delegate; - } - - /** - * The object mapper used to deserialize results in {@link #as(Class)} and {@link - * #as(GenericType)}. - * - *

This is an implementation detail, it's only exposed through the internal API. - */ - public ObjectMapper getObjectMapper() { - return objectMapper; - } - - @Override - public boolean isNull() { - return delegate.isNull(); - } - - @Override - public boolean isMap() { - return delegate.isObject(); - } - - @Override - public Iterable keys() { - return (Iterable) delegate::fieldNames; - } - - @Override - public LegacyGraphNode getByKey(Object key) { - if (!(key instanceof String)) { - return null; - } - JsonNode node = delegate.get(((String) key)); - if (node == null) { - return null; - } - return new LegacyGraphNode(node, objectMapper); - } - - @Override - @SuppressWarnings("unchecked") - public Map asMap() { - return (Map) as(MAP_TYPE); - } - - @Override - public boolean isList() { - return delegate.isArray(); - } - - @Override - public int size() { - return delegate.size(); - } - - @Override - public LegacyGraphNode getByIndex(int index) { - JsonNode node = delegate.get(index); - if (node == null) { - return null; - } - return new LegacyGraphNode(node, objectMapper); - } - - @Override - @SuppressWarnings("unchecked") - public List asList() { - return (List) as(LIST_TYPE); - } - - @Override - public boolean isValue() { - return delegate.isValueNode(); - } - - @Override - public int asInt() { - return delegate.asInt(); - } - - @Override - public boolean asBoolean() { - return delegate.asBoolean(); - } - - @Override - public long asLong() { - return delegate.asLong(); - } - - @Override - public double asDouble() { - return delegate.asDouble(); - } - - @Override - public String asString() { - return delegate.asText(); - } - - @Override - public boolean isVertex() { - return isType(VERTEX_TYPE); - } - - @Override - public Vertex asVertex() { - try { - return GraphSONUtils.GRAPHSON1_READER - .get() - .readVertex( - new ByteArrayInputStream(delegate.toString().getBytes(StandardCharsets.UTF_8)), - null, - null, - null); - } catch (IOException e) { - throw new UncheckedIOException("Could not deserialize node as Vertex.", e); - } - } - - @Override - public boolean isEdge() { - return isType(EDGE_TYPE); - } - - @Override - public Edge asEdge() { - try { - return GraphSONUtils.GRAPHSON1_READER - .get() - .readEdge( - new ByteArrayInputStream(delegate.toString().getBytes(StandardCharsets.UTF_8)), - Attachable::get); - } catch (IOException e) { - throw new UncheckedIOException("Could not deserialize node as Edge.", e); - } - } - - @Override - public boolean isPath() { - return false; - } - - @Override - public Path asPath() { - throw new UnsupportedOperationException( - "GraphSON1 does not support Path, use another Graph sub-protocol such as GraphSON2."); - } - - @Override - public boolean isProperty() { - return delegate.has(GraphSONTokens.KEY) && delegate.has(GraphSONTokens.VALUE); - } - - @Override - @SuppressWarnings("unchecked") - public Property asProperty() { - try { - return GraphSONUtils.GRAPHSON1_READER - .get() - .readProperty( - new ByteArrayInputStream(delegate.toString().getBytes(StandardCharsets.UTF_8)), - Attachable::get); - } catch (IOException e) { - throw new UncheckedIOException("Could not deserialize node as Property.", e); - } - } - - @Override - public boolean isVertexProperty() { - return delegate.has(GraphSONTokens.ID) - && delegate.has(GraphSONTokens.VALUE) - && delegate.has(GraphSONTokens.LABEL); - } - - @Override - @SuppressWarnings("unchecked") - public VertexProperty asVertexProperty() { - try { - return GraphSONUtils.GRAPHSON1_READER - .get() - .readVertexProperty( - new ByteArrayInputStream(delegate.toString().getBytes(StandardCharsets.UTF_8)), - Attachable::get); - } catch (IOException e) { - throw new UncheckedIOException("Could not deserialize node as VertexProperty.", e); - } - } - - @Override - public boolean isSet() { - return false; - } - - @Override - public Set asSet() { - throw new UnsupportedOperationException( - "GraphSON1 does not support Set, use another Graph sub-protocol such as GraphSON2."); - } - - @Override - public ResultT as(Class clazz) { - try { - return objectMapper.treeToValue(delegate, clazz); - } catch (IOException e) { - throw new UncheckedIOException("Could not deserialize node as: " + clazz, e); - } - } - - @Override - public ResultT as(GenericType type) { - try { - JsonParser parser = objectMapper.treeAsTokens(delegate); - JavaType javaType = objectMapper.constructType(type.__getToken().getType()); - return objectMapper.readValue(parser, javaType); - } catch (IOException e) { - throw new UncheckedIOException("Could not deserialize node as: " + type, e); - } - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof LegacyGraphNode)) { - return false; - } - LegacyGraphNode that = (LegacyGraphNode) o; - return Objects.equal(delegate, that.delegate); - } - - @Override - public int hashCode() { - return Objects.hashCode(delegate); - } - - @Override - public String toString() { - return delegate.toString(); - } - - private boolean isType(String expectedTypeName) { - JsonNode type = delegate.get(TYPE); - return type != null && expectedTypeName.equals(type.asText()); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/MultiPageGraphResultSet.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/MultiPageGraphResultSet.java deleted file mode 100644 index fe81d73ba00..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/MultiPageGraphResultSet.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import com.datastax.dse.driver.api.core.graph.AsyncGraphResultSet; -import com.datastax.dse.driver.api.core.graph.GraphNode; -import com.datastax.dse.driver.api.core.graph.GraphResultSet; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import com.datastax.oss.driver.internal.core.util.CountingIterator; -import com.datastax.oss.driver.internal.core.util.concurrent.BlockingOperation; -import com.datastax.oss.driver.internal.core.util.concurrent.CompletableFutures; -import com.datastax.oss.driver.shaded.guava.common.collect.Lists; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -public class MultiPageGraphResultSet implements GraphResultSet { - private final RowIterator iterator; - private final List executionInfos = new ArrayList<>(); - - public MultiPageGraphResultSet(AsyncGraphResultSet firstPage) { - iterator = new RowIterator(firstPage); - executionInfos.add(firstPage.getRequestExecutionInfo()); - } - - @Override - public void cancel() { - iterator.cancel(); - } - - @NonNull - @Override - public ExecutionInfo getRequestExecutionInfo() { - return executionInfos.get(executionInfos.size() - 1); - } - - @NonNull - @Override - @Deprecated - public com.datastax.dse.driver.api.core.graph.GraphExecutionInfo getExecutionInfo() { - return GraphExecutionInfoConverter.convert(getRequestExecutionInfo()); - } - - /** - * The execution information for all the queries that have been performed so far to assemble this - * iterable. - * - *

This will have multiple elements if the query is paged, since the driver performs blocking - * background queries to fetch additional pages transparently as the result set is being iterated. - */ - @NonNull - public List getRequestExecutionInfos() { - return executionInfos; - } - - /** @deprecated use {@link #getRequestExecutionInfos()} instead. */ - @NonNull - @Deprecated - public List getExecutionInfos() { - return Lists.transform(executionInfos, GraphExecutionInfoConverter::convert); - } - - @NonNull - @Override - public Iterator iterator() { - return iterator; - } - - public class RowIterator extends CountingIterator { - private AsyncGraphResultSet currentPage; - private Iterator currentRows; - private boolean cancelled = false; - - private RowIterator(AsyncGraphResultSet firstPage) { - super(firstPage.remaining()); - currentPage = firstPage; - currentRows = firstPage.currentPage().iterator(); - } - - @Override - protected GraphNode computeNext() { - maybeMoveToNextPage(); - return currentRows.hasNext() ? currentRows.next() : endOfData(); - } - - private void maybeMoveToNextPage() { - if (!cancelled && !currentRows.hasNext() && currentPage.hasMorePages()) { - BlockingOperation.checkNotDriverThread(); - AsyncGraphResultSet nextPage = - CompletableFutures.getUninterruptibly(currentPage.fetchNextPage()); - currentPage = nextPage; - remaining += currentPage.remaining(); - currentRows = nextPage.currentPage().iterator(); - executionInfos.add(nextPage.getRequestExecutionInfo()); - } - } - - private void cancel() { - currentPage.cancel(); - cancelled = true; - } - - public boolean isCancelled() { - return cancelled; - } - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/ObjectGraphNode.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/ObjectGraphNode.java deleted file mode 100644 index 56123799fdd..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/ObjectGraphNode.java +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import com.datastax.dse.driver.api.core.graph.GraphNode; -import com.datastax.oss.driver.api.core.type.reflect.GenericType; -import com.datastax.oss.driver.shaded.guava.common.base.Objects; -import java.util.List; -import java.util.Map; -import java.util.Set; -import net.jcip.annotations.Immutable; -import org.apache.tinkerpop.gremlin.process.traversal.Path; -import org.apache.tinkerpop.gremlin.structure.Edge; -import org.apache.tinkerpop.gremlin.structure.Property; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.apache.tinkerpop.gremlin.structure.VertexProperty; - -/** - * Modern implementation for GraphSON 2+ results. - * - *

The server returns results with type information. The driver works with the decoded objects - * directly. - */ -@Immutable -public class ObjectGraphNode implements GraphNode { - - private final Object delegate; - - public ObjectGraphNode(Object delegate) { - this.delegate = delegate; - } - - @Override - public boolean isNull() { - return delegate == null; - } - - @Override - public boolean isMap() { - return delegate instanceof Map; - } - - @Override - public Iterable keys() { - return ((Map) delegate).keySet(); - } - - @Override - public GraphNode getByKey(Object key) { - if (!isMap()) { - return null; - } - Map map = asMap(); - if (map.containsKey(key)) { - return new ObjectGraphNode(map.get(key)); - } - return null; - } - - @Override - @SuppressWarnings("unchecked") - public Map asMap() { - return (Map) delegate; - } - - @Override - public boolean isList() { - return delegate instanceof List; - } - - @Override - public int size() { - if (isList()) { - return asList().size(); - } else if (isMap()) { - return asMap().size(); - } else if (isSet()) { - return asSet().size(); - } else { - return 0; - } - } - - @Override - public GraphNode getByIndex(int index) { - if (!isList() || index < 0 || index >= size()) { - return null; - } - return new ObjectGraphNode(asList().get(index)); - } - - @Override - @SuppressWarnings("unchecked") - public List asList() { - return (List) delegate; - } - - @Override - public boolean isValue() { - return !(isList() - || isMap() - || isSet() - || isVertex() - || isEdge() - || isPath() - || isProperty() - || isVertexProperty()); - } - - @Override - public boolean isVertexProperty() { - return delegate instanceof VertexProperty; - } - - @Override - public boolean isProperty() { - return delegate instanceof Property; - } - - @Override - public boolean isPath() { - return delegate instanceof Path; - } - - @Override - public int asInt() { - return (Integer) delegate; - } - - @Override - public boolean asBoolean() { - return (Boolean) delegate; - } - - @Override - public long asLong() { - return (Long) delegate; - } - - @Override - public double asDouble() { - return (Double) delegate; - } - - @Override - public String asString() { - return (String) delegate; - } - - @Override - @SuppressWarnings("unchecked") - public T as(Class clazz) { - return (T) delegate; - } - - @Override - @SuppressWarnings("unchecked") - public T as(GenericType type) { - return (T) delegate; - } - - @Override - public boolean isVertex() { - return delegate instanceof Vertex; - } - - @Override - public Vertex asVertex() { - return (Vertex) delegate; - } - - @Override - public boolean isEdge() { - return delegate instanceof Edge; - } - - @Override - public Edge asEdge() { - return (Edge) delegate; - } - - @Override - public Path asPath() { - return (Path) delegate; - } - - @Override - @SuppressWarnings("unchecked") - public Property asProperty() { - return (Property) delegate; - } - - @Override - @SuppressWarnings("unchecked") - public VertexProperty asVertexProperty() { - return (VertexProperty) delegate; - } - - @Override - public boolean isSet() { - return delegate instanceof Set; - } - - @Override - @SuppressWarnings("unchecked") - public Set asSet() { - return (Set) delegate; - } - - @Override - public String toString() { - return this.delegate.toString(); - } - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } - // Compare each others' delegates. - return other instanceof ObjectGraphNode - && Objects.equal(this.delegate, ((ObjectGraphNode) other).delegate); - } - - @Override - public int hashCode() { - return Objects.hashCode(delegate); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/SearchPredicate.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/SearchPredicate.java deleted file mode 100644 index b69c3a59cf0..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/SearchPredicate.java +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import com.datastax.oss.driver.shaded.guava.common.collect.Sets; -import java.util.List; -import java.util.Set; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -/** - * List of predicates for geolocation usage with DseGraph and Search indexes. Should not be accessed - * directly but through the {@link com.datastax.dse.driver.api.core.graph.predicates.Search} static - * methods. - */ -public enum SearchPredicate implements DsePredicate { - /** Whether the text contains a given term as a token in the text (case insensitive). */ - token { - @Override - public boolean test(Object value, Object condition) { - preEvaluate(condition); - return value != null && evaluate(value.toString(), (String) condition); - } - - boolean evaluate(String value, String terms) { - Set tokens = Sets.newHashSet(tokenize(value.toLowerCase())); - terms = terms.trim(); - List tokenTerms = tokenize(terms.toLowerCase()); - if (!terms.isEmpty() && tokenTerms.isEmpty()) { - return false; - } - for (String term : tokenTerms) { - if (!tokens.contains(term)) { - return false; - } - } - return true; - } - - @Override - public boolean isValidCondition(Object condition) { - return condition != null && isNotBlank((String) condition); - } - - @Override - public String toString() { - return "token"; - } - }, - - /** Whether the text contains a token that starts with a given term (case insensitive). */ - tokenPrefix { - @Override - public boolean test(Object value, Object condition) { - preEvaluate(condition); - return value != null && evaluate(value.toString(), (String) condition); - } - - boolean evaluate(String value, String prefix) { - for (String token : tokenize(value.toLowerCase())) { - if (token.startsWith(prefix.toLowerCase().trim())) { - return true; - } - } - return false; - } - - @Override - public boolean isValidCondition(Object condition) { - return condition != null; - } - - @Override - public String toString() { - return "tokenPrefix"; - } - }, - - /** Whether the text contains a token that matches a regular expression (case insensitive). */ - tokenRegex { - @Override - public boolean test(Object value, Object condition) { - preEvaluate(condition); - return value != null && evaluate(value.toString(), (String) condition); - } - - boolean evaluate(String value, String regex) { - Pattern compiled = Pattern.compile(regex, Pattern.CASE_INSENSITIVE); - for (String token : tokenize(value.toLowerCase())) { - if (compiled.matcher(token).matches()) { - return true; - } - } - return false; - } - - @Override - public boolean isValidCondition(Object condition) { - return condition != null && isNotBlank((String) condition); - } - - @Override - public String toString() { - return "tokenRegex"; - } - }, - - /** - * Whether some token in the text is within a given edit distance from the given term (case - * insensitive). - */ - tokenFuzzy { - @Override - public boolean test(Object value, Object condition) { - preEvaluate(condition); - if (value == null) { - return false; - } - - EditDistance fuzzyCondition = (EditDistance) condition; - - for (String token : tokenize(value.toString().toLowerCase())) { - if (SearchUtils.getOptimalStringAlignmentDistance(token, fuzzyCondition.query.toLowerCase()) - <= fuzzyCondition.distance) { - return true; - } - } - - return false; - } - - @Override - public boolean isValidCondition(Object condition) { - return condition != null; - } - - @Override - public String toString() { - return "tokenFuzzy"; - } - }, - - /** Whether the text starts with a given prefix (case sensitive). */ - prefix { - @Override - public boolean test(Object value, Object condition) { - preEvaluate(condition); - return value != null && value.toString().startsWith(((String) condition).trim()); - } - - @Override - public boolean isValidCondition(Object condition) { - return condition != null; - } - - @Override - public String toString() { - return "prefix"; - } - }, - - /** Whether the text matches a regular expression (case sensitive). */ - regex { - @Override - public boolean test(Object value, Object condition) { - preEvaluate(condition); - return value != null - && Pattern.compile((String) condition, Pattern.DOTALL) - .matcher(value.toString()) - .matches(); - } - - @Override - public boolean isValidCondition(Object condition) { - return condition != null && isNotBlank((String) condition); - } - - @Override - public String toString() { - return "regex"; - } - }, - - /** Whether the text is within a given edit distance from the given term (case sensitive). */ - fuzzy { - @Override - public boolean test(Object value, Object condition) { - preEvaluate(condition); - if (value == null) { - return false; - } - EditDistance fuzzyCondition = (EditDistance) condition; - return SearchUtils.getOptimalStringAlignmentDistance(value.toString(), fuzzyCondition.query) - <= fuzzyCondition.distance; - } - - @Override - public boolean isValidCondition(Object condition) { - return condition != null; - } - - @Override - public String toString() { - return "fuzzy"; - } - }, - - /** - * Whether tokenized text contains a given phrase, optionally within a given proximity (case - * insensitive). - */ - phrase { - @Override - public boolean test(Object value, Object condition) { - preEvaluate(condition); - if (value == null) { - return false; - } - - EditDistance phraseCondition = (EditDistance) condition; - - List valueTokens = tokenize(value.toString().toLowerCase()); - List phraseTokens = tokenize(phraseCondition.query.toLowerCase()); - - int valuePosition = 0; - int phrasePosition = 0; - int distance = 0; - - // Look for matches while phrase/value tokens and distance budget remain - while (phrasePosition < phraseTokens.size() - && valuePosition < valueTokens.size() - && distance <= phraseCondition.distance) { - - if (phraseTokens.get(phrasePosition).equals(valueTokens.get(valuePosition))) { - // Early return-true when we've matched the whole phrase (within the specified distance) - if (phrasePosition == phraseTokens.size() - 1) { - return true; - } - phrasePosition++; - } else if (0 < phrasePosition) { - // We've previously found at least one matching token in the input string, - // but the current token does not match the phrase. Increment distance. - distance++; - } - - valuePosition++; - } - - return false; - } - - @Override - public boolean isValidCondition(Object condition) { - return condition != null; - } - - @Override - public String toString() { - return "phrase"; - } - }; - - private static boolean isNotBlank(String str) { - if (str == null || str.isEmpty()) { - return false; - } - int strLen = str.length(); - for (int i = 0; i < strLen; i++) { - if (!Character.isWhitespace(str.charAt(i))) { - return true; - } - } - return false; - } - - // Match anything that is not either: - // 1) a unicode letter, regardless of subcategory (same as Character.isLetter), or - // 2) a unicode decimal digit number (same as Character.isDigit) - private static final Pattern TOKEN_SPLIT_PATTERN = Pattern.compile("[^\\p{L}\\p{Nd}]"); - - static List tokenize(String str) { - String[] rawTokens = TOKEN_SPLIT_PATTERN.split(str); // could contain empty strings - return Stream.of(rawTokens).filter(t -> 0 < t.length()).collect(Collectors.toList()); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/SearchUtils.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/SearchUtils.java deleted file mode 100644 index 3440c40e87a..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/SearchUtils.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -public class SearchUtils { - - /** - * Finds the Optimal - * string alignment distance – also referred to as the Damerau-Levenshtein distance – between - * two strings. - * - *

This is the number of changes needed to change one string into another (insertions, - * deletions or substitutions of a single character, or transpositions of two adjacent - * characters). - * - *

This implementation is based on the Apache Commons Lang implementation of the Levenshtein - * distance, only adding support for transpositions. - * - *

Note that this is the distance used in Lucene for {@code FuzzyTermsEnum}. Lucene itself has - * an implementation of this algorithm, but it is much less efficient in terms of space (also note - * that Lucene's implementation does not return the distance, but a similarity score based on it). - * - * @param s the first string, must not be {@code null}. - * @param t the second string, must not be {@code null}. - * @return The Optimal string alignment distance between the two strings. - * @throws IllegalArgumentException if either String input is {@code null}. - * @see org.apache.commons.lang.StringUtils#getLevenshteinDistance(String, String) - * @see - * LuceneLevenshteinDistance - */ - public static int getOptimalStringAlignmentDistance(String s, String t) { - - /* - * Code adapted from https://github.com/apache/commons-lang/blob/LANG_2_6/src/main/java/org/apache/commons/lang/StringUtils.java - * which was originally released under the Apache 2.0 license with the following copyright: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - if (s == null || t == null) { - throw new IllegalArgumentException("Strings must not be null"); - } - - int n = s.length(); // length of s - int m = t.length(); // length of t - - if (n == 0) { - return m; - } else if (m == 0) { - return n; - } - - if (n > m) { - // swap the input strings to consume less memory - String tmp = s; - s = t; - t = tmp; - n = m; - m = t.length(); - } - - // instead of maintaining the full matrix in memory, - // we use a sliding window containing 3 lines: - // the current line being written to, and - // the two previous ones. - - int d[] = new int[n + 1]; // current line in the cost matrix - int p1[] = new int[n + 1]; // first line above the current one in the cost matrix - int p2[] = new int[n + 1]; // second line above the current one in the cost matrix - int _d[]; // placeholder to assist in swapping p1, p2 and d - - // indexes into strings s and t - int i; // iterates through s - int j; // iterates through t - - for (i = 0; i <= n; i++) { - p1[i] = i; - } - - for (j = 1; j <= m; j++) { - - // jth character of t - char t_j = t.charAt(j - 1); - d[0] = j; - - for (i = 1; i <= n; i++) { - - char s_i = s.charAt(i - 1); - int cost = s_i == t_j ? 0 : 1; - - int deletion = d[i - 1] + 1; // cell to the left + 1 - int insertion = p1[i] + 1; // cell to the top + 1 - int substitution = p1[i - 1] + cost; // cell diagonally left and up + cost - - d[i] = Math.min(Math.min(deletion, insertion), substitution); - - // transposition - if (i > 1 && j > 1 && s_i == t.charAt(j - 2) && s.charAt(i - 2) == t_j) { - d[i] = Math.min(d[i], p2[i - 2] + cost); - } - } - - // swap arrays - _d = p2; - p2 = p1; - p1 = d; - d = _d; - } - - // our last action in the above loop was to switch d and p1, so p1 now - // actually has the most recent cost counts - return p1[n]; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/SinglePageGraphResultSet.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/SinglePageGraphResultSet.java deleted file mode 100644 index ff1d984d745..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/SinglePageGraphResultSet.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import com.datastax.dse.driver.api.core.graph.AsyncGraphResultSet; -import com.datastax.dse.driver.api.core.graph.GraphNode; -import com.datastax.dse.driver.api.core.graph.GraphResultSet; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Iterator; -import net.jcip.annotations.NotThreadSafe; - -@NotThreadSafe -public class SinglePageGraphResultSet implements GraphResultSet { - - private final AsyncGraphResultSet onlyPage; - - public SinglePageGraphResultSet(AsyncGraphResultSet onlyPage) { - this.onlyPage = onlyPage; - assert !onlyPage.hasMorePages(); - } - - @NonNull - @Override - public ExecutionInfo getRequestExecutionInfo() { - return onlyPage.getRequestExecutionInfo(); - } - - @NonNull - @Override - @Deprecated - public com.datastax.dse.driver.api.core.graph.GraphExecutionInfo getExecutionInfo() { - return onlyPage.getExecutionInfo(); - } - - @NonNull - @Override - public Iterator iterator() { - return onlyPage.currentPage().iterator(); - } - - @Override - public void cancel() { - onlyPage.cancel(); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/TinkerpopBufferUtil.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/TinkerpopBufferUtil.java deleted file mode 100644 index 5650d904350..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/TinkerpopBufferUtil.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import java.nio.ByteBuffer; -import org.apache.tinkerpop.gremlin.structure.io.Buffer; - -/** Mirror of {@link ByteBufUtil} for Tinkerpop Buffer's */ -public class TinkerpopBufferUtil { - - public static ByteBuffer readBytes(Buffer tinkerBuff, int size) { - ByteBuffer res = ByteBuffer.allocate(size); - tinkerBuff.readBytes(res); - res.flip(); - return res; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/AbstractDynamicGraphBinaryCustomSerializer.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/AbstractDynamicGraphBinaryCustomSerializer.java deleted file mode 100644 index 649f5310c5d..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/AbstractDynamicGraphBinaryCustomSerializer.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph.binary; - -import java.io.IOException; -import org.apache.tinkerpop.gremlin.structure.io.Buffer; -import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryReader; -import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryWriter; - -/** - * Convenience class for dynamic types implemented as Custom types in GraphBinary. This class will - * take care of handling {value_length} automatically for implementing classes. {@link - * #writeDynamicCustomValue(Object, Buffer, GraphBinaryWriter)} and {@link - * #readDynamicCustomValue(Buffer, GraphBinaryReader)} only need to handle writing the internal - * components of the custom type. - * - * @param the java type the implementing classes will encode and decode. - */ -public abstract class AbstractDynamicGraphBinaryCustomSerializer - extends AbstractSimpleGraphBinaryCustomSerializer { - protected abstract void writeDynamicCustomValue(T value, Buffer buffer, GraphBinaryWriter context) - throws IOException; - - protected abstract T readDynamicCustomValue(Buffer buffer, GraphBinaryReader context) - throws IOException; - - @Override - protected T readCustomValue(int valueLength, Buffer buffer, GraphBinaryReader context) - throws IOException { - int initialIndex = buffer.readerIndex(); - - // read actual custom value - T read = readDynamicCustomValue(buffer, context); - - // make sure we didn't read more than what was input as {value_length} - checkValueSize(valueLength, (buffer.readerIndex() - initialIndex)); - - return read; - } - - @Override - protected void writeCustomValue(T value, Buffer buffer, GraphBinaryWriter context) - throws IOException { - // Store the current writer index - final int valueLengthIndex = buffer.writerIndex(); - - // Write a dummy length that will be overwritten at the end of this method - buffer.writeInt(0); - - // Custom type's writer logic - writeDynamicCustomValue(value, buffer, context); - - // value_length = diff written - 4 bytes for the dummy length - final int valueLength = buffer.writerIndex() - valueLengthIndex - GraphBinaryUtils.sizeOfInt(); - - // Go back, write the {value_length} and then reset back the writer index - buffer.markWriterIndex().writerIndex(valueLengthIndex).writeInt(valueLength).resetWriterIndex(); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/AbstractSimpleGraphBinaryCustomSerializer.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/AbstractSimpleGraphBinaryCustomSerializer.java deleted file mode 100644 index 6dd149707e8..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/AbstractSimpleGraphBinaryCustomSerializer.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph.binary; - -import com.datastax.oss.driver.shaded.guava.common.base.Preconditions; -import java.io.IOException; -import org.apache.tinkerpop.gremlin.structure.io.Buffer; -import org.apache.tinkerpop.gremlin.structure.io.binary.DataType; -import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryReader; -import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryWriter; -import org.apache.tinkerpop.gremlin.structure.io.binary.types.CustomTypeSerializer; - -/** - * A base custom type serializer for DSE types that handles most of the boiler plate code associated - * with GraphBinary's custom types. - * - *

The full format of a custom type in GraphBinary is the following: - * - *

{type_code}{custom_type_name}{custom_type_info_length}{custom_type_info_bytes}{value_flag}{value_length}{value_bytes} - * - *

This class is made to handle - * {type_code}{custom_type_name}{custom_type_info_length}{custom_type_info_bytes}{value_flag} for - * DSE types. - * - *

Implementing classes are still in charge of encoding {value_length}{value_bytes} in the {@link - * #readCustomValue(int, Buffer, GraphBinaryReader)} implementations. - * - *

Implementing classes must override {@link CustomTypeSerializer#getTypeName()} with their own - * type name. - * - * @param the java type the implementing classes will encode and decode. - */ -abstract class AbstractSimpleGraphBinaryCustomSerializer implements CustomTypeSerializer { - AbstractSimpleGraphBinaryCustomSerializer() { - super(); - } - - protected static final String INCORRECT_VALUE_LENGTH_ERROR_MESSAGE = - "{value_length} read for this value does not correspond to the size of a '%s' value. [%s] bytes required but got [%s]"; - - protected abstract T readCustomValue(int valueLength, Buffer buffer, GraphBinaryReader context) - throws IOException; - - protected abstract void writeCustomValue(T value, Buffer buffer, GraphBinaryWriter context) - throws IOException; - - protected void checkValueSize(int lengthRequired, int lengthFound) { - Preconditions.checkArgument( - lengthFound == lengthRequired, - INCORRECT_VALUE_LENGTH_ERROR_MESSAGE, - getTypeName(), - lengthRequired, - lengthFound); - } - - @Override - public DataType getDataType() { - return DataType.CUSTOM; - } - - @Override - public T read(Buffer buffer, GraphBinaryReader context) throws IOException { - // the type serializer registry will take care of deserializing {custom_type_name} - // read {custom_type_info_length} and verify it is 0. - // See #write(T, ByteBuf, GraphBinaryWriter) for why it is set to 0 - if (context.readValue(buffer, Integer.class, false) != 0) { - throw new IOException("{custom_type_info} should not be provided for this custom type"); - } - - return readValue(buffer, context, true); - } - - @Override - public T readValue(Buffer buffer, GraphBinaryReader context, boolean nullable) - throws IOException { - if (nullable) { - // read {value_flag} - final byte valueFlag = buffer.readByte(); - - // if value is null and the value is nullable - if ((valueFlag & 1) == 1) { - return null; - } - // Note: we don't error out if the valueFlag == "value is null" and nullable == false because - // the serializer - // should have errored out at write time if that was the case. - } - - // Read the byte length of the value bytes - final int valueLength = buffer.readInt(); - - if (valueLength <= 0) { - throw new IOException(String.format("Unexpected value length: %d", valueLength)); - } - - if (valueLength > buffer.readableBytes()) { - throw new IOException( - String.format( - "Not enough readable bytes: %d bytes required for value (%d bytes available)", - valueLength, buffer.readableBytes())); - } - - // subclasses are responsible for reading {value} - return readCustomValue(valueLength, buffer, context); - } - - @Override - public void write(final T value, final Buffer buffer, final GraphBinaryWriter context) - throws IOException { - // the type serializer registry will take care of serializing {custom_type_name} - // write "{custom_type_info_length}" to 0 because we don't need it for the DSE types - context.writeValue(0, buffer, false); - writeValue(value, buffer, context, true); - } - - @Override - public void writeValue( - final T value, final Buffer buffer, final GraphBinaryWriter context, final boolean nullable) - throws IOException { - if (value == null) { - if (!nullable) { - throw new IOException("Unexpected null value when nullable is false"); - } - - // writes {value_flag} to "1" which means "the value is null" - context.writeValueFlagNull(buffer); - return; - } - - if (nullable) { - // writes {value_flag} to "0" which means "value is not null" - context.writeValueFlagNone(buffer); - } - - // sub classes will be responsible for writing {value_length} and {value_bytes} - writeCustomValue(value, buffer, context); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/ComplexTypeSerializerUtil.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/ComplexTypeSerializerUtil.java deleted file mode 100644 index bec3c78743a..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/ComplexTypeSerializerUtil.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph.binary; - -import com.datastax.dse.driver.internal.core.graph.TinkerpopBufferUtil; -import com.datastax.dse.driver.internal.core.graph.binary.buffer.DseNettyBufferFactory; -import com.datastax.dse.driver.internal.core.protocol.TinkerpopBufferPrimitiveCodec; -import com.datastax.oss.driver.api.core.data.GettableByIndex; -import com.datastax.oss.driver.api.core.data.SettableByIndex; -import com.datastax.oss.driver.api.core.type.CustomType; -import com.datastax.oss.driver.api.core.type.DataType; -import com.datastax.oss.driver.api.core.type.ListType; -import com.datastax.oss.driver.api.core.type.MapType; -import com.datastax.oss.driver.api.core.type.SetType; -import com.datastax.oss.driver.api.core.type.TupleType; -import com.datastax.oss.driver.api.core.type.UserDefinedType; -import com.datastax.oss.driver.internal.core.context.DefaultDriverContext; -import com.datastax.oss.driver.internal.core.type.DataTypeHelper; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import com.datastax.oss.protocol.internal.PrimitiveCodec; -import com.datastax.oss.protocol.internal.ProtocolConstants; -import com.datastax.oss.protocol.internal.response.result.RawType; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.nio.BufferUnderflowException; -import java.nio.ByteBuffer; -import java.util.Objects; -import org.apache.tinkerpop.gremlin.structure.io.Buffer; - -class ComplexTypeSerializerUtil { - - private static final PrimitiveCodec codec = - new TinkerpopBufferPrimitiveCodec(new DseNettyBufferFactory()); - - static void encodeTypeDefinition( - DataType type, Buffer buffer, DefaultDriverContext driverContext) { - RawType protocolType = toProtocolSpec(type); - protocolType.encode(buffer, codec, driverContext.getProtocolVersion().getCode()); - } - - static DataType decodeTypeDefinition(Buffer buffer, DefaultDriverContext driverContext) { - RawType type = RawType.decode(buffer, codec, driverContext.getProtocolVersion().getCode()); - return DataTypeHelper.fromProtocolSpec(type, driverContext); - } - - /* Tinkerpop-based encoding of UDT values, based on the UdtCoded.encode() method, but using Tinkerpop buffers directly to avoid - unnecessary NIO ByteBuffer copies. */ - static void encodeValue(@Nullable GettableByIndex value, Buffer tinkerBuff) { - if (value == null) { - return; - } - - for (int i = 0; i < value.size(); i++) { - ByteBuffer fieldBuffer = value.getBytesUnsafe(i); - if (fieldBuffer == null) { - tinkerBuff.writeInt(-1); - } else { - tinkerBuff.writeInt(fieldBuffer.remaining()); - tinkerBuff.writeBytes(fieldBuffer.duplicate()); - } - } - } - - /* This method will move forward the Tinkerpop buffer given in parameter based on the UDT value read. - Content of the method is roughly equivalent to UdtCodec.decode(), but using Tinkerpop buffers directly to avoid - unnecessary NIO ByteBuffer copies. */ - static > T decodeValue(Buffer tinkerBuff, T val, int size) { - try { - for (int i = 0; i < size; i++) { - int fieldSize = tinkerBuff.readInt(); - if (fieldSize >= 0) { - // the reassignment is to shut down the error-prone warning about ignoring return values. - val = val.setBytesUnsafe(i, TinkerpopBufferUtil.readBytes(tinkerBuff, fieldSize)); - } - } - return val; - } catch (BufferUnderflowException e) { - throw new IllegalArgumentException("Not enough bytes to deserialize a UDT value", e); - } - } - - private static RawType toProtocolSpec(DataType dataType) { - int id = dataType.getProtocolCode(); - RawType type = RawType.PRIMITIVES.get(id); - if (type != null) { - return type; - } - - switch (id) { - case ProtocolConstants.DataType.CUSTOM: - CustomType customType = ((CustomType) dataType); - type = new RawType.RawCustom(customType.getClassName()); - break; - case ProtocolConstants.DataType.LIST: - ListType listType = ((ListType) dataType); - type = new RawType.RawList(toProtocolSpec(listType.getElementType())); - break; - case ProtocolConstants.DataType.SET: - SetType setType = ((SetType) dataType); - type = new RawType.RawSet(toProtocolSpec(setType.getElementType())); - break; - case ProtocolConstants.DataType.MAP: - MapType mapType = ((MapType) dataType); - type = - new RawType.RawMap( - toProtocolSpec(mapType.getKeyType()), toProtocolSpec(mapType.getValueType())); - break; - case ProtocolConstants.DataType.TUPLE: - TupleType tupleType = ((TupleType) dataType); - ImmutableList.Builder subTypesList = - ImmutableList.builderWithExpectedSize(tupleType.getComponentTypes().size()); - for (int i = 0; i < tupleType.getComponentTypes().size(); i++) { - subTypesList.add(toProtocolSpec(tupleType.getComponentTypes().get(i))); - } - type = new RawType.RawTuple(subTypesList.build()); - break; - case ProtocolConstants.DataType.UDT: - UserDefinedType userDefinedType = ((UserDefinedType) dataType); - ImmutableMap.Builder subTypesMap = - ImmutableMap.builderWithExpectedSize(userDefinedType.getFieldNames().size()); - for (int i = 0; i < userDefinedType.getFieldTypes().size(); i++) { - subTypesMap.put( - userDefinedType.getFieldNames().get(i).asInternal(), - toProtocolSpec(userDefinedType.getFieldTypes().get(i))); - } - type = - new RawType.RawUdt( - Objects.requireNonNull(userDefinedType.getKeyspace()).asInternal(), - userDefinedType.getName().asInternal(), - subTypesMap.build()); - break; - default: - throw new IllegalArgumentException("Unsupported type: " + dataType.asCql(true, true)); - } - return type; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/CqlDurationSerializer.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/CqlDurationSerializer.java deleted file mode 100644 index 1ac97de0ef4..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/CqlDurationSerializer.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph.binary; - -import com.datastax.oss.driver.api.core.data.CqlDuration; -import java.io.IOException; -import org.apache.tinkerpop.gremlin.structure.io.Buffer; -import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryReader; -import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryWriter; - -public class CqlDurationSerializer extends AbstractSimpleGraphBinaryCustomSerializer { - - @Override - public String getTypeName() { - return GraphBinaryModule.GRAPH_BINARY_DURATION_TYPE_NAME; - } - - @Override - protected CqlDuration readCustomValue( - final int valueLength, final Buffer buffer, final GraphBinaryReader context) - throws IOException { - checkValueSize(GraphBinaryUtils.sizeOfDuration(), valueLength); - return CqlDuration.newInstance( - context.readValue(buffer, Integer.class, false), - context.readValue(buffer, Integer.class, false), - context.readValue(buffer, Long.class, false)); - } - - @Override - protected void writeCustomValue(CqlDuration value, Buffer buffer, GraphBinaryWriter context) - throws IOException { - context.writeValue(GraphBinaryUtils.sizeOfDuration(), buffer, false); - context.writeValue(value.getMonths(), buffer, false); - context.writeValue(value.getDays(), buffer, false); - context.writeValue(value.getNanoseconds(), buffer, false); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/DistanceSerializer.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/DistanceSerializer.java deleted file mode 100644 index 9e281b2b84a..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/DistanceSerializer.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph.binary; - -import com.datastax.dse.driver.api.core.data.geometry.Point; -import com.datastax.dse.driver.internal.core.data.geometry.Distance; -import java.io.IOException; -import org.apache.tinkerpop.gremlin.structure.io.Buffer; -import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryReader; -import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryWriter; - -public class DistanceSerializer extends AbstractSimpleGraphBinaryCustomSerializer { - @Override - public String getTypeName() { - return GraphBinaryModule.GRAPH_BINARY_DISTANCE_TYPE_NAME; - } - - @Override - protected Distance readCustomValue(int valueLength, Buffer buffer, GraphBinaryReader context) - throws IOException { - Point p = context.readValue(buffer, Point.class, false); - checkValueSize(GraphBinaryUtils.sizeOfDistance(p), valueLength); - return new Distance(p, context.readValue(buffer, Double.class, false)); - } - - @Override - protected void writeCustomValue(Distance value, Buffer buffer, GraphBinaryWriter context) - throws IOException { - context.writeValue(GraphBinaryUtils.sizeOfDistance(value.getCenter()), buffer, false); - context.writeValue(value.getCenter(), buffer, false); - context.writeValue(value.getRadius(), buffer, false); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/EditDistanceSerializer.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/EditDistanceSerializer.java deleted file mode 100644 index b2831040123..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/EditDistanceSerializer.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph.binary; - -import com.datastax.dse.driver.internal.core.graph.EditDistance; -import java.io.IOException; -import org.apache.tinkerpop.gremlin.structure.io.Buffer; -import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryReader; -import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryWriter; - -public class EditDistanceSerializer - extends AbstractSimpleGraphBinaryCustomSerializer { - @Override - public String getTypeName() { - return GraphBinaryModule.GRAPH_BINARY_EDIT_DISTANCE_TYPE_NAME; - } - - @Override - protected EditDistance readCustomValue(int valueLength, Buffer buffer, GraphBinaryReader context) - throws IOException { - int distance = context.readValue(buffer, Integer.class, false); - String query = context.readValue(buffer, String.class, false); - checkValueSize(GraphBinaryUtils.sizeOfEditDistance(query), valueLength); - - return new EditDistance(query, distance); - } - - @Override - protected void writeCustomValue(EditDistance value, Buffer buffer, GraphBinaryWriter context) - throws IOException { - context.writeValue(GraphBinaryUtils.sizeOfEditDistance(value.query), buffer, false); - context.writeValue(value.distance, buffer, false); - context.writeValue(value.query, buffer, false); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/GeometrySerializer.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/GeometrySerializer.java deleted file mode 100644 index 996e79c7693..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/GeometrySerializer.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph.binary; - -import com.datastax.dse.driver.api.core.data.geometry.Geometry; -import com.datastax.dse.driver.internal.core.graph.TinkerpopBufferUtil; -import java.io.IOException; -import java.nio.ByteBuffer; -import org.apache.tinkerpop.gremlin.structure.io.Buffer; -import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryReader; -import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryWriter; - -public abstract class GeometrySerializer - extends AbstractSimpleGraphBinaryCustomSerializer { - public abstract T fromWellKnownBinary(ByteBuffer buffer); - - @Override - protected T readCustomValue(int valueLength, Buffer buffer, GraphBinaryReader context) - throws IOException { - return fromWellKnownBinary(TinkerpopBufferUtil.readBytes(buffer, valueLength)); - } - - @Override - protected void writeCustomValue(T value, Buffer buffer, GraphBinaryWriter context) - throws IOException { - ByteBuffer bb = value.asWellKnownBinary(); - - // writing the {value_length} - context.writeValue(bb.remaining(), buffer, false); - buffer.writeBytes(bb); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/GraphBinaryModule.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/GraphBinaryModule.java deleted file mode 100644 index 59f966a34c2..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/GraphBinaryModule.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph.binary; - -import com.datastax.dse.driver.api.core.data.geometry.LineString; -import com.datastax.dse.driver.api.core.data.geometry.Point; -import com.datastax.dse.driver.api.core.data.geometry.Polygon; -import com.datastax.dse.driver.internal.core.data.geometry.Distance; -import com.datastax.dse.driver.internal.core.graph.EditDistance; -import com.datastax.dse.driver.internal.core.graph.binary.buffer.DseNettyBufferFactory; -import com.datastax.oss.driver.api.core.data.CqlDuration; -import com.datastax.oss.driver.api.core.data.TupleValue; -import com.datastax.oss.driver.api.core.data.UdtValue; -import com.datastax.oss.driver.internal.core.context.DefaultDriverContext; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.UnpooledByteBufAllocator; -import java.io.IOException; -import org.apache.tinkerpop.gremlin.structure.io.Buffer; -import org.apache.tinkerpop.gremlin.structure.io.BufferFactory; -import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryReader; -import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryWriter; -import org.apache.tinkerpop.gremlin.structure.io.binary.TypeSerializerRegistry; -import org.javatuples.Pair; - -public class GraphBinaryModule { - public static final UnpooledByteBufAllocator ALLOCATOR = new UnpooledByteBufAllocator(false); - private static final BufferFactory FACTORY = new DseNettyBufferFactory(); - - static final String GRAPH_BINARY_POINT_TYPE_NAME = "driver.dse.geometry.Point"; - static final String GRAPH_BINARY_LINESTRING_TYPE_NAME = "driver.dse.geometry.LineString"; - static final String GRAPH_BINARY_POLYGON_TYPE_NAME = "driver.dse.geometry.Polygon"; - static final String GRAPH_BINARY_DISTANCE_TYPE_NAME = "driver.dse.geometry.Distance"; - static final String GRAPH_BINARY_DURATION_TYPE_NAME = "driver.core.Duration"; - static final String GRAPH_BINARY_EDIT_DISTANCE_TYPE_NAME = "driver.dse.search.EditDistance"; - static final String GRAPH_BINARY_TUPLE_VALUE_TYPE_NAME = "driver.core.TupleValue"; - static final String GRAPH_BINARY_UDT_VALUE_TYPE_NAME = "driver.core.UDTValue"; - static final String GRAPH_BINARY_PAIR_TYPE_NAME = "org.javatuples.Pair"; - - private final GraphBinaryReader reader; - private final GraphBinaryWriter writer; - - public GraphBinaryModule(GraphBinaryReader reader, GraphBinaryWriter writer) { - this.reader = reader; - this.writer = writer; - } - - public static TypeSerializerRegistry createDseTypeSerializerRegistry( - DefaultDriverContext driverContext) { - return TypeSerializerRegistry.build() - .addCustomType(CqlDuration.class, new CqlDurationSerializer()) - .addCustomType(Point.class, new PointSerializer()) - .addCustomType(LineString.class, new LineStringSerializer()) - .addCustomType(Polygon.class, new PolygonSerializer()) - .addCustomType(Distance.class, new DistanceSerializer()) - .addCustomType(EditDistance.class, new EditDistanceSerializer()) - .addCustomType(TupleValue.class, new TupleValueSerializer(driverContext)) - .addCustomType(UdtValue.class, new UdtValueSerializer(driverContext)) - .addCustomType(Pair.class, new PairSerializer()) - .create(); - } - - @SuppressWarnings("TypeParameterUnusedInFormals") - public T deserialize(final Buffer buffer) throws IOException { - return reader.read(buffer); - } - - public Buffer serialize(final T value) throws IOException { - return serialize(value, FACTORY.create(ALLOCATOR.heapBuffer())); - } - - public Buffer serialize(final T value, final Buffer buffer) throws IOException { - try { - writer.write(value, buffer); - return buffer; - } catch (Exception e) { - buffer.release(); - throw e; - } - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/GraphBinaryUtils.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/GraphBinaryUtils.java deleted file mode 100644 index 42283cd5167..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/GraphBinaryUtils.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph.binary; - -import com.datastax.dse.driver.api.core.data.geometry.Point; -import java.nio.charset.StandardCharsets; - -class GraphBinaryUtils { - static int sizeOfInt() { - return 4; - } - - static int sizeOfLong() { - return 8; - } - - static int sizeOfDouble() { - return 8; - } - - static int sizeOfPoint(Point point) { - return point.asWellKnownBinary().remaining(); - } - - /* assumes UTF8 */ - static int sizeOfString(String s) { - // length + data length - return sizeOfInt() + s.getBytes(StandardCharsets.UTF_8).length; - } - - static int sizeOfDuration() { - return sizeOfInt() + sizeOfInt() + sizeOfLong(); - } - - static int sizeOfDistance(Point point) { - return sizeOfPoint(point) + sizeOfDouble(); - } - - static int sizeOfEditDistance(String s) { - return sizeOfInt() + sizeOfString(s); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/LineStringSerializer.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/LineStringSerializer.java deleted file mode 100644 index 4dfa8f8f0f1..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/LineStringSerializer.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph.binary; - -import com.datastax.dse.driver.api.core.data.geometry.LineString; -import java.nio.ByteBuffer; - -public class LineStringSerializer extends GeometrySerializer { - @Override - public String getTypeName() { - return GraphBinaryModule.GRAPH_BINARY_LINESTRING_TYPE_NAME; - } - - @Override - public LineString fromWellKnownBinary(ByteBuffer buffer) { - return LineString.fromWellKnownBinary(buffer); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/PairSerializer.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/PairSerializer.java deleted file mode 100644 index 3f13dd5b3a0..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/PairSerializer.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph.binary; - -import java.io.IOException; -import org.apache.tinkerpop.gremlin.structure.io.Buffer; -import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryReader; -import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryWriter; -import org.javatuples.Pair; - -public class PairSerializer extends AbstractDynamicGraphBinaryCustomSerializer { - - @Override - public String getTypeName() { - return GraphBinaryModule.GRAPH_BINARY_PAIR_TYPE_NAME; - } - - @Override - protected Pair readDynamicCustomValue(Buffer buffer, GraphBinaryReader context) - throws IOException { - return new Pair<>(context.read(buffer), context.read(buffer)); - } - - @Override - protected void writeDynamicCustomValue(Pair value, Buffer buffer, GraphBinaryWriter context) - throws IOException { - context.write(value.getValue0(), buffer); - context.write(value.getValue1(), buffer); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/PointSerializer.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/PointSerializer.java deleted file mode 100644 index 2204b0da073..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/PointSerializer.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph.binary; - -import com.datastax.dse.driver.api.core.data.geometry.Point; -import java.nio.ByteBuffer; - -public class PointSerializer extends GeometrySerializer { - - @Override - public String getTypeName() { - return GraphBinaryModule.GRAPH_BINARY_POINT_TYPE_NAME; - } - - @Override - public Point fromWellKnownBinary(ByteBuffer buffer) { - return Point.fromWellKnownBinary(buffer); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/PolygonSerializer.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/PolygonSerializer.java deleted file mode 100644 index 8e3bc67838a..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/PolygonSerializer.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph.binary; - -import com.datastax.dse.driver.api.core.data.geometry.Polygon; -import java.nio.ByteBuffer; - -public class PolygonSerializer extends GeometrySerializer { - @Override - public String getTypeName() { - return GraphBinaryModule.GRAPH_BINARY_POLYGON_TYPE_NAME; - } - - @Override - public Polygon fromWellKnownBinary(ByteBuffer buffer) { - return Polygon.fromWellKnownBinary(buffer); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/TupleValueSerializer.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/TupleValueSerializer.java deleted file mode 100644 index b7c6fc2098d..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/TupleValueSerializer.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph.binary; - -import com.datastax.oss.driver.api.core.data.TupleValue; -import com.datastax.oss.driver.api.core.type.DataType; -import com.datastax.oss.driver.api.core.type.TupleType; -import com.datastax.oss.driver.internal.core.context.DefaultDriverContext; -import java.io.IOException; -import org.apache.tinkerpop.gremlin.structure.io.Buffer; -import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryReader; -import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryWriter; - -public class TupleValueSerializer extends AbstractDynamicGraphBinaryCustomSerializer { - - private final DefaultDriverContext driverContext; - - public TupleValueSerializer(DefaultDriverContext driverContext) { - this.driverContext = driverContext; - } - - @Override - public String getTypeName() { - return GraphBinaryModule.GRAPH_BINARY_TUPLE_VALUE_TYPE_NAME; - } - - @Override - public TupleValue readDynamicCustomValue(Buffer buffer, GraphBinaryReader context) - throws IOException { - // read the type first - DataType type = ComplexTypeSerializerUtil.decodeTypeDefinition(buffer, driverContext); - - assert type instanceof TupleType - : "GraphBinary TupleValue deserializer was called on a value that is not encoded as a TupleValue."; - - TupleType tupleType = (TupleType) type; - TupleValue value = tupleType.newValue(); - - // then decode the values from the buffer - return ComplexTypeSerializerUtil.decodeValue( - buffer, value, tupleType.getComponentTypes().size()); - } - - @Override - public void writeDynamicCustomValue(TupleValue value, Buffer buffer, GraphBinaryWriter context) - throws IOException { - // write type first in native protocol - ComplexTypeSerializerUtil.encodeTypeDefinition(value.getType(), buffer, driverContext); - - // write value after - ComplexTypeSerializerUtil.encodeValue(value, buffer); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/UdtValueSerializer.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/UdtValueSerializer.java deleted file mode 100644 index 3e617ebf926..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/UdtValueSerializer.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph.binary; - -import com.datastax.oss.driver.api.core.data.UdtValue; -import com.datastax.oss.driver.api.core.type.DataType; -import com.datastax.oss.driver.api.core.type.UserDefinedType; -import com.datastax.oss.driver.internal.core.context.DefaultDriverContext; -import java.io.IOException; -import org.apache.tinkerpop.gremlin.structure.io.Buffer; -import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryReader; -import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryWriter; - -public class UdtValueSerializer extends AbstractDynamicGraphBinaryCustomSerializer { - private final DefaultDriverContext driverContext; - - public UdtValueSerializer(DefaultDriverContext driverContext) { - this.driverContext = driverContext; - } - - @Override - public String getTypeName() { - return GraphBinaryModule.GRAPH_BINARY_UDT_VALUE_TYPE_NAME; - } - - @Override - public UdtValue readDynamicCustomValue(Buffer buffer, GraphBinaryReader context) - throws IOException { - // read type definition first - DataType driverType = ComplexTypeSerializerUtil.decodeTypeDefinition(buffer, driverContext); - - assert driverType instanceof UserDefinedType - : "GraphBinary UdtValue deserializer was called on a value that is not encoded as a UdtValue."; - - UserDefinedType userDefinedType = (UserDefinedType) driverType; - UdtValue value = userDefinedType.newValue(); - - // then read values - return ComplexTypeSerializerUtil.decodeValue( - buffer, value, userDefinedType.getFieldTypes().size()); - } - - @Override - public void writeDynamicCustomValue(UdtValue value, Buffer buffer, GraphBinaryWriter context) - throws IOException { - // write type first in native protocol format - ComplexTypeSerializerUtil.encodeTypeDefinition(value.getType(), buffer, driverContext); - // write value after - ComplexTypeSerializerUtil.encodeValue(value, buffer); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/buffer/DseNettyBuffer.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/buffer/DseNettyBuffer.java deleted file mode 100644 index 590ac2e9be2..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/buffer/DseNettyBuffer.java +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph.binary.buffer; - -import io.netty.buffer.ByteBuf; -import java.io.IOException; -import java.io.OutputStream; -import java.nio.ByteBuffer; -import org.apache.tinkerpop.gremlin.structure.io.Buffer; - -/** - * Internal impl of Tinkerpop Buffers. We implement an internal type here to allow for this class to - * use shaded Netty types (without bringing all of Tinkerpop into the shaded JAR). The impl is based - * on the initial impl of {@link NettyBuffer} but we don't guarantee that this class will mirror - * changes to that class over time. - */ -final class DseNettyBuffer implements Buffer { - private final ByteBuf buffer; - - /** - * Creates a new instance. - * - * @param buffer The buffer to wrap. - */ - DseNettyBuffer(ByteBuf buffer) { - if (buffer == null) { - throw new IllegalArgumentException("buffer can't be null"); - } - - this.buffer = buffer; - } - - @Override - public int readableBytes() { - return this.buffer.readableBytes(); - } - - @Override - public int readerIndex() { - return this.buffer.readerIndex(); - } - - @Override - public Buffer readerIndex(final int readerIndex) { - this.buffer.readerIndex(readerIndex); - return this; - } - - @Override - public int writerIndex() { - return this.buffer.writerIndex(); - } - - @Override - public Buffer writerIndex(final int writerIndex) { - this.buffer.writerIndex(writerIndex); - return this; - } - - @Override - public Buffer markWriterIndex() { - this.buffer.markWriterIndex(); - return this; - } - - @Override - public Buffer resetWriterIndex() { - this.buffer.resetWriterIndex(); - return this; - } - - @Override - public int capacity() { - return this.buffer.capacity(); - } - - @Override - public boolean isDirect() { - return this.buffer.isDirect(); - } - - @Override - public boolean readBoolean() { - return this.buffer.readBoolean(); - } - - @Override - public byte readByte() { - return this.buffer.readByte(); - } - - @Override - public short readShort() { - return this.buffer.readShort(); - } - - @Override - public int readInt() { - return this.buffer.readInt(); - } - - @Override - public long readLong() { - return this.buffer.readLong(); - } - - @Override - public float readFloat() { - return this.buffer.readFloat(); - } - - @Override - public double readDouble() { - return this.buffer.readDouble(); - } - - @Override - public Buffer readBytes(final byte[] destination) { - this.buffer.readBytes(destination); - return this; - } - - @Override - public Buffer readBytes(final byte[] destination, final int dstIndex, final int length) { - this.buffer.readBytes(destination, dstIndex, length); - return this; - } - - @Override - public Buffer readBytes(final ByteBuffer dst) { - this.buffer.readBytes(dst); - return this; - } - - @Override - public Buffer readBytes(final OutputStream out, final int length) throws IOException { - this.buffer.readBytes(out, length); - return this; - } - - @Override - public Buffer writeBoolean(final boolean value) { - this.buffer.writeBoolean(value); - return this; - } - - @Override - public Buffer writeByte(final int value) { - this.buffer.writeByte(value); - return this; - } - - @Override - public Buffer writeShort(final int value) { - this.buffer.writeShort(value); - return this; - } - - @Override - public Buffer writeInt(final int value) { - this.buffer.writeInt(value); - return this; - } - - @Override - public Buffer writeLong(final long value) { - this.buffer.writeLong(value); - return this; - } - - @Override - public Buffer writeFloat(final float value) { - this.buffer.writeFloat(value); - return this; - } - - @Override - public Buffer writeDouble(final double value) { - this.buffer.writeDouble(value); - return this; - } - - @Override - public Buffer writeBytes(final byte[] src) { - this.buffer.writeBytes(src); - return this; - } - - @Override - public Buffer writeBytes(final ByteBuffer src) { - this.buffer.writeBytes(src); - return this; - } - - @Override - public Buffer writeBytes(byte[] src, final int srcIndex, final int length) { - this.buffer.writeBytes(src, srcIndex, length); - return this; - } - - @Override - public boolean release() { - return this.buffer.release(); - } - - @Override - public Buffer retain() { - this.buffer.retain(); - return this; - } - - @Override - public int referenceCount() { - return this.buffer.refCnt(); - } - - @Override - public ByteBuffer[] nioBuffers() { - return this.buffer.nioBuffers(); - } - - @Override - public ByteBuffer nioBuffer() { - return this.buffer.nioBuffer(); - } - - @Override - public ByteBuffer nioBuffer(final int index, final int length) { - return this.buffer.nioBuffer(index, length); - } - - @Override - public ByteBuffer[] nioBuffers(final int index, final int length) { - return this.buffer.nioBuffers(index, length); - } - - @Override - public int nioBufferCount() { - return this.buffer.nioBufferCount(); - } - - @Override - public Buffer getBytes(final int index, final byte[] dst) { - this.buffer.getBytes(index, dst); - return this; - } - - /** Returns the underlying buffer. */ - public ByteBuf getUnderlyingBuffer() { - return this.buffer; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/buffer/DseNettyBufferFactory.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/buffer/DseNettyBufferFactory.java deleted file mode 100644 index 57ee3cb1a9d..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/binary/buffer/DseNettyBufferFactory.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph.binary.buffer; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; -import io.netty.buffer.CompositeByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.buffer.UnpooledByteBufAllocator; -import java.nio.ByteBuffer; -import java.util.function.Supplier; -import org.apache.tinkerpop.gremlin.structure.io.Buffer; -import org.apache.tinkerpop.gremlin.structure.io.BufferFactory; - -/** - * Internal BufferFactory impl for creation of Tinkerpop buffers. We implement an internal type here - * to allow for this class to use shaded Netty types (without bringing all of Tinkerpop into the - * shaded JAR). The impl is based on the initial impl of {@code - * org.apache.tinkerpop.gremlin.driver.ser.NettyBufferFactory} but we don't guarantee that this - * class will mirror changes to that class over time. - */ -public class DseNettyBufferFactory implements BufferFactory { - - private static final ByteBufAllocator DEFAULT_ALLOCATOR = new UnpooledByteBufAllocator(false); - - private final ByteBufAllocator allocator; - - public DseNettyBufferFactory() { - this.allocator = DEFAULT_ALLOCATOR; - } - - public DseNettyBufferFactory(ByteBufAllocator allocator) { - this.allocator = allocator; - } - - @Override - public Buffer create(final ByteBuf value) { - return new DseNettyBuffer(value); - } - - @Override - public Buffer wrap(final ByteBuffer value) { - return create(Unpooled.wrappedBuffer(value)); - } - - public Buffer heap() { - return create(allocator.heapBuffer()); - } - - public Buffer heap(int initialSize) { - return create(allocator.heapBuffer(initialSize)); - } - - public Buffer heap(int initialSize, int maxSize) { - return create(allocator.heapBuffer(initialSize, maxSize)); - } - - public Buffer io() { - return create(allocator.ioBuffer()); - } - - public Buffer io(int initialSize) { - return create(allocator.ioBuffer(initialSize)); - } - - public Buffer io(int initialSize, int maxSize) { - return create(allocator.ioBuffer(initialSize, maxSize)); - } - - public Buffer direct() { - return create(allocator.directBuffer()); - } - - public Buffer direct(int initialSize) { - return create(allocator.directBuffer(initialSize)); - } - - public Buffer direct(int initialSize, int maxSize) { - return create(allocator.directBuffer(initialSize, maxSize)); - } - - public Buffer composite(ByteBuf... components) { - - CompositeByteBuf buff = allocator.compositeBuffer(components.length); - buff.addComponents(components); - return create(buff); - } - - public Buffer composite(Buffer... components) { - ByteBuf[] nettyBufs = new ByteBuf[components.length]; - for (int i = 0; i < components.length; ++i) { - if (!(components[i] instanceof DseNettyBuffer)) { - throw new IllegalArgumentException("Can only concatenate DseNettyBuffer instances"); - } - nettyBufs[i] = ((DseNettyBuffer) components[i]).getUnderlyingBuffer(); - } - return composite(nettyBufs); - } - - public Buffer withBytes(int... bytes) { - return withBytes(this::heap, bytes); - } - - public Buffer withBytes(Supplier supplier, int... bytes) { - Buffer buff = supplier.get(); - for (int val : bytes) { - buff.writeByte(val); - } - return buff; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/reactive/DefaultReactiveGraphNode.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/reactive/DefaultReactiveGraphNode.java deleted file mode 100644 index fda0eed5333..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/reactive/DefaultReactiveGraphNode.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph.reactive; - -import com.datastax.dse.driver.api.core.graph.GraphNode; -import com.datastax.dse.driver.api.core.graph.reactive.ReactiveGraphNode; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import com.datastax.oss.driver.api.core.type.reflect.GenericType; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.List; -import java.util.Map; -import java.util.Set; -import net.jcip.annotations.NotThreadSafe; -import org.apache.tinkerpop.gremlin.process.traversal.Path; -import org.apache.tinkerpop.gremlin.structure.Edge; -import org.apache.tinkerpop.gremlin.structure.Property; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.apache.tinkerpop.gremlin.structure.VertexProperty; - -@NotThreadSafe -class DefaultReactiveGraphNode implements ReactiveGraphNode { - - private final GraphNode graphNode; - private final ExecutionInfo executionInfo; - - DefaultReactiveGraphNode(@NonNull GraphNode graphNode, @NonNull ExecutionInfo executionInfo) { - this.graphNode = graphNode; - this.executionInfo = executionInfo; - } - - @NonNull - @Override - public ExecutionInfo getExecutionInfo() { - return executionInfo; - } - - @Override - public boolean isNull() { - return graphNode.isNull(); - } - - @Override - public boolean isMap() { - return graphNode.isMap(); - } - - @Override - public Iterable keys() { - return graphNode.keys(); - } - - @Override - public GraphNode getByKey(Object key) { - return graphNode.getByKey(key); - } - - @Override - public Map asMap() { - return graphNode.asMap(); - } - - @Override - public boolean isList() { - return graphNode.isList(); - } - - @Override - public int size() { - return graphNode.size(); - } - - @Override - public GraphNode getByIndex(int index) { - return graphNode.getByIndex(index); - } - - @Override - public List asList() { - return graphNode.asList(); - } - - @Override - public boolean isValue() { - return graphNode.isValue(); - } - - @Override - public int asInt() { - return graphNode.asInt(); - } - - @Override - public boolean asBoolean() { - return graphNode.asBoolean(); - } - - @Override - public long asLong() { - return graphNode.asLong(); - } - - @Override - public double asDouble() { - return graphNode.asDouble(); - } - - @Override - public String asString() { - return graphNode.asString(); - } - - @Override - public ResultT as(Class clazz) { - return graphNode.as(clazz); - } - - @Override - public ResultT as(GenericType type) { - return graphNode.as(type); - } - - @Override - public boolean isVertex() { - return graphNode.isVertex(); - } - - @Override - public Vertex asVertex() { - return graphNode.asVertex(); - } - - @Override - public boolean isEdge() { - return graphNode.isEdge(); - } - - @Override - public Edge asEdge() { - return graphNode.asEdge(); - } - - @Override - public boolean isPath() { - return graphNode.isPath(); - } - - @Override - public Path asPath() { - return graphNode.asPath(); - } - - @Override - public boolean isProperty() { - return graphNode.isProperty(); - } - - @Override - public Property asProperty() { - return graphNode.asProperty(); - } - - @Override - public boolean isVertexProperty() { - return graphNode.isVertexProperty(); - } - - @Override - public VertexProperty asVertexProperty() { - return graphNode.asVertexProperty(); - } - - @Override - public boolean isSet() { - return graphNode.isSet(); - } - - @Override - public Set asSet() { - return graphNode.asSet(); - } - - @Override - public String toString() { - return "DefaultReactiveGraphNode{graphNode=" - + graphNode - + ", executionInfo=" - + executionInfo - + '}'; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/reactive/DefaultReactiveGraphResultSet.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/reactive/DefaultReactiveGraphResultSet.java deleted file mode 100644 index 137e44e4d95..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/reactive/DefaultReactiveGraphResultSet.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph.reactive; - -import com.datastax.dse.driver.api.core.graph.AsyncGraphResultSet; -import com.datastax.dse.driver.api.core.graph.reactive.ReactiveGraphNode; -import com.datastax.dse.driver.api.core.graph.reactive.ReactiveGraphResultSet; -import com.datastax.dse.driver.internal.core.cql.reactive.EmptySubscription; -import com.datastax.dse.driver.internal.core.cql.reactive.SimpleUnicastProcessor; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Objects; -import java.util.concurrent.Callable; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.atomic.AtomicBoolean; -import net.jcip.annotations.ThreadSafe; -import org.reactivestreams.Publisher; -import org.reactivestreams.Subscriber; - -@ThreadSafe -public class DefaultReactiveGraphResultSet implements ReactiveGraphResultSet { - - private final Callable> firstPage; - - private final AtomicBoolean alreadySubscribed = new AtomicBoolean(false); - - private final SimpleUnicastProcessor executionInfosPublisher = - new SimpleUnicastProcessor<>(); - - public DefaultReactiveGraphResultSet(Callable> firstPage) { - this.firstPage = firstPage; - } - - @Override - public void subscribe(@NonNull Subscriber subscriber) { - // As per rule 1.9, we need to throw an NPE if subscriber is null - Objects.requireNonNull(subscriber, "Subscriber cannot be null"); - // As per rule 1.11, this publisher is allowed to support only one subscriber. - if (alreadySubscribed.compareAndSet(false, true)) { - ReactiveGraphResultSetSubscription subscription = - new ReactiveGraphResultSetSubscription(subscriber, executionInfosPublisher); - try { - subscriber.onSubscribe(subscription); - // must be done after onSubscribe - subscription.start(firstPage); - } catch (Throwable t) { - // As per rule 2.13: In the case that this rule is violated, - // any associated Subscription to the Subscriber MUST be considered as - // cancelled, and the caller MUST raise this error condition in a fashion - // that is adequate for the runtime environment. - subscription.doOnError( - new IllegalStateException( - subscriber - + " violated the Reactive Streams rule 2.13 by throwing an exception from onSubscribe.", - t)); - } - } else { - subscriber.onSubscribe(EmptySubscription.INSTANCE); - subscriber.onError( - new IllegalStateException("This publisher does not support multiple subscriptions")); - } - // As per 2.13, this method must return normally (i.e. not throw) - } - - @NonNull - @Override - public Publisher getExecutionInfos() { - return executionInfosPublisher; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/reactive/FailedReactiveGraphResultSet.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/reactive/FailedReactiveGraphResultSet.java deleted file mode 100644 index 45bbd8c62b0..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/reactive/FailedReactiveGraphResultSet.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph.reactive; - -import com.datastax.dse.driver.api.core.graph.reactive.ReactiveGraphNode; -import com.datastax.dse.driver.api.core.graph.reactive.ReactiveGraphResultSet; -import com.datastax.dse.driver.internal.core.cql.reactive.FailedPublisher; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import edu.umd.cs.findbugs.annotations.NonNull; -import org.reactivestreams.Publisher; - -public class FailedReactiveGraphResultSet extends FailedPublisher - implements ReactiveGraphResultSet { - - public FailedReactiveGraphResultSet(Throwable error) { - super(error); - } - - @NonNull - @Override - public Publisher getExecutionInfos() { - return new FailedPublisher<>(error); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/reactive/ReactiveGraphRequestProcessor.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/reactive/ReactiveGraphRequestProcessor.java deleted file mode 100644 index ed2cd28926c..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/reactive/ReactiveGraphRequestProcessor.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph.reactive; - -import com.datastax.dse.driver.api.core.graph.GraphStatement; -import com.datastax.dse.driver.api.core.graph.reactive.ReactiveGraphResultSet; -import com.datastax.dse.driver.internal.core.graph.GraphRequestAsyncProcessor; -import com.datastax.oss.driver.api.core.session.Request; -import com.datastax.oss.driver.api.core.type.reflect.GenericType; -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import com.datastax.oss.driver.internal.core.session.DefaultSession; -import com.datastax.oss.driver.internal.core.session.RequestProcessor; -import edu.umd.cs.findbugs.annotations.NonNull; -import net.jcip.annotations.ThreadSafe; - -@ThreadSafe -public class ReactiveGraphRequestProcessor - implements RequestProcessor, ReactiveGraphResultSet> { - - public static final GenericType REACTIVE_GRAPH_RESULT_SET = - GenericType.of(ReactiveGraphResultSet.class); - - private final GraphRequestAsyncProcessor asyncGraphProcessor; - - public ReactiveGraphRequestProcessor(@NonNull GraphRequestAsyncProcessor asyncGraphProcessor) { - this.asyncGraphProcessor = asyncGraphProcessor; - } - - @Override - public boolean canProcess(Request request, GenericType resultType) { - return request instanceof GraphStatement && resultType.equals(REACTIVE_GRAPH_RESULT_SET); - } - - @Override - public ReactiveGraphResultSet process( - GraphStatement request, - DefaultSession session, - InternalDriverContext context, - String sessionLogPrefix) { - return new DefaultReactiveGraphResultSet( - () -> asyncGraphProcessor.process(request, session, context, sessionLogPrefix)); - } - - @Override - public ReactiveGraphResultSet newFailure(RuntimeException error) { - return new FailedReactiveGraphResultSet(error); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/reactive/ReactiveGraphResultSetSubscription.java b/core/src/main/java/com/datastax/dse/driver/internal/core/graph/reactive/ReactiveGraphResultSetSubscription.java deleted file mode 100644 index c3234d74ebc..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/graph/reactive/ReactiveGraphResultSetSubscription.java +++ /dev/null @@ -1,475 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph.reactive; - -import com.datastax.dse.driver.api.core.graph.AsyncGraphResultSet; -import com.datastax.dse.driver.api.core.graph.reactive.ReactiveGraphNode; -import com.datastax.dse.driver.internal.core.cql.reactive.ReactiveOperators; -import com.datastax.dse.driver.internal.core.util.concurrent.BoundedConcurrentQueue; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import com.datastax.oss.driver.internal.core.util.concurrent.CompletableFutures; -import com.datastax.oss.driver.shaded.guava.common.collect.Iterators; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.util.Collections; -import java.util.Iterator; -import java.util.Objects; -import java.util.concurrent.Callable; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionException; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; -import net.jcip.annotations.ThreadSafe; -import org.reactivestreams.Subscriber; -import org.reactivestreams.Subscription; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * This class is very similar to {@link - * com.datastax.dse.driver.internal.core.cql.reactive.ReactiveResultSetSubscription}. It exists - * merely because {@link AsyncGraphResultSet} is not a subtype of {@link - * com.datastax.oss.driver.api.core.AsyncPagingIterable} and thus it would be difficult to re-use - * ReactiveResultSetSubscription for graph result sets. - */ -@ThreadSafe -public class ReactiveGraphResultSetSubscription implements Subscription { - - private static final Logger LOG = - LoggerFactory.getLogger(ReactiveGraphResultSetSubscription.class); - - private static final int MAX_ENQUEUED_PAGES = 4; - - /** Tracks the number of items requested by the subscriber. */ - private final AtomicLong requested = new AtomicLong(0); - - /** The pages received so far, with a maximum of MAX_ENQUEUED_PAGES elements. */ - private final BoundedConcurrentQueue pages = - new BoundedConcurrentQueue<>(MAX_ENQUEUED_PAGES); - - /** - * Used to signal that a thread is currently draining, i.e., emitting items to the subscriber. - * When it is zero, that means there is no ongoing emission. This mechanism effectively serializes - * access to the drain() method, and also keeps track of missed attempts to enter it, since each - * thread that attempts to drain will increment this counter. - * - * @see #drain() - */ - private final AtomicInteger draining = new AtomicInteger(0); - - /** - * Waited upon by the driver and completed when the subscriber requests its first item. - * - *

Used to hold off emitting results until the subscriber issues its first request for items. - * Since this future is only completed from {@link #request(long)}, this effectively conditions - * the enqueueing of the first page to the reception of the subscriber's first request. - * - *

This mechanism avoids sending terminal signals before a request is made when the stream is - * empty. Note that as per 2.9, "a Subscriber MUST be prepared to receive an onComplete signal - * with or without a preceding Subscription.request(long n) call." However, the TCK considers it - * as unfair behavior. - * - * @see #start(Callable) - * @see #request(long) - */ - private final CompletableFuture firstSubscriberRequestArrived = new CompletableFuture<>(); - - /** non-final because it has to be de-referenced, see {@link #clear()}. */ - private volatile Subscriber mainSubscriber; - - private volatile Subscriber executionInfosSubscriber; - - /** - * Set to true when the subscription is cancelled, which happens when an error is encountered, - * when the result set is fully consumed and the subscription terminates, or when the subscriber - * manually calls {@link #cancel()}. - */ - private volatile boolean cancelled = false; - - ReactiveGraphResultSetSubscription( - @NonNull Subscriber mainSubscriber, - @NonNull Subscriber executionInfosSubscriber) { - this.mainSubscriber = mainSubscriber; - this.executionInfosSubscriber = executionInfosSubscriber; - } - - /** - * Starts the query execution. - * - *

Must be called immediately after creating the subscription, but after {@link - * Subscriber#onSubscribe(Subscription)}. - * - * @param firstPage The future that, when complete, will produce the first page. - */ - void start(@NonNull Callable> firstPage) { - firstSubscriberRequestArrived.thenAccept( - (aVoid) -> fetchNextPageAndEnqueue(new Page(firstPage))); - } - - @Override - public void request(long n) { - // As per 3.6: after the Subscription is cancelled, additional - // calls to request() MUST be NOPs. - if (!cancelled) { - if (n < 1) { - // Validate request as per rule 3.9 - doOnError( - new IllegalArgumentException( - mainSubscriber - + " violated the Reactive Streams rule 3.9 by requesting a non-positive number of elements.")); - } else { - // As per rule 3.17, when demand overflows Long.MAX_VALUE - // it can be treated as "effectively unbounded" - ReactiveOperators.addCap(requested, n); - // Set the first future to true if not done yet. - // This will make the first page of results ready for consumption, - // see start(). - // As per 2.7 it is the subscriber's responsibility to provide - // external synchronization when calling request(), - // so the check-then-act idiom below is good enough - // (and besides, complete() is idempotent). - if (!firstSubscriberRequestArrived.isDone()) { - firstSubscriberRequestArrived.complete(null); - } - drain(); - } - } - } - - @Override - public void cancel() { - // As per 3.5: Subscription.cancel() MUST respect the responsiveness of - // its caller by returning in a timely manner, MUST be idempotent and - // MUST be thread-safe. - if (!cancelled) { - cancelled = true; - if (draining.getAndIncrement() == 0) { - // If nobody is draining, clear now; - // otherwise, the draining thread will notice - // that the cancelled flag was set - // and will clear for us. - clear(); - } - } - } - - /** - * Attempts to drain available items, i.e. emit them to the subscriber. - * - *

Access to this method is serialized by the field {@link #draining}: only one thread at a - * time can drain, but threads that attempt to drain while other thread is already draining - * increment that field; the draining thread, before finishing its work, checks for such failed - * attempts and triggers another round of draining if that was the case. - * - *

The loop is interrupted when 1) the requested amount has been met or 2) when there are no - * more items readily available or 3) the subscription has been cancelled. - * - *

The loop also checks for stream exhaustion and emits a terminal {@code onComplete} signal in - * this case. - * - *

This method may run on a driver IO thread when invoked from {@link - * #fetchNextPageAndEnqueue(Page)}, or on a subscriber thread, when invoked from {@link - * #request(long)}. - */ - @SuppressWarnings("ConditionalBreakInInfiniteLoop") - private void drain() { - // As per 3.4: this method SHOULD respect the responsiveness - // of its caller by returning in a timely manner. - // We accomplish this by a wait-free implementation. - if (draining.getAndIncrement() != 0) { - // Someone else is already draining, so do nothing, - // the other thread will notice that we attempted to drain. - // This also allows to abide by rule 3.3 and avoid - // cycles such as request() -> onNext() -> request() etc. - return; - } - int missed = 1; - // Note: when termination is detected inside this loop, - // we MUST call clear() manually. - for (; ; ) { - // The requested number of items at this point - long r = requested.get(); - // The number of items emitted thus far - long emitted = 0L; - while (emitted != r) { - if (cancelled) { - clear(); - return; - } - Object result; - try { - result = tryNext(); - } catch (Throwable t) { - doOnError(t); - clear(); - return; - } - if (result == null) { - break; - } - if (result instanceof Throwable) { - doOnError((Throwable) result); - clear(); - return; - } - doOnNext((ReactiveGraphNode) result); - emitted++; - } - if (isExhausted()) { - doOnComplete(); - clear(); - return; - } - if (cancelled) { - clear(); - return; - } - if (emitted != 0) { - // if any item was emitted, adjust the requested field - ReactiveOperators.subCap(requested, emitted); - } - // if another thread tried to call drain() while we were busy, - // then we should do another drain round. - missed = draining.addAndGet(-missed); - if (missed == 0) { - break; - } - } - } - - /** - * Tries to return the next item, if one is readily available, and returns {@code null} otherwise. - * - *

Cannot run concurrently due to the {@link #draining} field. - */ - @Nullable - private Object tryNext() { - Page current = pages.peek(); - if (current != null) { - if (current.hasMoreRows()) { - return current.nextRow(); - } else if (current.hasMorePages()) { - // Discard current page as it is consumed. - // Don't discard the last page though as we need it - // to test isExhausted(). It will be GC'ed when a terminal signal - // is issued anyway, so that's no big deal. - if (pages.poll() == null) { - throw new AssertionError("Queue is empty, this should not happen"); - } - current = pages.peek(); - // if the next page is readily available, - // serve its first row now, no need to wait - // for the next drain. - if (current != null && current.hasMoreRows()) { - return current.nextRow(); - } - } - } - // No items available right now. - return null; - } - - /** - * Returns {@code true} when the entire stream has been consumed and no more items can be emitted. - * When that is the case, a terminal signal is sent. - * - *

Cannot run concurrently due to the draining field. - */ - private boolean isExhausted() { - Page current = pages.peek(); - // Note: current can only be null when: - // 1) we are waiting for the first page and it hasn't arrived yet; - // 2) we just discarded the current page, but the next page hasn't arrived yet. - // In any case, a null here means it is not the last page, since the last page - // stays in the queue until the very end of the operation. - return current != null && !current.hasMoreRows() && !current.hasMorePages(); - } - - /** - * Runs on a subscriber thread initially, see {@link #start(Callable)}. Subsequent executions run - * on the thread that completes the pair of futures [current.fetchNextPage, pages.offer] and - * enqueues. This can be a driver IO thread or a subscriber thread; in both cases, cannot run - * concurrently due to the fact that one can only fetch the next page when the current one is - * arrived and enqueued. - */ - private void fetchNextPageAndEnqueue(@NonNull Page current) { - current - .fetchNextPage() - // as soon as the response arrives, - // create the new page - .handle( - (rs, t) -> { - Page page; - if (t == null) { - page = toPage(rs); - executionInfosSubscriber.onNext(rs.getRequestExecutionInfo()); - if (!page.hasMorePages()) { - executionInfosSubscriber.onComplete(); - } - } else { - // Unwrap CompletionExceptions created by combined futures - if (t instanceof CompletionException) { - t = t.getCause(); - } - page = toErrorPage(t); - executionInfosSubscriber.onError(t); - } - return page; - }) - .thenCompose(pages::offer) - .thenAccept( - page -> { - if (page.hasMorePages() && !cancelled) { - // preemptively fetch the next page, if available - fetchNextPageAndEnqueue(page); - } - drain(); - }); - } - - private void doOnNext(@NonNull ReactiveGraphNode result) { - try { - mainSubscriber.onNext(result); - } catch (Throwable t) { - LOG.error( - mainSubscriber - + " violated the Reactive Streams rule 2.13 by throwing an exception from onNext.", - t); - cancel(); - } - } - - private void doOnComplete() { - try { - // Then we signal onComplete as per rules 1.2 and 1.5 - mainSubscriber.onComplete(); - } catch (Throwable t) { - LOG.error( - mainSubscriber - + " violated the Reactive Streams rule 2.13 by throwing an exception from onComplete.", - t); - } - // We need to consider this Subscription as cancelled as per rule 1.6 - cancel(); - } - - // package-private because it can be invoked by the publisher if the subscription handshake - // process fails. - void doOnError(@NonNull Throwable error) { - try { - // Then we signal the error downstream, as per rules 1.2 and 1.4. - mainSubscriber.onError(error); - } catch (Throwable t) { - t.addSuppressed(error); - LOG.error( - mainSubscriber - + " violated the Reactive Streams rule 2.13 by throwing an exception from onError.", - t); - } - // We need to consider this Subscription as cancelled as per rule 1.6 - cancel(); - } - - private void clear() { - // We don't need these pages anymore and should not hold references - // to them. - pages.clear(); - // As per 3.13, Subscription.cancel() MUST request the Publisher to - // eventually drop any references to the corresponding subscriber. - // Our own publishers do not keep references to this subscription, - // but downstream processors might do so, which is why we need to - // defensively clear the subscriber reference when we are done. - mainSubscriber = null; - executionInfosSubscriber = null; - } - - /** - * Converts the received result object into a {@link Page}. - * - * @param rs the result object to convert. - * @return a new page. - */ - @NonNull - private Page toPage(@NonNull AsyncGraphResultSet rs) { - ExecutionInfo executionInfo = rs.getRequestExecutionInfo(); - Iterator results = - Iterators.transform( - rs.currentPage().iterator(), - row -> new DefaultReactiveGraphNode(Objects.requireNonNull(row), executionInfo)); - return new Page(results, rs.hasMorePages() ? rs::fetchNextPage : null); - } - - /** Converts the given error into a {@link Page}, containing the error as its only element. */ - @NonNull - private Page toErrorPage(@NonNull Throwable t) { - return new Page(Iterators.singletonIterator(t), null); - } - - /** - * A page object comprises an iterator over the page's results, and a future pointing to the next - * page (or {@code null}, if it's the last page). - */ - static class Page { - - @NonNull final Iterator iterator; - - // A pointer to the next page, or null if this is the last page. - @Nullable final Callable> nextPage; - - /** called only from start() */ - Page(@NonNull Callable> nextPage) { - this.iterator = Collections.emptyIterator(); - this.nextPage = nextPage; - } - - Page( - @NonNull Iterator iterator, - @Nullable Callable> nextPage) { - this.iterator = iterator; - this.nextPage = nextPage; - } - - boolean hasMorePages() { - return nextPage != null; - } - - @NonNull - CompletionStage fetchNextPage() { - try { - return Objects.requireNonNull(nextPage).call(); - } catch (Exception e) { - // This is a synchronous failure in the driver. - // It can happen in rare cases when the driver throws an exception instead of returning a - // failed future; e.g. if someone tries to execute a continuous paging request but the - // protocol version in use does not support it. - // We treat it as a failed future. - return CompletableFutures.failedFuture(e); - } - } - - boolean hasMoreRows() { - return iterator.hasNext(); - } - - @NonNull - Object nextRow() { - return iterator.next(); - } - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/AddressFormatter.java b/core/src/main/java/com/datastax/dse/driver/internal/core/insights/AddressFormatter.java deleted file mode 100644 index cecc951a3ab..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/AddressFormatter.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights; - -import java.net.InetAddress; -import java.net.InetSocketAddress; - -class AddressFormatter { - - static String nullSafeToString(Object address) { - if (address instanceof InetAddress) { - return nullSafeToString((InetAddress) address); - } else if (address instanceof InetSocketAddress) { - return nullSafeToString((InetSocketAddress) address); - } else if (address instanceof String) { - return address.toString(); - } else { - return ""; - } - } - - static String nullSafeToString(InetAddress inetAddress) { - return inetAddress != null ? inetAddress.getHostAddress() : null; - } - - static String nullSafeToString(InetSocketAddress inetSocketAddress) { - if (inetSocketAddress != null) { - if (inetSocketAddress.isUnresolved()) { - return String.format( - "%s:%s", - nullSafeToString(inetSocketAddress.getHostName()), inetSocketAddress.getPort()); - } else { - return String.format( - "%s:%s", nullSafeToString(inetSocketAddress.getAddress()), inetSocketAddress.getPort()); - } - } - return null; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/ConfigAntiPatternsFinder.java b/core/src/main/java/com/datastax/dse/driver/internal/core/insights/ConfigAntiPatternsFinder.java deleted file mode 100644 index 7f5b9c20a0e..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/ConfigAntiPatternsFinder.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights; - -import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.SSL_ENGINE_FACTORY_CLASS; -import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.SSL_HOSTNAME_VALIDATION; - -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import java.util.HashMap; -import java.util.Map; - -class ConfigAntiPatternsFinder { - Map findAntiPatterns(InternalDriverContext driverContext) { - Map antiPatterns = new HashMap<>(); - findSslAntiPattern(driverContext, antiPatterns); - return antiPatterns; - } - - private void findSslAntiPattern( - InternalDriverContext driverContext, Map antiPatterns) { - boolean isSslDefined = - driverContext.getConfig().getDefaultProfile().isDefined(SSL_ENGINE_FACTORY_CLASS); - boolean certValidation = - driverContext.getConfig().getDefaultProfile().getBoolean(SSL_HOSTNAME_VALIDATION, false); - if (isSslDefined && !certValidation) { - antiPatterns.put( - "sslWithoutCertValidation", - "Client-to-node encryption is enabled but server certificate validation is disabled"); - } - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/DataCentersFinder.java b/core/src/main/java/com/datastax/dse/driver/internal/core/insights/DataCentersFinder.java deleted file mode 100644 index 7112b8dcdf7..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/DataCentersFinder.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights; - -import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.CONNECTION_POOL_REMOTE_SIZE; - -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.loadbalancing.NodeDistance; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import com.datastax.oss.driver.shaded.guava.common.annotations.VisibleForTesting; -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - -class DataCentersFinder { - - Set getDataCenters(InternalDriverContext driverContext) { - return getDataCenters( - driverContext.getMetadataManager().getMetadata().getNodes().values(), - driverContext.getConfig().getDefaultProfile()); - } - - @VisibleForTesting - Set getDataCenters(Collection nodes, DriverExecutionProfile executionProfile) { - - int remoteConnectionsLength = executionProfile.getInt(CONNECTION_POOL_REMOTE_SIZE); - - Set dataCenters = new HashSet<>(); - for (Node n : nodes) { - NodeDistance distance = n.getDistance(); - - if (distance.equals(NodeDistance.LOCAL) - || (distance.equals(NodeDistance.REMOTE) && remoteConnectionsLength > 0)) { - dataCenters.add(n.getDatacenter()); - } - } - return dataCenters; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/ExecutionProfilesInfoFinder.java b/core/src/main/java/com/datastax/dse/driver/internal/core/insights/ExecutionProfilesInfoFinder.java deleted file mode 100644 index a7c92d80d96..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/ExecutionProfilesInfoFinder.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights; - -import static com.datastax.dse.driver.api.core.config.DseDriverOption.GRAPH_TRAVERSAL_SOURCE; - -import com.datastax.dse.driver.internal.core.insights.PackageUtil.ClassSettingDetails; -import com.datastax.dse.driver.internal.core.insights.schema.LoadBalancingInfo; -import com.datastax.dse.driver.internal.core.insights.schema.SpecificExecutionProfile; -import com.datastax.dse.driver.internal.core.insights.schema.SpeculativeExecutionInfo; -import com.datastax.oss.driver.api.core.config.DefaultDriverOption; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; - -class ExecutionProfilesInfoFinder { - Map getExecutionProfilesInfo( - InternalDriverContext driverContext) { - - SpecificExecutionProfile defaultProfile = - mapToSpecificProfile(driverContext.getConfig().getDefaultProfile()); - - return driverContext.getConfig().getProfiles().entrySet().stream() - .collect( - Collectors.toMap( - Map.Entry::getKey, - e -> { - if (isNotDefaultProfile(e)) { - SpecificExecutionProfile specificExecutionProfile = - mapToSpecificProfile(e.getValue()); - return retainOnlyDifferentFieldsFromSpecificProfile( - defaultProfile, specificExecutionProfile); - } else { - return defaultProfile; - } - })); - } - - private boolean isNotDefaultProfile(Map.Entry e) { - return !e.getKey().equals("default"); - } - - private SpecificExecutionProfile retainOnlyDifferentFieldsFromSpecificProfile( - SpecificExecutionProfile defaultProfile, SpecificExecutionProfile specificExecutionProfile) { - Integer readTimeout = - getIfDifferentOrReturnNull( - defaultProfile, specificExecutionProfile, SpecificExecutionProfile::getReadTimeout); - LoadBalancingInfo loadBalancingInfo = - getIfDifferentOrReturnNull( - defaultProfile, specificExecutionProfile, SpecificExecutionProfile::getLoadBalancing); - - SpeculativeExecutionInfo speculativeExecutionInfo = - getIfDifferentOrReturnNull( - defaultProfile, - specificExecutionProfile, - SpecificExecutionProfile::getSpeculativeExecution); - - String consistency = - getIfDifferentOrReturnNull( - defaultProfile, specificExecutionProfile, SpecificExecutionProfile::getConsistency); - - String serialConsistency = - getIfDifferentOrReturnNull( - defaultProfile, - specificExecutionProfile, - SpecificExecutionProfile::getSerialConsistency); - - Map graphOptions = - getIfDifferentOrReturnNull( - defaultProfile, specificExecutionProfile, SpecificExecutionProfile::getGraphOptions); - - return new SpecificExecutionProfile( - readTimeout, - loadBalancingInfo, - speculativeExecutionInfo, - consistency, - serialConsistency, - graphOptions); - } - - private T getIfDifferentOrReturnNull( - SpecificExecutionProfile defaultProfile, - SpecificExecutionProfile profile, - Function valueExtractor) { - T defaultProfileValue = valueExtractor.apply(defaultProfile); - T specificProfileValue = valueExtractor.apply(profile); - if (defaultProfileValue.equals(specificProfileValue)) { - return null; - } else { - return specificProfileValue; - } - } - - private SpecificExecutionProfile mapToSpecificProfile( - DriverExecutionProfile driverExecutionProfile) { - return new SpecificExecutionProfile( - (int) driverExecutionProfile.getDuration(DefaultDriverOption.REQUEST_TIMEOUT).toMillis(), - getLoadBalancingInfo(driverExecutionProfile), - getSpeculativeExecutionInfo(driverExecutionProfile), - driverExecutionProfile.getString(DefaultDriverOption.REQUEST_CONSISTENCY), - driverExecutionProfile.getString(DefaultDriverOption.REQUEST_SERIAL_CONSISTENCY), - getGraphOptions(driverExecutionProfile)); - } - - private SpeculativeExecutionInfo getSpeculativeExecutionInfo( - DriverExecutionProfile driverExecutionProfile) { - Map options = new LinkedHashMap<>(); - - putIfExists( - options, - "maxSpeculativeExecutions", - DefaultDriverOption.SPECULATIVE_EXECUTION_MAX, - driverExecutionProfile); - putIfExists( - options, "delay", DefaultDriverOption.SPECULATIVE_EXECUTION_DELAY, driverExecutionProfile); - - ClassSettingDetails speculativeExecutionDetails = - PackageUtil.getSpeculativeExecutionDetails( - driverExecutionProfile.getString( - DefaultDriverOption.SPECULATIVE_EXECUTION_POLICY_CLASS)); - return new SpeculativeExecutionInfo( - speculativeExecutionDetails.getClassName(), - options, - speculativeExecutionDetails.getFullPackage()); - } - - private void putIfExists( - Map options, - String key, - DefaultDriverOption option, - DriverExecutionProfile executionProfile) { - if (executionProfile.isDefined(option)) { - options.put(key, executionProfile.getInt(option)); - } - } - - private LoadBalancingInfo getLoadBalancingInfo(DriverExecutionProfile driverExecutionProfile) { - Map options = new LinkedHashMap<>(); - if (driverExecutionProfile.isDefined(DefaultDriverOption.LOAD_BALANCING_LOCAL_DATACENTER)) { - options.put( - "localDataCenter", - driverExecutionProfile.getString(DefaultDriverOption.LOAD_BALANCING_LOCAL_DATACENTER)); - } - @SuppressWarnings("deprecation") - boolean hasNodeFiltering = - driverExecutionProfile.isDefined(DefaultDriverOption.LOAD_BALANCING_FILTER_CLASS) - || driverExecutionProfile.isDefined( - DefaultDriverOption.LOAD_BALANCING_DISTANCE_EVALUATOR_CLASS); - options.put("filterFunction", hasNodeFiltering); - ClassSettingDetails loadBalancingDetails = - PackageUtil.getLoadBalancingDetails( - driverExecutionProfile.getString(DefaultDriverOption.LOAD_BALANCING_POLICY_CLASS)); - return new LoadBalancingInfo( - loadBalancingDetails.getClassName(), options, loadBalancingDetails.getFullPackage()); - } - - private Map getGraphOptions(DriverExecutionProfile driverExecutionProfile) { - Map graphOptionsMap = new HashMap<>(); - String graphTraversalSource = driverExecutionProfile.getString(GRAPH_TRAVERSAL_SOURCE, null); - if (graphTraversalSource != null) { - graphOptionsMap.put("source", graphTraversalSource); - } - return graphOptionsMap; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/InsightsClient.java b/core/src/main/java/com/datastax/dse/driver/internal/core/insights/InsightsClient.java deleted file mode 100644 index 168477894ed..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/InsightsClient.java +++ /dev/null @@ -1,490 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights; - -import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.AUTH_PROVIDER_CLASS; -import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.CONNECTION_POOL_LOCAL_SIZE; -import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.CONNECTION_POOL_REMOTE_SIZE; -import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.HEARTBEAT_INTERVAL; -import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.PROTOCOL_COMPRESSION; -import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.SSL_ENGINE_FACTORY_CLASS; -import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.SSL_HOSTNAME_VALIDATION; - -import com.datastax.dse.driver.api.core.DseProtocolVersion; -import com.datastax.dse.driver.internal.core.insights.PackageUtil.ClassSettingDetails; -import com.datastax.dse.driver.internal.core.insights.configuration.InsightsConfiguration; -import com.datastax.dse.driver.internal.core.insights.exceptions.InsightEventFormatException; -import com.datastax.dse.driver.internal.core.insights.schema.AuthProviderType; -import com.datastax.dse.driver.internal.core.insights.schema.Insight; -import com.datastax.dse.driver.internal.core.insights.schema.InsightMetadata; -import com.datastax.dse.driver.internal.core.insights.schema.InsightType; -import com.datastax.dse.driver.internal.core.insights.schema.InsightsStartupData; -import com.datastax.dse.driver.internal.core.insights.schema.InsightsStatusData; -import com.datastax.dse.driver.internal.core.insights.schema.PoolSizeByHostDistance; -import com.datastax.dse.driver.internal.core.insights.schema.SSL; -import com.datastax.dse.driver.internal.core.insights.schema.SessionStateForNode; -import com.datastax.oss.driver.api.core.config.DefaultDriverOption; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.datastax.oss.driver.api.core.session.SessionBuilder; -import com.datastax.oss.driver.api.core.type.DataTypes; -import com.datastax.oss.driver.api.core.type.codec.TypeCodec; -import com.datastax.oss.driver.api.core.uuid.Uuids; -import com.datastax.oss.driver.internal.core.adminrequest.AdminRequestHandler; -import com.datastax.oss.driver.internal.core.context.DefaultDriverContext; -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import com.datastax.oss.driver.internal.core.context.StartupOptionsBuilder; -import com.datastax.oss.driver.internal.core.control.ControlConnection; -import com.datastax.oss.driver.internal.core.pool.ChannelPool; -import com.datastax.oss.driver.internal.core.util.concurrent.CompletableFutures; -import com.datastax.oss.driver.shaded.guava.common.annotations.VisibleForTesting; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import com.datastax.oss.protocol.internal.request.Query; -import com.datastax.oss.protocol.internal.request.query.QueryOptions; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.net.UnknownHostException; -import java.nio.ByteBuffer; -import java.time.Duration; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Supplier; -import java.util.stream.Collectors; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class InsightsClient { - private static final Logger LOGGER = LoggerFactory.getLogger(InsightsClient.class); - private static final String STARTUP_MESSAGE_NAME = "driver.startup"; - private static final String STATUS_MESSAGE_NAME = "driver.status"; - private static final String REPORT_INSIGHT_RPC = "CALL InsightsRpc.reportInsight(?)"; - private static final Map TAGS = ImmutableMap.of("language", "java"); - private static final String STARTUP_VERSION_1_ID = "v1"; - private static final String STATUS_VERSION_1_ID = "v1"; - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); - private static final int MAX_NUMBER_OF_STATUS_ERROR_LOGS = 5; - static final String DEFAULT_JAVA_APPLICATION = "Default Java Application"; - - private final ControlConnection controlConnection; - private final String id = Uuids.random().toString(); - private final InsightsConfiguration insightsConfiguration; - private final AtomicInteger numberOfStatusEventErrors = new AtomicInteger(); - - private final InternalDriverContext driverContext; - private final Supplier timestampSupplier; - private final PlatformInfoFinder platformInfoFinder; - private final ReconnectionPolicyInfoFinder reconnectionPolicyInfoInfoFinder; - private final ExecutionProfilesInfoFinder executionProfilesInfoFinder; - private final ConfigAntiPatternsFinder configAntiPatternsFinder; - private final DataCentersFinder dataCentersFinder; - private final StackTraceElement[] initCallStackTrace; - - private volatile ScheduledFuture scheduleInsightsTask; - - public static InsightsClient createInsightsClient( - InsightsConfiguration insightsConfiguration, - InternalDriverContext driverContext, - StackTraceElement[] initCallStackTrace) { - DataCentersFinder dataCentersFinder = new DataCentersFinder(); - return new InsightsClient( - driverContext, - System::currentTimeMillis, - insightsConfiguration, - new PlatformInfoFinder(), - new ReconnectionPolicyInfoFinder(), - new ExecutionProfilesInfoFinder(), - new ConfigAntiPatternsFinder(), - dataCentersFinder, - initCallStackTrace); - } - - InsightsClient( - InternalDriverContext driverContext, - Supplier timestampSupplier, - InsightsConfiguration insightsConfiguration, - PlatformInfoFinder platformInfoFinder, - ReconnectionPolicyInfoFinder reconnectionPolicyInfoInfoFinder, - ExecutionProfilesInfoFinder executionProfilesInfoFinder, - ConfigAntiPatternsFinder configAntiPatternsFinder, - DataCentersFinder dataCentersFinder, - StackTraceElement[] initCallStackTrace) { - this.driverContext = driverContext; - this.controlConnection = driverContext.getControlConnection(); - this.timestampSupplier = timestampSupplier; - this.insightsConfiguration = insightsConfiguration; - this.platformInfoFinder = platformInfoFinder; - this.reconnectionPolicyInfoInfoFinder = reconnectionPolicyInfoInfoFinder; - this.executionProfilesInfoFinder = executionProfilesInfoFinder; - this.configAntiPatternsFinder = configAntiPatternsFinder; - this.dataCentersFinder = dataCentersFinder; - this.initCallStackTrace = initCallStackTrace; - } - - public CompletionStage sendStartupMessage() { - try { - if (!shouldSendEvent()) { - return CompletableFuture.completedFuture(null); - } else { - String startupMessage = createStartupMessage(); - return sendJsonMessage(startupMessage) - .whenComplete( - (aVoid, throwable) -> { - if (throwable != null) { - LOGGER.debug( - "Error while sending startup message to Insights. Message was: " - + trimToFirst500characters(startupMessage), - throwable); - } - }); - } - } catch (Exception e) { - LOGGER.debug("Unexpected error while sending startup message to Insights.", e); - return CompletableFutures.failedFuture(e); - } - } - - private static String trimToFirst500characters(String startupMessage) { - return startupMessage.substring(0, Math.min(startupMessage.length(), 500)); - } - - public void scheduleStatusMessageSend() { - if (!shouldSendEvent()) { - return; - } - scheduleInsightsTask = - scheduleInsightsTask( - insightsConfiguration.getStatusEventDelayMillis(), - insightsConfiguration.getExecutor(), - this::sendStatusMessage); - } - - public void shutdown() { - if (scheduleInsightsTask != null) { - scheduleInsightsTask.cancel(false); - } - } - - @VisibleForTesting - public CompletionStage sendStatusMessage() { - try { - String statusMessage = createStatusMessage(); - CompletionStage result = sendJsonMessage(statusMessage); - return result.whenComplete( - (aVoid, throwable) -> { - if (throwable != null) { - if (numberOfStatusEventErrors.getAndIncrement() < MAX_NUMBER_OF_STATUS_ERROR_LOGS) { - LOGGER.debug( - "Error while sending status message to Insights. Message was: " - + trimToFirst500characters(statusMessage), - throwable); - } - } - }); - } catch (Exception e) { - LOGGER.debug("Unexpected error while sending status message to Insights.", e); - return CompletableFutures.failedFuture(e); - } - } - - private CompletionStage sendJsonMessage(String jsonMessage) { - - QueryOptions queryOptions = createQueryOptionsWithJson(jsonMessage); - String logPrefix = driverContext.getSessionName(); - Duration timeout = - driverContext - .getConfig() - .getDefaultProfile() - .getDuration(DefaultDriverOption.CONTROL_CONNECTION_TIMEOUT); - LOGGER.debug("sending JSON message: {}", jsonMessage); - - Query query = new Query(REPORT_INSIGHT_RPC, queryOptions); - return AdminRequestHandler.call(controlConnection.channel(), query, timeout, logPrefix).start(); - } - - private QueryOptions createQueryOptionsWithJson(String json) { - TypeCodec codec = - driverContext.getCodecRegistry().codecFor(DataTypes.TEXT, String.class); - ByteBuffer startupMessageSerialized = codec.encode(json, DseProtocolVersion.DSE_V2); - return new QueryOptions( - QueryOptions.DEFAULT.consistency, - Collections.singletonList(startupMessageSerialized), - QueryOptions.DEFAULT.namedValues, - QueryOptions.DEFAULT.skipMetadata, - QueryOptions.DEFAULT.pageSize, - QueryOptions.DEFAULT.pagingState, - QueryOptions.DEFAULT.serialConsistency, - QueryOptions.DEFAULT.defaultTimestamp, - QueryOptions.DEFAULT.keyspace, - QueryOptions.DEFAULT.nowInSeconds); - } - - private boolean shouldSendEvent() { - try { - return insightsConfiguration.isMonitorReportingEnabled() - && InsightsSupportVerifier.supportsInsights( - driverContext.getMetadataManager().getMetadata().getNodes().values()); - } catch (Exception e) { - LOGGER.debug("Unexpected error while checking Insights support.", e); - return false; - } - } - - @VisibleForTesting - String createStartupMessage() { - InsightMetadata insightMetadata = createMetadata(STARTUP_MESSAGE_NAME, STARTUP_VERSION_1_ID); - InsightsStartupData data = createStartupData(); - - try { - return OBJECT_MAPPER.writeValueAsString(new Insight<>(insightMetadata, data)); - } catch (JsonProcessingException e) { - throw new InsightEventFormatException("Problem when creating: " + STARTUP_MESSAGE_NAME, e); - } - } - - @VisibleForTesting - String createStatusMessage() { - InsightMetadata insightMetadata = createMetadata(STATUS_MESSAGE_NAME, STATUS_VERSION_1_ID); - InsightsStatusData data = createStatusData(); - - try { - return OBJECT_MAPPER.writeValueAsString(new Insight<>(insightMetadata, data)); - } catch (JsonProcessingException e) { - throw new InsightEventFormatException("Problem when creating: " + STATUS_MESSAGE_NAME, e); - } - } - - private InsightsStatusData createStatusData() { - Map startupOptions = driverContext.getStartupOptions(); - return InsightsStatusData.builder() - .withClientId(getClientId(startupOptions)) - .withSessionId(id) - .withControlConnection(getControlConnectionSocketAddress()) - .withConnectedNodes(getConnectedNodes()) - .build(); - } - - private Map getConnectedNodes() { - Map pools = driverContext.getPoolManager().getPools(); - return pools.entrySet().stream() - .collect( - Collectors.toMap( - entry -> AddressFormatter.nullSafeToString(entry.getKey().getEndPoint().resolve()), - this::constructSessionStateForNode)); - } - - private SessionStateForNode constructSessionStateForNode(Map.Entry entry) { - return new SessionStateForNode( - entry.getKey().getOpenConnections(), entry.getValue().getInFlight()); - } - - private InsightsStartupData createStartupData() { - Map startupOptions = driverContext.getStartupOptions(); - return InsightsStartupData.builder() - .withClientId(getClientId(startupOptions)) - .withSessionId(id) - .withApplicationName(getApplicationName(startupOptions)) - .withApplicationVersion(getApplicationVersion(startupOptions)) - .withDriverName(getDriverName(startupOptions)) - .withDriverVersion(getDriverVersion(startupOptions)) - .withContactPoints( - getResolvedContactPoints( - driverContext.getMetadataManager().getContactPoints().stream() - .map(n -> n.getEndPoint().resolve()) - .filter(InetSocketAddress.class::isInstance) - .map(InetSocketAddress.class::cast) - .collect(Collectors.toSet()))) - .withInitialControlConnection(getControlConnectionSocketAddress()) - .withProtocolVersion(driverContext.getProtocolVersion().getCode()) - .withLocalAddress(getLocalAddress()) - .withExecutionProfiles(executionProfilesInfoFinder.getExecutionProfilesInfo(driverContext)) - .withPoolSizeByHostDistance(getPoolSizeByHostDistance()) - .withHeartbeatInterval( - driverContext - .getConfig() - .getDefaultProfile() - .getDuration(HEARTBEAT_INTERVAL) - .toMillis()) - .withCompression( - driverContext.getConfig().getDefaultProfile().getString(PROTOCOL_COMPRESSION, "none")) - .withReconnectionPolicy( - reconnectionPolicyInfoInfoFinder.getReconnectionPolicyInfo( - driverContext.getReconnectionPolicy(), - driverContext.getConfig().getDefaultProfile())) - .withSsl(getSsl()) - .withAuthProvider(getAuthProvider()) - .withOtherOptions(getOtherOptions()) - .withPlatformInfo(platformInfoFinder.getInsightsPlatformInfo()) - .withConfigAntiPatterns(configAntiPatternsFinder.findAntiPatterns(driverContext)) - .withPeriodicStatusInterval(getPeriodicStatusInterval()) - .withHostName(getLocalHostName()) - .withApplicationNameWasGenerated(isApplicationNameGenerated(startupOptions)) - .withDataCenters(dataCentersFinder.getDataCenters(driverContext)) - .build(); - } - - private AuthProviderType getAuthProvider() { - String authProviderClassName = - driverContext - .getConfig() - .getDefaultProfile() - .getString(AUTH_PROVIDER_CLASS, "NoAuthProvider"); - ClassSettingDetails authProviderDetails = - PackageUtil.getAuthProviderDetails(authProviderClassName); - return new AuthProviderType( - authProviderDetails.getClassName(), authProviderDetails.getFullPackage()); - } - - private long getPeriodicStatusInterval() { - return TimeUnit.MILLISECONDS.toSeconds(insightsConfiguration.getStatusEventDelayMillis()); - } - - @VisibleForTesting - static Map> getResolvedContactPoints(Set contactPoints) { - if (contactPoints == null) { - return Collections.emptyMap(); - } - return contactPoints.stream() - .collect( - Collectors.groupingBy( - InetSocketAddress::getHostName, - Collectors.mapping(AddressFormatter::nullSafeToString, Collectors.toList()))); - } - - private String getDriverVersion(Map startupOptions) { - return startupOptions.get(StartupOptionsBuilder.DRIVER_VERSION_KEY); - } - - private String getDriverName(Map startupOptions) { - return startupOptions.get(StartupOptionsBuilder.DRIVER_NAME_KEY); - } - - private String getClientId(Map startupOptions) { - return startupOptions.get(StartupOptionsBuilder.CLIENT_ID_KEY); - } - - private boolean isApplicationNameGenerated(Map startupOptions) { - return startupOptions.get(StartupOptionsBuilder.APPLICATION_NAME_KEY) == null; - } - - private String getApplicationVersion(Map startupOptions) { - String applicationVersion = startupOptions.get(StartupOptionsBuilder.APPLICATION_VERSION_KEY); - if (applicationVersion == null) { - return ""; - } - return applicationVersion; - } - - private String getApplicationName(Map startupOptions) { - String applicationName = startupOptions.get(StartupOptionsBuilder.APPLICATION_NAME_KEY); - if (applicationName == null || applicationName.isEmpty()) { - return getClusterCreateCaller(initCallStackTrace); - } - return applicationName; - } - - @VisibleForTesting - static String getClusterCreateCaller(StackTraceElement[] stackTrace) { - for (int i = 0; i < stackTrace.length - 1; i++) { - if (isClusterStackTrace(stackTrace[i])) { - int nextElement = i + 1; - if (!isClusterStackTrace(stackTrace[nextElement])) { - return stackTrace[nextElement].getClassName(); - } - } - } - return DEFAULT_JAVA_APPLICATION; - } - - private static boolean isClusterStackTrace(StackTraceElement stackTraceElement) { - return stackTraceElement.getClassName().equals(DefaultDriverContext.class.getName()) - || stackTraceElement.getClassName().equals(SessionBuilder.class.getName()); - } - - private String getLocalHostName() { - try { - return InetAddress.getLocalHost().getHostName(); - } catch (UnknownHostException e) { - LOGGER.warn("Can not resolve the name of a host, returning null", e); - return null; - } - } - - private Map getOtherOptions() { - return Collections.emptyMap(); // todo - } - - private SSL getSsl() { - boolean isSslDefined = - driverContext.getConfig().getDefaultProfile().isDefined(SSL_ENGINE_FACTORY_CLASS); - boolean certValidation = - driverContext.getConfig().getDefaultProfile().getBoolean(SSL_HOSTNAME_VALIDATION, false); - return new SSL(isSslDefined, certValidation); - } - - private PoolSizeByHostDistance getPoolSizeByHostDistance() { - - return new PoolSizeByHostDistance( - driverContext.getConfig().getDefaultProfile().getInt(CONNECTION_POOL_LOCAL_SIZE), - driverContext.getConfig().getDefaultProfile().getInt(CONNECTION_POOL_REMOTE_SIZE), - 0); - } - - private String getControlConnectionSocketAddress() { - SocketAddress controlConnectionAddress = controlConnection.channel().getEndPoint().resolve(); - return AddressFormatter.nullSafeToString(controlConnectionAddress); - } - - private String getLocalAddress() { - SocketAddress controlConnectionLocalAddress = controlConnection.channel().localAddress(); - if (controlConnectionLocalAddress instanceof InetSocketAddress) { - return AddressFormatter.nullSafeToString( - ((InetSocketAddress) controlConnectionLocalAddress).getAddress()); - } - return null; - } - - private InsightMetadata createMetadata(String messageName, String messageVersion) { - return new InsightMetadata( - messageName, timestampSupplier.get(), TAGS, InsightType.EVENT, messageVersion); - } - - @VisibleForTesting - static ScheduledFuture scheduleInsightsTask( - long statusEventDelayMillis, - ScheduledExecutorService scheduledTasksExecutor, - Runnable runnable) { - long initialDelay = - (long) Math.floor(statusEventDelayMillis - zeroToTenPercentRandom(statusEventDelayMillis)); - return scheduledTasksExecutor.scheduleWithFixedDelay( - runnable, initialDelay, statusEventDelayMillis, TimeUnit.MILLISECONDS); - } - - private static double zeroToTenPercentRandom(long statusEventDelayMillis) { - return 0.1 * statusEventDelayMillis * Math.random(); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/InsightsSupportVerifier.java b/core/src/main/java/com/datastax/dse/driver/internal/core/insights/InsightsSupportVerifier.java deleted file mode 100644 index ec016ef52d8..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/InsightsSupportVerifier.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights; - -import com.datastax.dse.driver.api.core.metadata.DseNodeProperties; -import com.datastax.oss.driver.api.core.Version; -import com.datastax.oss.driver.api.core.metadata.Node; -import java.util.Collection; - -class InsightsSupportVerifier { - private static final Version minDse6Version = Version.parse("6.0.5"); - private static final Version minDse51Version = Version.parse("5.1.13"); - private static final Version dse600Version = Version.parse("6.0.0"); - - static boolean supportsInsights(Collection nodes) { - assert minDse6Version != null; - assert dse600Version != null; - assert minDse51Version != null; - if (nodes.isEmpty()) return false; - - for (Node node : nodes) { - Object version = node.getExtras().get(DseNodeProperties.DSE_VERSION); - if (version == null) { - return false; - } - Version dseVersion = (Version) version; - if (!(dseVersion.compareTo(minDse6Version) >= 0 - || (dseVersion.compareTo(dse600Version) < 0 - && dseVersion.compareTo(minDse51Version) >= 0))) { - return false; - } - } - return true; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/PackageUtil.java b/core/src/main/java/com/datastax/dse/driver/internal/core/insights/PackageUtil.java deleted file mode 100644 index c7e15bbdfae..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/PackageUtil.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights; - -import com.datastax.oss.driver.shaded.guava.common.annotations.VisibleForTesting; - -class PackageUtil { - static final String DEFAULT_SPECULATIVE_EXECUTION_PACKAGE = - "com.datastax.oss.driver.internal.core.specex"; - static final String DEFAULT_LOAD_BALANCING_PACKAGE = - "com.datastax.oss.driver.internal.core.loadbalancing"; - static final String DEFAULT_AUTH_PROVIDER_PACKAGE = "com.datastax.oss.driver.internal.core.auth"; - - static String getNamespace(Class tClass) { - String namespace = ""; - Package packageInfo = tClass.getPackage(); - if (packageInfo != null) { - namespace = packageInfo.getName(); - } - return namespace; - } - - static ClassSettingDetails getSpeculativeExecutionDetails(String classSetting) { - return getClassSettingDetails(classSetting, DEFAULT_SPECULATIVE_EXECUTION_PACKAGE); - } - - static ClassSettingDetails getLoadBalancingDetails(String classSetting) { - return getClassSettingDetails(classSetting, DEFAULT_LOAD_BALANCING_PACKAGE); - } - - static ClassSettingDetails getAuthProviderDetails(String classSetting) { - return getClassSettingDetails(classSetting, DEFAULT_AUTH_PROVIDER_PACKAGE); - } - - private static ClassSettingDetails getClassSettingDetails( - String classSetting, String packageName) { - String className = getClassName(classSetting); - String fullPackage = getFullPackageOrDefault(classSetting, packageName); - return new ClassSettingDetails(className, fullPackage); - } - - @VisibleForTesting - static String getClassName(String classSetting) { - int lastDot = classSetting.lastIndexOf('.'); - return lastDot < 0 ? classSetting : classSetting.substring(lastDot + 1); - } - - @VisibleForTesting - static String getFullPackageOrDefault(String classSetting, String defaultValue) { - int lastDot = classSetting.lastIndexOf('.'); - return lastDot < 0 ? defaultValue : classSetting.substring(0, lastDot); - } - - static class ClassSettingDetails { - private final String className; - private final String fullPackage; - - ClassSettingDetails(String className, String fullPackage) { - this.className = className; - this.fullPackage = fullPackage; - } - - String getClassName() { - return className; - } - - String getFullPackage() { - return fullPackage; - } - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/PlatformInfoFinder.java b/core/src/main/java/com/datastax/dse/driver/internal/core/insights/PlatformInfoFinder.java deleted file mode 100644 index 84b4d76e8b7..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/PlatformInfoFinder.java +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights; - -import static com.datastax.dse.driver.internal.core.insights.schema.InsightsPlatformInfo.OS; -import static com.datastax.dse.driver.internal.core.insights.schema.InsightsPlatformInfo.RuntimeAndCompileTimeVersions; - -import com.datastax.dse.driver.internal.core.insights.schema.InsightsPlatformInfo; -import com.datastax.dse.driver.internal.core.insights.schema.InsightsPlatformInfo.CPUS; -import com.datastax.oss.driver.internal.core.os.Native; -import com.datastax.oss.driver.shaded.guava.common.annotations.VisibleForTesting; -import com.datastax.oss.driver.shaded.guava.common.base.Splitter; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Properties; -import java.util.function.Function; - -class PlatformInfoFinder { - private static final String MAVEN_IGNORE_LINE = "The following files have been resolved:"; - private static final Splitter DEPENDENCY_SPLITTER = Splitter.on(':'); - static final String UNVERIFIED_RUNTIME_VERSION = "UNVERIFIED"; - private final Function propertiesUrlProvider; - - @SuppressWarnings("UnnecessaryLambda") - private static final Function M2_PROPERTIES_PROVIDER = - d -> { - ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); - if (contextClassLoader == null) { - contextClassLoader = PlatformInfoFinder.class.getClassLoader(); - } - return contextClassLoader.getResource( - "META-INF/maven/" + d.groupId + "/" + d.artifactId + "/pom.properties"); - }; - - PlatformInfoFinder() { - this(M2_PROPERTIES_PROVIDER); - } - - @VisibleForTesting - PlatformInfoFinder(Function pomPropertiesUrlProvider) { - this.propertiesUrlProvider = pomPropertiesUrlProvider; - } - - InsightsPlatformInfo getInsightsPlatformInfo() { - OS os = getOsInfo(); - CPUS cpus = getCpuInfo(); - Map> runtimeInfo = getRuntimeInfo(); - - return new InsightsPlatformInfo(os, cpus, runtimeInfo); - } - - private Map> getRuntimeInfo() { - Map coreDeps = - fetchDependenciesFromFile( - this.getClass().getResourceAsStream("/com/datastax/dse/driver/internal/deps.txt")); - - Map queryBuilderDeps = - fetchDependenciesFromFile( - this.getClass() - .getResourceAsStream("/com/datastax/dse/driver/internal/querybuilder/deps.txt")); - - Map mapperProcessorDeps = - fetchDependenciesFromFile( - this.getClass() - .getResourceAsStream( - "/com/datastax/dse/driver/internal/mapper/processor/deps.txt")); - - Map mapperRuntimeDeps = - fetchDependenciesFromFile( - this.getClass() - .getResourceAsStream("/com/datastax/dse/driver/internal/mapper/deps.txt")); - - Map> runtimeDependencies = - new LinkedHashMap<>(); - putIfNonEmpty(coreDeps, runtimeDependencies, "core"); - putIfNonEmpty(queryBuilderDeps, runtimeDependencies, "query-builder"); - putIfNonEmpty(mapperProcessorDeps, runtimeDependencies, "mapper-processor"); - putIfNonEmpty(mapperRuntimeDeps, runtimeDependencies, "mapper-runtime"); - addJavaVersion(runtimeDependencies); - return runtimeDependencies; - } - - private void putIfNonEmpty( - Map moduleDependencies, - Map> runtimeDependencies, - String moduleName) { - if (!moduleDependencies.isEmpty()) { - runtimeDependencies.put(moduleName, moduleDependencies); - } - } - - @VisibleForTesting - void addJavaVersion(Map> runtimeDependencies) { - Package javaPackage = Runtime.class.getPackage(); - Map javaDependencies = new LinkedHashMap<>(); - javaDependencies.put( - "version", toSameRuntimeAndCompileVersion(javaPackage.getImplementationVersion())); - javaDependencies.put( - "vendor", toSameRuntimeAndCompileVersion(javaPackage.getImplementationVendor())); - javaDependencies.put( - "title", toSameRuntimeAndCompileVersion(javaPackage.getImplementationTitle())); - putIfNonEmpty(javaDependencies, runtimeDependencies, "java"); - } - - private RuntimeAndCompileTimeVersions toSameRuntimeAndCompileVersion(String version) { - return new RuntimeAndCompileTimeVersions(version, version, false); - } - - /** - * Method is fetching dependencies from file. Lines in file should be in format: - * com.organization:artifactId:jar:1.2.0 or com.organization:artifactId:jar:native:1.2.0 - * - *

For such file the output will be: Map - * "com.organization:artifactId",{"runtimeVersion":"1.2.0", "compileVersion:"1.2.0", "optional": - * false} Duplicates will be omitted. If there are two dependencies for the exactly the same - * organizationId:artifactId it is not deterministic which version will be taken. In the case of - * an error while opening file this method will fail silently returning an empty Map - */ - @VisibleForTesting - Map fetchDependenciesFromFile(InputStream inputStream) { - Map dependencies = new LinkedHashMap<>(); - if (inputStream == null) { - return dependencies; - } - try { - List dependenciesFromFile = extractMavenDependenciesFromFile(inputStream); - for (DependencyFromFile d : dependenciesFromFile) { - dependencies.put(formatDependencyName(d), getRuntimeAndCompileVersion(d)); - } - } catch (IOException e) { - return dependencies; - } - return dependencies; - } - - private RuntimeAndCompileTimeVersions getRuntimeAndCompileVersion(DependencyFromFile d) { - URL url = propertiesUrlProvider.apply(d); - if (url == null) { - return new RuntimeAndCompileTimeVersions( - UNVERIFIED_RUNTIME_VERSION, d.getVersion(), d.isOptional()); - } - Properties properties = new Properties(); - try { - properties.load(url.openStream()); - } catch (IOException e) { - return new RuntimeAndCompileTimeVersions( - UNVERIFIED_RUNTIME_VERSION, d.getVersion(), d.isOptional()); - } - Object version = properties.get("version"); - if (version == null) { - return new RuntimeAndCompileTimeVersions( - UNVERIFIED_RUNTIME_VERSION, d.getVersion(), d.isOptional()); - } else { - return new RuntimeAndCompileTimeVersions(version.toString(), d.getVersion(), d.isOptional()); - } - } - - private String formatDependencyName(DependencyFromFile d) { - return String.format("%s:%s", d.getGroupId(), d.getArtifactId()); - } - - private List extractMavenDependenciesFromFile(InputStream inputStream) - throws IOException { - List dependenciesFromFile = new ArrayList<>(); - BufferedReader reader = - new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)); - for (String line; (line = reader.readLine()) != null; ) { - if (lineWithDependencyInfo(line)) { - dependenciesFromFile.add(extractDependencyFromLine(line.trim())); - } - } - return dependenciesFromFile; - } - - private DependencyFromFile extractDependencyFromLine(String line) { - List split = DEPENDENCY_SPLITTER.splitToList(line); - if (split.size() == 6) { // case for i.e.: com.github.jnr:jffi:jar:native:1.2.16:compile - return new DependencyFromFile( - split.get(0), split.get(1), split.get(4), checkIsOptional(split.get(5))); - } else { // case for normal: org.ow2.asm:asm:jar:5.0.3:compile - return new DependencyFromFile( - split.get(0), split.get(1), split.get(3), checkIsOptional(split.get(4))); - } - } - - private boolean checkIsOptional(String scope) { - return scope.contains("(optional)"); - } - - private boolean lineWithDependencyInfo(String line) { - return (!line.equals(MAVEN_IGNORE_LINE) && !line.isEmpty()); - } - - private CPUS getCpuInfo() { - int numberOfProcessors = Runtime.getRuntime().availableProcessors(); - String model = Native.getCpu(); - return new CPUS(numberOfProcessors, model); - } - - private OS getOsInfo() { - String osName = System.getProperty("os.name"); - String osVersion = System.getProperty("os.version"); - String osArch = System.getProperty("os.arch"); - return new OS(osName, osVersion, osArch); - } - - static class DependencyFromFile { - private final String groupId; - private final String artifactId; - private final String version; - private final boolean optional; - - DependencyFromFile(String groupId, String artifactId, String version, boolean optional) { - this.groupId = groupId; - this.artifactId = artifactId; - this.version = version; - this.optional = optional; - } - - String getGroupId() { - return groupId; - } - - String getArtifactId() { - return artifactId; - } - - String getVersion() { - return version; - } - - boolean isOptional() { - return optional; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof DependencyFromFile)) { - return false; - } - DependencyFromFile that = (DependencyFromFile) o; - return optional == that.optional - && Objects.equals(groupId, that.groupId) - && Objects.equals(artifactId, that.artifactId) - && Objects.equals(version, that.version); - } - - @Override - public int hashCode() { - return Objects.hash(groupId, artifactId, version, optional); - } - - @Override - public String toString() { - return "DependencyFromFile{" - + "groupId='" - + groupId - + '\'' - + ", artifactId='" - + artifactId - + '\'' - + ", version='" - + version - + '\'' - + ", optional=" - + optional - + '}'; - } - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/ReconnectionPolicyInfoFinder.java b/core/src/main/java/com/datastax/dse/driver/internal/core/insights/ReconnectionPolicyInfoFinder.java deleted file mode 100644 index af8aff74035..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/ReconnectionPolicyInfoFinder.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights; - -import com.datastax.dse.driver.internal.core.insights.schema.ReconnectionPolicyInfo; -import com.datastax.oss.driver.api.core.config.DefaultDriverOption; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.connection.ReconnectionPolicy; -import com.datastax.oss.driver.internal.core.connection.ConstantReconnectionPolicy; -import com.datastax.oss.driver.internal.core.connection.ExponentialReconnectionPolicy; -import java.util.HashMap; -import java.util.Map; - -class ReconnectionPolicyInfoFinder { - ReconnectionPolicyInfo getReconnectionPolicyInfo( - ReconnectionPolicy reconnectionPolicy, DriverExecutionProfile executionProfile) { - Class reconnectionPolicyClass = reconnectionPolicy.getClass(); - String type = reconnectionPolicyClass.getSimpleName(); - String namespace = PackageUtil.getNamespace(reconnectionPolicyClass); - Map options = new HashMap<>(); - if (reconnectionPolicy instanceof ConstantReconnectionPolicy) { - options.put( - "delayMs", - executionProfile.getDuration(DefaultDriverOption.RECONNECTION_BASE_DELAY).toMillis()); - } else if (reconnectionPolicy instanceof ExponentialReconnectionPolicy) { - ExponentialReconnectionPolicy exponentialReconnectionPolicy = - (ExponentialReconnectionPolicy) reconnectionPolicy; - options.put("maxDelayMs", exponentialReconnectionPolicy.getMaxDelayMs()); - options.put("baseDelayMs", exponentialReconnectionPolicy.getBaseDelayMs()); - options.put("maxAttempts", exponentialReconnectionPolicy.getMaxAttempts()); - } - return new ReconnectionPolicyInfo(type, options, namespace); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/configuration/InsightsConfiguration.java b/core/src/main/java/com/datastax/dse/driver/internal/core/insights/configuration/InsightsConfiguration.java deleted file mode 100644 index ac27bb76389..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/configuration/InsightsConfiguration.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights.configuration; - -import io.netty.util.concurrent.EventExecutor; - -public class InsightsConfiguration { - private final boolean monitorReportingEnabled; - private final long statusEventDelayMillis; - private final EventExecutor executor; - - public InsightsConfiguration( - boolean monitorReportingEnabled, long statusEventDelayMillis, EventExecutor executor) { - this.monitorReportingEnabled = monitorReportingEnabled; - this.statusEventDelayMillis = statusEventDelayMillis; - this.executor = executor; - } - - public boolean isMonitorReportingEnabled() { - return monitorReportingEnabled; - } - - public long getStatusEventDelayMillis() { - return statusEventDelayMillis; - } - - public EventExecutor getExecutor() { - return executor; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/exceptions/InsightEventFormatException.java b/core/src/main/java/com/datastax/dse/driver/internal/core/insights/exceptions/InsightEventFormatException.java deleted file mode 100644 index cfce68971ef..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/exceptions/InsightEventFormatException.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights.exceptions; - -public class InsightEventFormatException extends RuntimeException { - - public InsightEventFormatException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/AuthProviderType.java b/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/AuthProviderType.java deleted file mode 100644 index 18aec53e899..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/AuthProviderType.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights.schema; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.Objects; - -public class AuthProviderType { - @JsonProperty("type") - private final String type; - - @JsonProperty("namespace") - private final String namespace; - - @JsonCreator - public AuthProviderType( - @JsonProperty("type") String type, @JsonProperty("namespace") String namespace) { - this.type = type; - this.namespace = namespace; - } - - public String getType() { - return type; - } - - public String getNamespace() { - return namespace; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof AuthProviderType)) { - return false; - } - AuthProviderType that = (AuthProviderType) o; - return Objects.equals(type, that.type) && Objects.equals(namespace, that.namespace); - } - - @Override - public int hashCode() { - return Objects.hash(type, namespace); - } - - @Override - public String toString() { - return "AuthProviderType{" + "type='" + type + '\'' + ", namespace='" + namespace + '\'' + '}'; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/Insight.java b/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/Insight.java deleted file mode 100644 index ca4e6455345..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/Insight.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights.schema; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; - -@JsonIgnoreProperties(ignoreUnknown = true) -@JsonInclude(JsonInclude.Include.NON_EMPTY) -public class Insight { - @JsonProperty("metadata") - private final InsightMetadata metadata; - - @JsonProperty("data") - private final T insightData; - - @JsonCreator - public Insight(@JsonProperty("metadata") InsightMetadata metadata, @JsonProperty("data") T data) { - this.metadata = metadata; - this.insightData = data; - } - - public InsightMetadata getMetadata() { - return metadata; - } - - public T getInsightData() { - return insightData; - } - - @Override - public String toString() { - return "Insight{" + "metadata=" + metadata + ", insightData=" + insightData + '}'; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/InsightMetadata.java b/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/InsightMetadata.java deleted file mode 100644 index d7397d813aa..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/InsightMetadata.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights.schema; - -import com.datastax.oss.driver.shaded.guava.common.base.Preconditions; -import com.datastax.oss.driver.shaded.guava.common.base.Strings; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.Map; -import java.util.Objects; - -public class InsightMetadata { - @JsonProperty("name") - private final String name; - - @JsonProperty("timestamp") - private final long timestamp; - - @JsonProperty("tags") - private final Map tags; - - @JsonProperty("insightType") - private final InsightType insightType; - - @JsonProperty("insightMappingId") - @JsonInclude(JsonInclude.Include.NON_NULL) - private String insightMappingId; - - @JsonCreator - public InsightMetadata( - @JsonProperty("name") String name, - @JsonProperty("timestamp") long timestamp, - @JsonProperty("tags") Map tags, - @JsonProperty("insightType") InsightType insightType, - @JsonProperty("insightMappingId") String insightMappingId) { - Preconditions.checkArgument(!Strings.isNullOrEmpty(name), "name is required"); - - this.name = name; - this.timestamp = timestamp; - this.tags = tags; - this.insightType = insightType; - this.insightMappingId = insightMappingId; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof InsightMetadata)) { - return false; - } - InsightMetadata that = (InsightMetadata) o; - return Objects.equals(name, that.name) - && timestamp == that.timestamp - && Objects.equals(tags, that.tags) - && insightType == that.insightType - && Objects.equals(insightMappingId, that.insightMappingId); - } - - @Override - public int hashCode() { - return Objects.hash(name, timestamp, tags, insightType, insightMappingId); - } - - @Override - public String toString() { - return "InsightMetadata{" - + "name='" - + name - + '\'' - + ", timestamp=" - + timestamp - + ", tags=" - + tags - + ", insightType=" - + insightType - + ", insightMappingId=" - + insightMappingId - + '}'; - } - - public String getName() { - return name; - } - - public long getTimestamp() { - return timestamp; - } - - public Map getTags() { - return tags; - } - - public InsightType getInsightType() { - return insightType; - } - - public String getInsightMappingId() { - return insightMappingId; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/InsightType.java b/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/InsightType.java deleted file mode 100644 index ae91e27d227..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/InsightType.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights.schema; - -public enum InsightType { - EVENT, - GAUGE, - COUNTER, - HISTOGRAM, - TIMER, - METER, - LOG; -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/InsightsPlatformInfo.java b/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/InsightsPlatformInfo.java deleted file mode 100644 index 231f082d785..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/InsightsPlatformInfo.java +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights.schema; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.Map; -import java.util.Objects; - -public class InsightsPlatformInfo { - @JsonProperty("os") - private final OS os; - - @JsonProperty("cpus") - private CPUS cpus; - - /** - * All dependencies in a map format grouped by the module: {"core" : {"com.datastax.driver:core": - * {"runtimeVersion:" : "1.0.0", "compileVersion": "1.0.1"},...}}, "extras"" {...} - */ - @JsonProperty("runtime") - private Map> runtime; - - @JsonCreator - public InsightsPlatformInfo( - @JsonProperty("os") OS os, - @JsonProperty("cpus") CPUS cpus, - @JsonProperty("runtime") Map> runtime) { - this.os = os; - this.cpus = cpus; - this.runtime = runtime; - } - - public OS getOs() { - return os; - } - - public CPUS getCpus() { - return cpus; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof InsightsPlatformInfo)) { - return false; - } - InsightsPlatformInfo that = (InsightsPlatformInfo) o; - return Objects.equals(os, that.os) - && Objects.equals(cpus, that.cpus) - && Objects.equals(runtime, that.runtime); - } - - @Override - public int hashCode() { - return Objects.hash(os, cpus, runtime); - } - - Map> getRuntime() { - return runtime; - } - - public static class OS { - @JsonProperty("name") - private final String name; - - @JsonProperty("version") - private final String version; - - @JsonProperty("arch") - private final String arch; - - @JsonCreator - public OS( - @JsonProperty("name") String name, - @JsonProperty("version") String version, - @JsonProperty("arch") String arch) { - this.name = name; - this.version = version; - this.arch = arch; - } - - public String getName() { - return name; - } - - public String getVersion() { - return version; - } - - public String getArch() { - return arch; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof OS)) { - return false; - } - OS os = (OS) o; - return Objects.equals(name, os.name) - && Objects.equals(version, os.version) - && Objects.equals(arch, os.arch); - } - - @Override - public int hashCode() { - return Objects.hash(name, version, arch); - } - } - - public static class CPUS { - @JsonProperty("length") - private final int length; - - @JsonProperty("model") - private final String model; - - @JsonCreator - public CPUS(@JsonProperty("length") int length, @JsonProperty("model") String model) { - this.length = length; - this.model = model; - } - - public int getLength() { - return length; - } - - public String getModel() { - return model; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof CPUS)) { - return false; - } - CPUS cpus = (CPUS) o; - return length == cpus.length && Objects.equals(model, cpus.model); - } - - @Override - public int hashCode() { - return Objects.hash(length, model); - } - } - - public static class RuntimeAndCompileTimeVersions { - @JsonProperty("runtimeVersion") - private final String runtimeVersion; - - @JsonProperty("compileVersion") - private final String compileVersion; - - @JsonProperty("optional") - private final boolean optional; - - @JsonCreator - public RuntimeAndCompileTimeVersions( - @JsonProperty("runtimeVersion") String runtimeVersion, - @JsonProperty("compileVersion") String compileVersion, - @JsonProperty("optional") boolean optional) { - this.runtimeVersion = runtimeVersion; - this.compileVersion = compileVersion; - this.optional = optional; - } - - public String getRuntimeVersion() { - return runtimeVersion; - } - - public String getCompileVersion() { - return compileVersion; - } - - public boolean isOptional() { - return optional; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof RuntimeAndCompileTimeVersions)) { - return false; - } - RuntimeAndCompileTimeVersions that = (RuntimeAndCompileTimeVersions) o; - return optional == that.optional - && Objects.equals(runtimeVersion, that.runtimeVersion) - && Objects.equals(compileVersion, that.compileVersion); - } - - @Override - public int hashCode() { - return Objects.hash(runtimeVersion, compileVersion, optional); - } - - @Override - public String toString() { - return "RuntimeAndCompileTimeVersions{" - + "runtimeVersion='" - + runtimeVersion - + '\'' - + ", compileVersion='" - + compileVersion - + '\'' - + ", optional=" - + optional - + '}'; - } - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/InsightsStartupData.java b/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/InsightsStartupData.java deleted file mode 100644 index bddd3ef94b3..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/InsightsStartupData.java +++ /dev/null @@ -1,425 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights.schema; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.List; -import java.util.Map; -import java.util.Set; - -public class InsightsStartupData { - @JsonProperty("clientId") - private final String clientId; - - @JsonProperty("sessionId") - private final String sessionId; - - @JsonProperty("applicationName") - private final String applicationName; - - @JsonProperty("applicationVersion") - private final String applicationVersion; - - @JsonProperty("contactPoints") - private final Map> contactPoints; - - @JsonProperty("initialControlConnection") - private final String initialControlConnection; - - @JsonProperty("protocolVersion") - private final int protocolVersion; - - @JsonProperty("localAddress") - private final String localAddress; - - @JsonProperty("executionProfiles") - private final Map executionProfiles; - - @JsonProperty("poolSizeByHostDistance") - private final PoolSizeByHostDistance poolSizeByHostDistance; - - @JsonProperty("heartbeatInterval") - private final long heartbeatInterval; - - @JsonProperty("compression") - private final String compression; - - @JsonProperty("reconnectionPolicy") - private final ReconnectionPolicyInfo reconnectionPolicy; - - @JsonProperty("ssl") - private final SSL ssl; - - @JsonProperty("authProvider") - private final AuthProviderType authProvider; - - @JsonProperty("otherOptions") - private final Map otherOptions; - - @JsonProperty("configAntiPatterns") - private final Map configAntiPatterns; - - @JsonProperty("periodicStatusInterval") - private final long periodicStatusInterval; - - @JsonProperty("platformInfo") - private final InsightsPlatformInfo platformInfo; - - @JsonProperty("hostName") - private final String hostName; - - @JsonProperty("driverName") - private String driverName; - - @JsonProperty("applicationNameWasGenerated") - private boolean applicationNameWasGenerated; - - @JsonProperty("driverVersion") - private String driverVersion; - - @JsonProperty("dataCenters") - private Set dataCenters; - - @JsonCreator - private InsightsStartupData( - @JsonProperty("clientId") String clientId, - @JsonProperty("sessionId") String sessionId, - @JsonProperty("applicationName") String applicationName, - @JsonProperty("applicationVersion") String applicationVersion, - @JsonProperty("contactPoints") Map> contactPoints, - @JsonProperty("initialControlConnection") String initialControlConnection, - @JsonProperty("protocolVersion") int protocolVersion, - @JsonProperty("localAddress") String localAddress, - @JsonProperty("executionProfiles") Map executionProfiles, - @JsonProperty("poolSizeByHostDistance") PoolSizeByHostDistance poolSizeByHostDistance, - @JsonProperty("heartbeatInterval") long heartbeatInterval, - @JsonProperty("compression") String compression, - @JsonProperty("reconnectionPolicy") ReconnectionPolicyInfo reconnectionPolicy, - @JsonProperty("ssl") SSL ssl, - @JsonProperty("authProvider") AuthProviderType authProvider, - @JsonProperty("otherOptions") Map otherOptions, - @JsonProperty("configAntiPatterns") Map configAntiPatterns, - @JsonProperty("periodicStatusInterval") long periodicStatusInterval, - @JsonProperty("platformInfo") InsightsPlatformInfo platformInfo, - @JsonProperty("hostName") String hostName, - @JsonProperty("driverName") String driverName, - @JsonProperty("applicationNameWasGenerated") boolean applicationNameWasGenerated, - @JsonProperty("driverVersion") String driverVersion, - @JsonProperty("dataCenters") Set dataCenters) { - this.clientId = clientId; - this.sessionId = sessionId; - this.applicationName = applicationName; - this.applicationVersion = applicationVersion; - this.contactPoints = contactPoints; - this.initialControlConnection = initialControlConnection; - this.protocolVersion = protocolVersion; - this.localAddress = localAddress; - this.executionProfiles = executionProfiles; - this.poolSizeByHostDistance = poolSizeByHostDistance; - this.heartbeatInterval = heartbeatInterval; - this.compression = compression; - this.reconnectionPolicy = reconnectionPolicy; - this.ssl = ssl; - this.authProvider = authProvider; - this.otherOptions = otherOptions; - this.configAntiPatterns = configAntiPatterns; - this.periodicStatusInterval = periodicStatusInterval; - this.platformInfo = platformInfo; - this.hostName = hostName; - this.driverName = driverName; - this.applicationNameWasGenerated = applicationNameWasGenerated; - this.driverVersion = driverVersion; - this.dataCenters = dataCenters; - } - - public String getClientId() { - return clientId; - } - - public String getSessionId() { - return sessionId; - } - - public String getApplicationName() { - return applicationName; - } - - public String getApplicationVersion() { - return applicationVersion; - } - - public Map> getContactPoints() { - return contactPoints; - } - - public String getInitialControlConnection() { - return initialControlConnection; - } - - public int getProtocolVersion() { - return protocolVersion; - } - - public String getLocalAddress() { - return localAddress; - } - - public Map getExecutionProfiles() { - return executionProfiles; - } - - public PoolSizeByHostDistance getPoolSizeByHostDistance() { - return poolSizeByHostDistance; - } - - public long getHeartbeatInterval() { - return heartbeatInterval; - } - - public String getCompression() { - return compression; - } - - public ReconnectionPolicyInfo getReconnectionPolicy() { - return reconnectionPolicy; - } - - public SSL getSsl() { - return ssl; - } - - public AuthProviderType getAuthProvider() { - return authProvider; - } - - public Map getOtherOptions() { - return otherOptions; - } - - public Map getConfigAntiPatterns() { - return configAntiPatterns; - } - - public long getPeriodicStatusInterval() { - return periodicStatusInterval; - } - - public InsightsPlatformInfo getPlatformInfo() { - return platformInfo; - } - - public String getHostName() { - return hostName; - } - - public String getDriverName() { - return driverName; - } - - public boolean isApplicationNameWasGenerated() { - return applicationNameWasGenerated; - } - - public String getDriverVersion() { - return driverVersion; - } - - public Set getDataCenters() { - return dataCenters; - } - - public static InsightsStartupData.Builder builder() { - return new InsightsStartupData.Builder(); - } - - public static class Builder { - private String clientId; - private String sessionId; - private String applicationName; - private String applicationVersion; - private Map> contactPoints; - private String initialControlConnection; - private int protocolVersion; - private String localAddress; - private Map executionProfiles; - private PoolSizeByHostDistance poolSizeByHostDistance; - private long heartbeatInterval; - private String compression; - private ReconnectionPolicyInfo reconnectionPolicy; - private SSL ssl; - private AuthProviderType authProvider; - private Map otherOptions; - private Map configAntiPatterns; - private long periodicStatusInterval; - private InsightsPlatformInfo platformInfo; - private String hostName; - private String driverName; - private String driverVersion; - private boolean applicationNameWasGenerated; - private Set dataCenters; - - public InsightsStartupData build() { - return new InsightsStartupData( - clientId, - sessionId, - applicationName, - applicationVersion, - contactPoints, - initialControlConnection, - protocolVersion, - localAddress, - executionProfiles, - poolSizeByHostDistance, - heartbeatInterval, - compression, - reconnectionPolicy, - ssl, - authProvider, - otherOptions, - configAntiPatterns, - periodicStatusInterval, - platformInfo, - hostName, - driverName, - applicationNameWasGenerated, - driverVersion, - dataCenters); - } - - public Builder withClientId(String clientId) { - this.clientId = clientId; - return this; - } - - public Builder withSessionId(String id) { - this.sessionId = id; - return this; - } - - public Builder withApplicationName(String applicationName) { - this.applicationName = applicationName; - return this; - } - - public Builder withApplicationVersion(String applicationVersion) { - this.applicationVersion = applicationVersion; - return this; - } - - public Builder withContactPoints(Map> contactPoints) { - this.contactPoints = contactPoints; - return this; - } - - public Builder withInitialControlConnection(String inetSocketAddress) { - this.initialControlConnection = inetSocketAddress; - return this; - } - - public Builder withProtocolVersion(int protocolVersion) { - this.protocolVersion = protocolVersion; - return this; - } - - public Builder withLocalAddress(String localAddress) { - this.localAddress = localAddress; - return this; - } - - public Builder withExecutionProfiles(Map executionProfiles) { - this.executionProfiles = executionProfiles; - return this; - } - - public Builder withPoolSizeByHostDistance(PoolSizeByHostDistance poolSizeByHostDistance) { - this.poolSizeByHostDistance = poolSizeByHostDistance; - return this; - } - - public Builder withHeartbeatInterval(long heartbeatInterval) { - this.heartbeatInterval = heartbeatInterval; - return this; - } - - public Builder withCompression(String compression) { - this.compression = compression; - return this; - } - - public Builder withReconnectionPolicy(ReconnectionPolicyInfo reconnectionPolicy) { - this.reconnectionPolicy = reconnectionPolicy; - return this; - } - - public Builder withSsl(SSL ssl) { - this.ssl = ssl; - return this; - } - - public Builder withAuthProvider(AuthProviderType authProvider) { - this.authProvider = authProvider; - return this; - } - - public Builder withOtherOptions(Map otherOptions) { - this.otherOptions = otherOptions; - return this; - } - - public Builder withConfigAntiPatterns(Map configAntiPatterns) { - this.configAntiPatterns = configAntiPatterns; - return this; - } - - public Builder withPeriodicStatusInterval(long periodicStatusInterval) { - this.periodicStatusInterval = periodicStatusInterval; - return this; - } - - public Builder withPlatformInfo(InsightsPlatformInfo insightsPlatformInfo) { - this.platformInfo = insightsPlatformInfo; - return this; - } - - public Builder withHostName(String hostName) { - this.hostName = hostName; - return this; - } - - public Builder withDriverName(String driverName) { - this.driverName = driverName; - return this; - } - - public Builder withDriverVersion(String driverVersion) { - this.driverVersion = driverVersion; - return this; - } - - public Builder withApplicationNameWasGenerated(boolean applicationNameWasGenerated) { - this.applicationNameWasGenerated = applicationNameWasGenerated; - return this; - } - - public Builder withDataCenters(Set dataCenters) { - this.dataCenters = dataCenters; - return this; - } - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/InsightsStatusData.java b/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/InsightsStatusData.java deleted file mode 100644 index 6f5a135f7c4..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/InsightsStatusData.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights.schema; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.Map; -import java.util.Objects; - -public class InsightsStatusData { - @JsonProperty("clientId") - private final String clientId; - - @JsonProperty("sessionId") - private final String sessionId; - - @JsonProperty("controlConnection") - private final String controlConnection; - - @JsonProperty("connectedNodes") - private final Map connectedNodes; - - @JsonCreator - private InsightsStatusData( - @JsonProperty("clientId") String clientId, - @JsonProperty("sessionId") String sessionId, - @JsonProperty("controlConnection") String controlConnection, - @JsonProperty("connectedNodes") Map connectedNodes) { - this.clientId = clientId; - this.sessionId = sessionId; - this.controlConnection = controlConnection; - this.connectedNodes = connectedNodes; - } - - public String getClientId() { - return clientId; - } - - public String getSessionId() { - return sessionId; - } - - public String getControlConnection() { - return controlConnection; - } - - public Map getConnectedNodes() { - return connectedNodes; - } - - @Override - public String toString() { - return "InsightsStatusData{" - + "clientId='" - + clientId - + '\'' - + ", sessionId='" - + sessionId - + '\'' - + ", controlConnection=" - + controlConnection - + ", connectedNodes=" - + connectedNodes - + '}'; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof InsightsStatusData)) { - return false; - } - InsightsStatusData that = (InsightsStatusData) o; - return Objects.equals(clientId, that.clientId) - && Objects.equals(sessionId, that.sessionId) - && Objects.equals(controlConnection, that.controlConnection) - && Objects.equals(connectedNodes, that.connectedNodes); - } - - @Override - public int hashCode() { - return Objects.hash(clientId, sessionId, controlConnection, connectedNodes); - } - - public static InsightsStatusData.Builder builder() { - return new InsightsStatusData.Builder(); - } - - public static class Builder { - private String clientId; - private String sessionId; - private String controlConnection; - private Map connectedNodes; - - public Builder withClientId(String clientId) { - this.clientId = clientId; - return this; - } - - public Builder withSessionId(String id) { - this.sessionId = id; - return this; - } - - public Builder withControlConnection(String controlConnection) { - this.controlConnection = controlConnection; - return this; - } - - public Builder withConnectedNodes(Map connectedNodes) { - this.connectedNodes = connectedNodes; - return this; - } - - public InsightsStatusData build() { - return new InsightsStatusData(clientId, sessionId, controlConnection, connectedNodes); - } - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/LoadBalancingInfo.java b/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/LoadBalancingInfo.java deleted file mode 100644 index 594583e3f28..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/LoadBalancingInfo.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights.schema; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.Map; -import java.util.Objects; - -public class LoadBalancingInfo { - @JsonProperty("type") - private final String type; - - @JsonProperty("options") - private final Map options; - - @JsonProperty("namespace") - private final String namespace; - - @JsonCreator - public LoadBalancingInfo( - @JsonProperty("type") String type, - @JsonProperty("options") Map options, - @JsonProperty("namespace") String namespace) { - this.type = type; - this.options = options; - this.namespace = namespace; - } - - public String getType() { - return type; - } - - public Map getOptions() { - return options; - } - - public String getNamespace() { - return namespace; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof LoadBalancingInfo)) { - return false; - } - LoadBalancingInfo that = (LoadBalancingInfo) o; - return Objects.equals(type, that.type) - && Objects.equals(options, that.options) - && Objects.equals(namespace, that.namespace); - } - - @Override - public int hashCode() { - return Objects.hash(type, options, namespace); - } - - @Override - public String toString() { - return "LoadBalancingInfo{" - + "type='" - + type - + '\'' - + ", options=" - + options - + ", namespace='" - + namespace - + '\'' - + '}'; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/PoolSizeByHostDistance.java b/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/PoolSizeByHostDistance.java deleted file mode 100644 index 07f76a18d40..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/PoolSizeByHostDistance.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights.schema; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.Objects; - -public class PoolSizeByHostDistance { - @JsonProperty("local") - private final int local; - - @JsonProperty("remote") - private final int remote; - - @JsonProperty("ignored") - private final int ignored; - - @JsonCreator - public PoolSizeByHostDistance( - @JsonProperty("local") int local, - @JsonProperty("remote") int remote, - @JsonProperty("ignored") int ignored) { - - this.local = local; - this.remote = remote; - this.ignored = ignored; - } - - public int getLocal() { - return local; - } - - public int getRemote() { - return remote; - } - - public int getIgnored() { - return ignored; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof PoolSizeByHostDistance)) { - return false; - } - PoolSizeByHostDistance that = (PoolSizeByHostDistance) o; - return local == that.local && remote == that.remote && ignored == that.ignored; - } - - @Override - public int hashCode() { - return Objects.hash(local, remote, ignored); - } - - @Override - public String toString() { - return "PoolSizeByHostDistance{" - + "local=" - + local - + ", remote=" - + remote - + ", ignored=" - + ignored - + '}'; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/ReconnectionPolicyInfo.java b/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/ReconnectionPolicyInfo.java deleted file mode 100644 index 463c23a4325..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/ReconnectionPolicyInfo.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights.schema; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.Map; -import java.util.Objects; - -public class ReconnectionPolicyInfo { - @JsonProperty("type") - private final String type; - - @JsonProperty("options") - private final Map options; - - @JsonProperty("namespace") - private final String namespace; - - @JsonCreator - public ReconnectionPolicyInfo( - @JsonProperty("type") String type, - @JsonProperty("options") Map options, - @JsonProperty("namespace") String namespace) { - - this.type = type; - this.options = options; - this.namespace = namespace; - } - - public String getType() { - return type; - } - - public Map getOptions() { - return options; - } - - public String getNamespace() { - return namespace; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof ReconnectionPolicyInfo)) { - return false; - } - ReconnectionPolicyInfo that = (ReconnectionPolicyInfo) o; - return Objects.equals(type, that.type) - && Objects.equals(options, that.options) - && Objects.equals(namespace, that.namespace); - } - - @Override - public int hashCode() { - return Objects.hash(type, options, namespace); - } - - @Override - public String toString() { - return "ReconnectionPolicyInfo{" - + "type='" - + type - + '\'' - + ", options=" - + options - + ", namespace='" - + namespace - + '\'' - + '}'; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/SSL.java b/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/SSL.java deleted file mode 100644 index debcd85c025..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/SSL.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights.schema; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.Objects; - -public class SSL { - @JsonProperty("enabled") - private final boolean enabled; - - @JsonProperty("certValidation") - private final boolean certValidation; - - @JsonCreator - public SSL( - @JsonProperty("enabled") boolean enabled, - @JsonProperty("certValidation") boolean certValidation) { - this.enabled = enabled; - this.certValidation = certValidation; - } - - public boolean isEnabled() { - return enabled; - } - - public boolean isCertValidation() { - return certValidation; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof SSL)) { - return false; - } - SSL that = (SSL) o; - return enabled == that.enabled && certValidation == that.certValidation; - } - - @Override - public int hashCode() { - return Objects.hash(enabled, certValidation); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/SessionStateForNode.java b/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/SessionStateForNode.java deleted file mode 100644 index 8b50e5b2313..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/SessionStateForNode.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights.schema; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.Objects; - -public class SessionStateForNode { - @JsonProperty("connections") - private final Integer connections; - - @JsonProperty("inFlightQueries") - private final Integer inFlightQueries; - - @JsonCreator - public SessionStateForNode( - @JsonProperty("connections") Integer connections, - @JsonProperty("inFlightQueries") Integer inFlightQueries) { - this.connections = connections; - this.inFlightQueries = inFlightQueries; - } - - public Integer getConnections() { - return connections; - } - - public Integer getInFlightQueries() { - return inFlightQueries; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof SessionStateForNode)) { - return false; - } - SessionStateForNode that = (SessionStateForNode) o; - return Objects.equals(connections, that.connections) - && Objects.equals(inFlightQueries, that.inFlightQueries); - } - - @Override - public int hashCode() { - return Objects.hash(connections, inFlightQueries); - } - - @Override - public String toString() { - return "SessionStateForNode{" - + "connections=" - + connections - + ", inFlightQueries=" - + inFlightQueries - + '}'; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/SpecificExecutionProfile.java b/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/SpecificExecutionProfile.java deleted file mode 100644 index 58652fdf885..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/SpecificExecutionProfile.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights.schema; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.Map; -import java.util.Objects; - -@JsonInclude(JsonInclude.Include.NON_NULL) -public class SpecificExecutionProfile { - @JsonProperty("readTimeout") - private final Integer readTimeout; - - @JsonProperty("loadBalancing") - private final LoadBalancingInfo loadBalancing; - - @JsonProperty("speculativeExecution") - private SpeculativeExecutionInfo speculativeExecution; - - @JsonProperty("consistency") - private final String consistency; - - @JsonProperty("serialConsistency") - private final String serialConsistency; - - @JsonProperty("graphOptions") - private Map graphOptions; - - @JsonCreator - public SpecificExecutionProfile( - @JsonProperty("readTimeout") Integer readTimeoutMillis, - @JsonProperty("loadBalancing") LoadBalancingInfo loadBalancing, - @JsonProperty("speculativeExecution") SpeculativeExecutionInfo speculativeExecutionInfo, - @JsonProperty("consistency") String consistency, - @JsonProperty("serialConsistency") String serialConsistency, - @JsonProperty("graphOptions") Map graphOptions) { - readTimeout = readTimeoutMillis; - this.loadBalancing = loadBalancing; - this.speculativeExecution = speculativeExecutionInfo; - this.consistency = consistency; - this.serialConsistency = serialConsistency; - this.graphOptions = graphOptions; - } - - public Integer getReadTimeout() { - return readTimeout; - } - - public LoadBalancingInfo getLoadBalancing() { - return loadBalancing; - } - - public SpeculativeExecutionInfo getSpeculativeExecution() { - return speculativeExecution; - } - - public String getConsistency() { - return consistency; - } - - public String getSerialConsistency() { - return serialConsistency; - } - - public Map getGraphOptions() { - return graphOptions; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof SpecificExecutionProfile)) { - return false; - } - SpecificExecutionProfile that = (SpecificExecutionProfile) o; - return Objects.equals(readTimeout, that.readTimeout) - && Objects.equals(loadBalancing, that.loadBalancing) - && Objects.equals(speculativeExecution, that.speculativeExecution) - && Objects.equals(consistency, that.consistency) - && Objects.equals(serialConsistency, that.serialConsistency) - && Objects.equals(graphOptions, that.graphOptions); - } - - @Override - public int hashCode() { - return Objects.hash( - readTimeout, - loadBalancing, - speculativeExecution, - consistency, - serialConsistency, - graphOptions); - } - - @Override - public String toString() { - return "SpecificExecutionProfile{" - + "readTimeout=" - + readTimeout - + ", loadBalancing=" - + loadBalancing - + ", speculativeExecution=" - + speculativeExecution - + ", consistency='" - + consistency - + '\'' - + ", serialConsistency='" - + serialConsistency - + '\'' - + ", graphOptions=" - + graphOptions - + '}'; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/SpeculativeExecutionInfo.java b/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/SpeculativeExecutionInfo.java deleted file mode 100644 index 779a4ed9e51..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/insights/schema/SpeculativeExecutionInfo.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights.schema; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.Map; -import java.util.Objects; - -public class SpeculativeExecutionInfo { - @JsonProperty("type") - private final String type; - - @JsonProperty("options") - private final Map options; - - @JsonProperty("namespace") - private String namespace; - - @JsonCreator - public SpeculativeExecutionInfo( - @JsonProperty("type") String type, - @JsonProperty("options") Map options, - @JsonProperty("namespace") String namespace) { - this.type = type; - this.options = options; - this.namespace = namespace; - } - - public String getType() { - return type; - } - - public Map getOptions() { - return options; - } - - public String getNamespace() { - return namespace; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof SpeculativeExecutionInfo)) { - return false; - } - SpeculativeExecutionInfo that = (SpeculativeExecutionInfo) o; - return Objects.equals(type, that.type) - && Objects.equals(options, that.options) - && Objects.equals(namespace, that.namespace); - } - - @Override - public int hashCode() { - return Objects.hash(type, options, namespace); - } - - @Override - public String toString() { - return "SpeculativeExecutionInfo{" - + "type='" - + type - + '\'' - + ", options=" - + options - + ", namespace='" - + namespace - + '\'' - + '}'; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/loadbalancing/DseDcInferringLoadBalancingPolicy.java b/core/src/main/java/com/datastax/dse/driver/internal/core/loadbalancing/DseDcInferringLoadBalancingPolicy.java deleted file mode 100644 index 501fa263258..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/loadbalancing/DseDcInferringLoadBalancingPolicy.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.loadbalancing; - -import com.datastax.oss.driver.api.core.context.DriverContext; -import com.datastax.oss.driver.internal.core.loadbalancing.DcInferringLoadBalancingPolicy; -import edu.umd.cs.findbugs.annotations.NonNull; - -/** - * @deprecated This class only exists for backward compatibility. It is equivalent to {@link - * DcInferringLoadBalancingPolicy}, which should now be used instead. - */ -@Deprecated -public class DseDcInferringLoadBalancingPolicy extends DcInferringLoadBalancingPolicy { - public DseDcInferringLoadBalancingPolicy( - @NonNull DriverContext context, @NonNull String profileName) { - super(context, profileName); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/loadbalancing/DseLoadBalancingPolicy.java b/core/src/main/java/com/datastax/dse/driver/internal/core/loadbalancing/DseLoadBalancingPolicy.java deleted file mode 100644 index 059a37c4774..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/loadbalancing/DseLoadBalancingPolicy.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.loadbalancing; - -import com.datastax.oss.driver.api.core.context.DriverContext; -import com.datastax.oss.driver.internal.core.loadbalancing.DefaultLoadBalancingPolicy; -import edu.umd.cs.findbugs.annotations.NonNull; - -/** - * @deprecated This class only exists for backward compatibility. It is equivalent to {@link - * DefaultLoadBalancingPolicy}, which should now be used instead. - */ -@Deprecated -public class DseLoadBalancingPolicy extends DefaultLoadBalancingPolicy { - public DseLoadBalancingPolicy(@NonNull DriverContext context, @NonNull String profileName) { - super(context, profileName); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/DefaultDseAggregateMetadata.java b/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/DefaultDseAggregateMetadata.java deleted file mode 100644 index 1baa50e7fb8..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/DefaultDseAggregateMetadata.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.metadata.schema; - -import com.datastax.dse.driver.api.core.metadata.schema.DseAggregateMetadata; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.metadata.schema.FunctionSignature; -import com.datastax.oss.driver.api.core.type.DataType; -import com.datastax.oss.driver.api.core.type.codec.TypeCodec; -import com.datastax.oss.driver.internal.core.metadata.schema.DefaultAggregateMetadata; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.util.Objects; -import java.util.Optional; -import net.jcip.annotations.Immutable; - -@Immutable -public class DefaultDseAggregateMetadata extends DefaultAggregateMetadata - implements DseAggregateMetadata { - - @Nullable private final Boolean deterministic; - - public DefaultDseAggregateMetadata( - @NonNull CqlIdentifier keyspace, - @NonNull FunctionSignature signature, - @Nullable FunctionSignature finalFuncSignature, - @Nullable Object initCond, - @NonNull DataType returnType, - @NonNull FunctionSignature stateFuncSignature, - @NonNull DataType stateType, - @NonNull TypeCodec stateTypeCodec, - @Nullable Boolean deterministic) { - super( - keyspace, - signature, - finalFuncSignature, - initCond, - returnType, - stateFuncSignature, - stateType, - stateTypeCodec); - this.deterministic = deterministic; - } - - @Override - @Deprecated - public boolean isDeterministic() { - return deterministic != null && deterministic; - } - - @Override - public Optional getDeterministic() { - return Optional.ofNullable(deterministic); - } - - @Override - public boolean equals(Object other) { - if (other == this) { - return true; - } else if (other instanceof DseAggregateMetadata) { - DseAggregateMetadata that = (DseAggregateMetadata) other; - return Objects.equals(this.getKeyspace(), that.getKeyspace()) - && Objects.equals(this.getSignature(), that.getSignature()) - && Objects.equals( - this.getFinalFuncSignature().orElse(null), that.getFinalFuncSignature().orElse(null)) - && Objects.equals(this.getInitCond().orElse(null), that.getInitCond().orElse(null)) - && Objects.equals(this.getReturnType(), that.getReturnType()) - && Objects.equals(this.getStateFuncSignature(), that.getStateFuncSignature()) - && Objects.equals(this.getStateType(), that.getStateType()) - && Objects.equals(this.deterministic, that.getDeterministic().orElse(null)); - } else { - return false; - } - } - - @Override - public int hashCode() { - return Objects.hash( - getKeyspace(), - getSignature(), - getFinalFuncSignature(), - getInitCond(), - getReturnType(), - getStateFuncSignature(), - getStateType(), - deterministic); - } - - @Override - public String toString() { - return "Aggregate Name: " - + getSignature().getName().asCql(false) - + ", Keyspace: " - + getKeyspace().asCql(false) - + ", Return Type: " - + getReturnType().asCql(false, false) - + ", Deterministic: " - + deterministic; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/DefaultDseColumnMetadata.java b/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/DefaultDseColumnMetadata.java deleted file mode 100644 index 2168f20fdc7..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/DefaultDseColumnMetadata.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.metadata.schema; - -import com.datastax.dse.driver.api.core.metadata.schema.DseColumnMetadata; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.type.DataType; -import com.datastax.oss.driver.internal.core.metadata.schema.DefaultColumnMetadata; -import edu.umd.cs.findbugs.annotations.NonNull; -import net.jcip.annotations.Immutable; - -@Immutable -public class DefaultDseColumnMetadata extends DefaultColumnMetadata implements DseColumnMetadata { - - public DefaultDseColumnMetadata( - @NonNull CqlIdentifier keyspace, - @NonNull CqlIdentifier parent, - @NonNull CqlIdentifier name, - @NonNull DataType dataType, - boolean isStatic) { - super(keyspace, parent, name, dataType, isStatic); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/DefaultDseEdgeMetadata.java b/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/DefaultDseEdgeMetadata.java deleted file mode 100644 index e4de62f294c..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/DefaultDseEdgeMetadata.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.metadata.schema; - -import com.datastax.dse.driver.api.core.metadata.schema.DseEdgeMetadata; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.shaded.guava.common.base.Preconditions; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.io.Serializable; -import java.util.List; -import java.util.Objects; - -public class DefaultDseEdgeMetadata implements DseEdgeMetadata, Serializable { - - private static final long serialVersionUID = 1; - - @NonNull private final CqlIdentifier labelName; - - @NonNull private final CqlIdentifier fromTable; - @NonNull private final CqlIdentifier fromLabel; - @NonNull private final List fromPartitionKeyColumns; - @NonNull private final List fromClusteringColumns; - - @NonNull private final CqlIdentifier toTable; - @NonNull private final CqlIdentifier toLabel; - @NonNull private final List toPartitionKeyColumns; - @NonNull private final List toClusteringColumns; - - public DefaultDseEdgeMetadata( - @NonNull CqlIdentifier labelName, - @NonNull CqlIdentifier fromTable, - @NonNull CqlIdentifier fromLabel, - @NonNull List fromPartitionKeyColumns, - @NonNull List fromClusteringColumns, - @NonNull CqlIdentifier toTable, - @NonNull CqlIdentifier toLabel, - @NonNull List toPartitionKeyColumns, - @NonNull List toClusteringColumns) { - this.labelName = Preconditions.checkNotNull(labelName); - this.fromTable = Preconditions.checkNotNull(fromTable); - this.fromLabel = Preconditions.checkNotNull(fromLabel); - this.fromPartitionKeyColumns = Preconditions.checkNotNull(fromPartitionKeyColumns); - this.fromClusteringColumns = Preconditions.checkNotNull(fromClusteringColumns); - this.toTable = Preconditions.checkNotNull(toTable); - this.toLabel = Preconditions.checkNotNull(toLabel); - this.toPartitionKeyColumns = Preconditions.checkNotNull(toPartitionKeyColumns); - this.toClusteringColumns = Preconditions.checkNotNull(toClusteringColumns); - } - - @NonNull - @Override - public CqlIdentifier getLabelName() { - return labelName; - } - - @NonNull - @Override - public CqlIdentifier getFromTable() { - return fromTable; - } - - @NonNull - @Override - public CqlIdentifier getFromLabel() { - return fromLabel; - } - - @NonNull - @Override - public List getFromPartitionKeyColumns() { - return fromPartitionKeyColumns; - } - - @NonNull - @Override - public List getFromClusteringColumns() { - return fromClusteringColumns; - } - - @NonNull - @Override - public CqlIdentifier getToTable() { - return toTable; - } - - @NonNull - @Override - public CqlIdentifier getToLabel() { - return toLabel; - } - - @NonNull - @Override - public List getToPartitionKeyColumns() { - return toPartitionKeyColumns; - } - - @NonNull - @Override - public List getToClusteringColumns() { - return toClusteringColumns; - } - - @Override - public boolean equals(Object other) { - if (other == this) { - return true; - } else if (other instanceof DseEdgeMetadata) { - DseEdgeMetadata that = (DseEdgeMetadata) other; - return Objects.equals(this.labelName, that.getLabelName()) - && Objects.equals(this.fromTable, that.getFromTable()) - && Objects.equals(this.fromLabel, that.getFromLabel()) - && Objects.equals(this.fromPartitionKeyColumns, that.getFromPartitionKeyColumns()) - && Objects.equals(this.fromClusteringColumns, that.getFromClusteringColumns()) - && Objects.equals(this.toTable, that.getToTable()) - && Objects.equals(this.toLabel, that.getToLabel()) - && Objects.equals(this.toPartitionKeyColumns, that.getToPartitionKeyColumns()) - && Objects.equals(this.toClusteringColumns, that.getToClusteringColumns()); - } else { - return false; - } - } - - @Override - public int hashCode() { - return Objects.hash( - labelName, - fromTable, - fromLabel, - fromPartitionKeyColumns, - fromClusteringColumns, - toTable, - toLabel, - toPartitionKeyColumns, - toClusteringColumns); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/DefaultDseFunctionMetadata.java b/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/DefaultDseFunctionMetadata.java deleted file mode 100644 index 0a94491f1f7..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/DefaultDseFunctionMetadata.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.metadata.schema; - -import com.datastax.dse.driver.api.core.metadata.schema.DseFunctionMetadata; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.metadata.schema.FunctionSignature; -import com.datastax.oss.driver.api.core.type.DataType; -import com.datastax.oss.driver.internal.core.metadata.schema.DefaultFunctionMetadata; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import net.jcip.annotations.Immutable; - -@Immutable -public class DefaultDseFunctionMetadata extends DefaultFunctionMetadata - implements DseFunctionMetadata { - - @Nullable private final Boolean deterministic; - @Nullable private final Monotonicity monotonicity; - @NonNull private final List monotonicArgumentNames; - - public DefaultDseFunctionMetadata( - @NonNull CqlIdentifier keyspace, - @NonNull FunctionSignature signature, - @NonNull List parameterNames, - @NonNull String body, - boolean calledOnNullInput, - @NonNull String language, - @NonNull DataType returnType, - @Nullable Boolean deterministic, - @Nullable Boolean monotonic, - @NonNull List monotonicArgumentNames) { - super(keyspace, signature, parameterNames, body, calledOnNullInput, language, returnType); - // set DSE extension attributes - this.deterministic = deterministic; - this.monotonicity = - monotonic == null - ? null - : monotonic - ? Monotonicity.FULLY_MONOTONIC - : monotonicArgumentNames.isEmpty() - ? Monotonicity.NOT_MONOTONIC - : Monotonicity.PARTIALLY_MONOTONIC; - this.monotonicArgumentNames = ImmutableList.copyOf(monotonicArgumentNames); - } - - @Override - @Deprecated - public boolean isDeterministic() { - return deterministic != null && deterministic; - } - - @Override - public Optional getDeterministic() { - return Optional.ofNullable(deterministic); - } - - @Override - @Deprecated - public boolean isMonotonic() { - return monotonicity == Monotonicity.FULLY_MONOTONIC; - } - - @Override - public Optional getMonotonicity() { - return Optional.ofNullable(monotonicity); - } - - @NonNull - @Override - public List getMonotonicArgumentNames() { - return this.monotonicArgumentNames; - } - - @Override - public boolean equals(Object other) { - if (other == this) { - return true; - } else if (other instanceof DseFunctionMetadata) { - DseFunctionMetadata that = (DseFunctionMetadata) other; - return Objects.equals(this.getKeyspace(), that.getKeyspace()) - && Objects.equals(this.getSignature(), that.getSignature()) - && Objects.equals(this.getParameterNames(), that.getParameterNames()) - && Objects.equals(this.getBody(), that.getBody()) - && this.isCalledOnNullInput() == that.isCalledOnNullInput() - && Objects.equals(this.getLanguage(), that.getLanguage()) - && Objects.equals(this.getReturnType(), that.getReturnType()) - && Objects.equals(this.deterministic, that.getDeterministic().orElse(null)) - && this.monotonicity == that.getMonotonicity().orElse(null) - && Objects.equals(this.monotonicArgumentNames, that.getMonotonicArgumentNames()); - } else { - return false; - } - } - - @Override - public int hashCode() { - return Objects.hash( - getKeyspace(), - getSignature(), - getParameterNames(), - getBody(), - isCalledOnNullInput(), - getLanguage(), - getReturnType(), - deterministic, - monotonicity, - monotonicArgumentNames); - } - - @Override - public String toString() { - return "Function Name: " - + this.getSignature().getName().asCql(false) - + ", Keyspace: " - + this.getKeyspace().asCql(false) - + ", Language: " - + this.getLanguage() - + ", Return Type: " - + getReturnType().asCql(false, false) - + ", Deterministic: " - + this.deterministic - + ", Monotonicity: " - + this.monotonicity - + ", Monotonic On: " - + (this.monotonicArgumentNames.isEmpty() ? "" : this.monotonicArgumentNames.get(0)); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/DefaultDseIndexMetadata.java b/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/DefaultDseIndexMetadata.java deleted file mode 100644 index c66d7934151..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/DefaultDseIndexMetadata.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.metadata.schema; - -import com.datastax.dse.driver.api.core.metadata.schema.DseIndexMetadata; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.metadata.schema.IndexKind; -import com.datastax.oss.driver.internal.core.metadata.schema.DefaultIndexMetadata; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Map; -import net.jcip.annotations.Immutable; - -@Immutable -public class DefaultDseIndexMetadata extends DefaultIndexMetadata implements DseIndexMetadata { - - public DefaultDseIndexMetadata( - @NonNull CqlIdentifier keyspace, - @NonNull CqlIdentifier table, - @NonNull CqlIdentifier name, - @NonNull IndexKind kind, - @NonNull String target, - @NonNull Map options) { - super(keyspace, table, name, kind, target, options); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/DefaultDseKeyspaceMetadata.java b/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/DefaultDseKeyspaceMetadata.java deleted file mode 100644 index 8e54c9082e1..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/DefaultDseKeyspaceMetadata.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.metadata.schema; - -import com.datastax.dse.driver.api.core.metadata.schema.DseGraphKeyspaceMetadata; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.metadata.schema.AggregateMetadata; -import com.datastax.oss.driver.api.core.metadata.schema.FunctionMetadata; -import com.datastax.oss.driver.api.core.metadata.schema.FunctionSignature; -import com.datastax.oss.driver.api.core.metadata.schema.TableMetadata; -import com.datastax.oss.driver.api.core.metadata.schema.ViewMetadata; -import com.datastax.oss.driver.api.core.type.UserDefinedType; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.io.Serializable; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import net.jcip.annotations.Immutable; - -@Immutable -public class DefaultDseKeyspaceMetadata implements DseGraphKeyspaceMetadata, Serializable { - - private static final long serialVersionUID = 1; - - @NonNull private final CqlIdentifier name; - private final boolean durableWrites; - private final boolean virtual; - @Nullable private final String graphEngine; - @NonNull private final Map replication; - @NonNull private final Map types; - @NonNull private final Map tables; - @NonNull private final Map views; - @NonNull private final Map functions; - @NonNull private final Map aggregates; - - public DefaultDseKeyspaceMetadata( - @NonNull CqlIdentifier name, - boolean durableWrites, - boolean virtual, - @Nullable String graphEngine, - @NonNull Map replication, - @NonNull Map types, - @NonNull Map tables, - @NonNull Map views, - @NonNull Map functions, - @NonNull Map aggregates) { - this.name = name; - this.durableWrites = durableWrites; - this.virtual = virtual; - this.graphEngine = graphEngine; - this.replication = replication; - this.types = types; - this.tables = tables; - this.views = views; - this.functions = functions; - this.aggregates = aggregates; - } - - @NonNull - @Override - public CqlIdentifier getName() { - return name; - } - - @Override - public boolean isDurableWrites() { - return durableWrites; - } - - @Override - public boolean isVirtual() { - return virtual; - } - - @NonNull - @Override - public Optional getGraphEngine() { - return Optional.ofNullable(graphEngine); - } - - @NonNull - @Override - public Map getReplication() { - return replication; - } - - @NonNull - @Override - public Map getUserDefinedTypes() { - return types; - } - - @NonNull - @Override - public Map getTables() { - return tables; - } - - @NonNull - @Override - public Map getViews() { - return views; - } - - @NonNull - @Override - public Map getFunctions() { - return functions; - } - - @NonNull - @Override - public Map getAggregates() { - return aggregates; - } - - @Override - public boolean equals(Object other) { - if (other == this) { - return true; - } else if (other instanceof DseGraphKeyspaceMetadata) { - DseGraphKeyspaceMetadata that = (DseGraphKeyspaceMetadata) other; - return Objects.equals(this.name, that.getName()) - && this.durableWrites == that.isDurableWrites() - && this.virtual == that.isVirtual() - && Objects.equals(this.graphEngine, that.getGraphEngine().orElse(null)) - && Objects.equals(this.replication, that.getReplication()) - && Objects.equals(this.types, that.getUserDefinedTypes()) - && Objects.equals(this.tables, that.getTables()) - && Objects.equals(this.views, that.getViews()) - && Objects.equals(this.functions, that.getFunctions()) - && Objects.equals(this.aggregates, that.getAggregates()); - } else { - return false; - } - } - - @Override - public int hashCode() { - return Objects.hash( - name, - durableWrites, - virtual, - graphEngine, - replication, - types, - tables, - views, - functions, - aggregates); - } - - @Override - public boolean shallowEquals(Object other) { - if (other == this) { - return true; - } else if (other instanceof DseGraphKeyspaceMetadata) { - DseGraphKeyspaceMetadata that = (DseGraphKeyspaceMetadata) other; - return Objects.equals(this.name, that.getName()) - && this.durableWrites == that.isDurableWrites() - && Objects.equals(this.graphEngine, that.getGraphEngine().orElse(null)) - && Objects.equals(this.replication, that.getReplication()); - } else { - return false; - } - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/DefaultDseTableMetadata.java b/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/DefaultDseTableMetadata.java deleted file mode 100644 index f8fb8cc10d1..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/DefaultDseTableMetadata.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.metadata.schema; - -import com.datastax.dse.driver.api.core.metadata.schema.DseEdgeMetadata; -import com.datastax.dse.driver.api.core.metadata.schema.DseGraphTableMetadata; -import com.datastax.dse.driver.api.core.metadata.schema.DseVertexMetadata; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.metadata.schema.ClusteringOrder; -import com.datastax.oss.driver.api.core.metadata.schema.ColumnMetadata; -import com.datastax.oss.driver.api.core.metadata.schema.IndexMetadata; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.io.Serializable; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.UUID; -import net.jcip.annotations.Immutable; - -@Immutable -public class DefaultDseTableMetadata implements DseGraphTableMetadata, Serializable { - - private static final long serialVersionUID = 1; - - @NonNull private final CqlIdentifier keyspace; - @NonNull private final CqlIdentifier name; - // null for virtual tables - @Nullable private final UUID id; - private final boolean compactStorage; - private final boolean virtual; - @NonNull private final List partitionKey; - @NonNull private final Map clusteringColumns; - @NonNull private final Map columns; - @NonNull private final Map options; - @NonNull private final Map indexes; - @Nullable private final DseVertexMetadata vertex; - @Nullable private final DseEdgeMetadata edge; - - public DefaultDseTableMetadata( - @NonNull CqlIdentifier keyspace, - @NonNull CqlIdentifier name, - @Nullable UUID id, - boolean compactStorage, - boolean virtual, - @NonNull List partitionKey, - @NonNull Map clusteringColumns, - @NonNull Map columns, - @NonNull Map options, - @NonNull Map indexes, - @Nullable DseVertexMetadata vertex, - @Nullable DseEdgeMetadata edge) { - this.keyspace = keyspace; - this.name = name; - this.id = id; - this.compactStorage = compactStorage; - this.virtual = virtual; - this.partitionKey = partitionKey; - this.clusteringColumns = clusteringColumns; - this.columns = columns; - this.options = options; - this.indexes = indexes; - this.vertex = vertex; - this.edge = edge; - } - - @NonNull - @Override - public CqlIdentifier getKeyspace() { - return keyspace; - } - - @NonNull - @Override - public CqlIdentifier getName() { - return name; - } - - @NonNull - @Override - public Optional getId() { - return Optional.ofNullable(id); - } - - @Override - public boolean isCompactStorage() { - return compactStorage; - } - - @Override - public boolean isVirtual() { - return virtual; - } - - @NonNull - @Override - public List getPartitionKey() { - return partitionKey; - } - - @NonNull - @Override - public Map getClusteringColumns() { - return clusteringColumns; - } - - @NonNull - @Override - public Map getColumns() { - return columns; - } - - @NonNull - @Override - public Map getOptions() { - return options; - } - - @NonNull - @Override - public Map getIndexes() { - return indexes; - } - - @NonNull - @Override - public Optional getVertex() { - return Optional.ofNullable(vertex); - } - - @NonNull - @Override - public Optional getEdge() { - return Optional.ofNullable(edge); - } - - @Override - public boolean equals(Object other) { - if (other == this) { - return true; - } else if (other instanceof DseGraphTableMetadata) { - DseGraphTableMetadata that = (DseGraphTableMetadata) other; - return Objects.equals(this.keyspace, that.getKeyspace()) - && Objects.equals(this.name, that.getName()) - && Objects.equals(this.id, that.getId().orElse(null)) - && this.compactStorage == that.isCompactStorage() - && this.virtual == that.isVirtual() - && Objects.equals(this.partitionKey, that.getPartitionKey()) - && Objects.equals(this.clusteringColumns, that.getClusteringColumns()) - && Objects.equals(this.columns, that.getColumns()) - && Objects.equals(this.indexes, that.getIndexes()) - && Objects.equals(this.vertex, that.getVertex().orElse(null)) - && Objects.equals(this.edge, that.getEdge().orElse(null)); - } else { - return false; - } - } - - @Override - public int hashCode() { - return Objects.hash( - keyspace, - name, - id, - compactStorage, - virtual, - partitionKey, - clusteringColumns, - columns, - indexes, - vertex, - edge); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/DefaultDseVertexMetadata.java b/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/DefaultDseVertexMetadata.java deleted file mode 100644 index 05ba2823704..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/DefaultDseVertexMetadata.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.metadata.schema; - -import com.datastax.dse.driver.api.core.metadata.schema.DseVertexMetadata; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.shaded.guava.common.base.Preconditions; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.io.Serializable; -import java.util.Objects; - -public class DefaultDseVertexMetadata implements DseVertexMetadata, Serializable { - - private static final long serialVersionUID = 1; - - @NonNull private final CqlIdentifier labelName; - - public DefaultDseVertexMetadata(@NonNull CqlIdentifier labelName) { - this.labelName = Preconditions.checkNotNull(labelName); - } - - @NonNull - @Override - public CqlIdentifier getLabelName() { - return labelName; - } - - @Override - public boolean equals(Object other) { - if (other == this) { - return true; - } else if (other instanceof DefaultDseVertexMetadata) { - DefaultDseVertexMetadata that = (DefaultDseVertexMetadata) other; - return Objects.equals(this.labelName, that.getLabelName()); - } else { - return false; - } - } - - @Override - public int hashCode() { - return labelName.hashCode(); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/DefaultDseViewMetadata.java b/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/DefaultDseViewMetadata.java deleted file mode 100644 index f04b7640041..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/DefaultDseViewMetadata.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.metadata.schema; - -import com.datastax.dse.driver.api.core.metadata.schema.DseViewMetadata; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.metadata.schema.ClusteringOrder; -import com.datastax.oss.driver.api.core.metadata.schema.ColumnMetadata; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.io.Serializable; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.UUID; -import net.jcip.annotations.Immutable; - -@Immutable -public class DefaultDseViewMetadata implements DseViewMetadata, Serializable { - - private static final long serialVersionUID = 1; - - @NonNull private final CqlIdentifier keyspace; - @NonNull private final CqlIdentifier name; - @NonNull private final CqlIdentifier baseTable; - private final boolean includesAllColumns; - @Nullable private final String whereClause; - @NonNull private final UUID id; - @NonNull private final ImmutableList partitionKey; - @NonNull private final ImmutableMap clusteringColumns; - @NonNull private final ImmutableMap columns; - @NonNull private final Map options; - - public DefaultDseViewMetadata( - @NonNull CqlIdentifier keyspace, - @NonNull CqlIdentifier name, - @NonNull CqlIdentifier baseTable, - boolean includesAllColumns, - @Nullable String whereClause, - @NonNull UUID id, - @NonNull ImmutableList partitionKey, - @NonNull ImmutableMap clusteringColumns, - @NonNull ImmutableMap columns, - @NonNull Map options) { - this.keyspace = keyspace; - this.name = name; - this.baseTable = baseTable; - this.includesAllColumns = includesAllColumns; - this.whereClause = whereClause; - this.id = id; - this.partitionKey = partitionKey; - this.clusteringColumns = clusteringColumns; - this.columns = columns; - this.options = options; - } - - @NonNull - @Override - public CqlIdentifier getKeyspace() { - return keyspace; - } - - @NonNull - @Override - public CqlIdentifier getName() { - return name; - } - - @NonNull - @Override - public Optional getId() { - return Optional.of(id); - } - - @NonNull - @Override - public CqlIdentifier getBaseTable() { - return baseTable; - } - - @Override - public boolean includesAllColumns() { - return includesAllColumns; - } - - @NonNull - @Override - public Optional getWhereClause() { - return Optional.ofNullable(whereClause); - } - - @NonNull - @Override - public List getPartitionKey() { - return partitionKey; - } - - @NonNull - @Override - public Map getClusteringColumns() { - return clusteringColumns; - } - - @NonNull - @Override - public Map getColumns() { - return columns; - } - - @NonNull - @Override - public Map getOptions() { - return options; - } - - @Override - public boolean equals(Object other) { - if (other == this) { - return true; - } else if (other instanceof DseViewMetadata) { - DseViewMetadata that = (DseViewMetadata) other; - return Objects.equals(this.keyspace, that.getKeyspace()) - && Objects.equals(this.name, that.getName()) - && Objects.equals(this.baseTable, that.getBaseTable()) - && this.includesAllColumns == that.includesAllColumns() - && Objects.equals(this.whereClause, that.getWhereClause().orElse(null)) - && Objects.equals(Optional.of(this.id), that.getId()) - && Objects.equals(this.partitionKey, that.getPartitionKey()) - && Objects.equals(this.clusteringColumns, that.getClusteringColumns()) - && Objects.equals(this.columns, that.getColumns()) - && Objects.equals(this.options, that.getOptions()); - } else { - return false; - } - } - - @Override - public int hashCode() { - return Objects.hash( - keyspace, - name, - baseTable, - includesAllColumns, - whereClause, - id, - partitionKey, - clusteringColumns, - columns, - options); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/ScriptHelper.java b/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/ScriptHelper.java deleted file mode 100644 index 64f6cac19f0..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/ScriptHelper.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.metadata.schema; - -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.internal.core.metadata.schema.ScriptBuilder; -import java.util.List; - -public class ScriptHelper { - - public static void appendEdgeSide( - ScriptBuilder builder, - CqlIdentifier table, - CqlIdentifier label, - List partitionKeyColumns, - List clusteringColumns, - String keyword) { - builder.append(" ").append(keyword).append(label).append("("); - - if (partitionKeyColumns.size() == 1) { // PRIMARY KEY (k - builder.append(partitionKeyColumns.get(0)); - } else { // PRIMARY KEY ((k1, k2) - builder.append("("); - boolean first = true; - for (CqlIdentifier pkColumn : partitionKeyColumns) { - if (first) { - first = false; - } else { - builder.append(", "); - } - builder.append(pkColumn); - } - builder.append(")"); - } - // PRIMARY KEY (, cc1, cc2, cc3) - for (CqlIdentifier clusteringColumn : clusteringColumns) { - builder.append(", ").append(clusteringColumn); - } - builder.append(")"); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/parsing/DseAggregateParser.java b/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/parsing/DseAggregateParser.java deleted file mode 100644 index 37a7a2768c2..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/parsing/DseAggregateParser.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.metadata.schema.parsing; - -import com.datastax.dse.driver.api.core.metadata.schema.DseAggregateMetadata; -import com.datastax.dse.driver.internal.core.metadata.schema.DefaultDseAggregateMetadata; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.metadata.schema.AggregateMetadata; -import com.datastax.oss.driver.api.core.type.UserDefinedType; -import com.datastax.oss.driver.internal.core.adminrequest.AdminRow; -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import com.datastax.oss.driver.internal.core.metadata.schema.parsing.AggregateParser; -import com.datastax.oss.driver.internal.core.metadata.schema.parsing.DataTypeParser; -import java.util.Map; -import net.jcip.annotations.ThreadSafe; - -@ThreadSafe -public class DseAggregateParser { - - private final AggregateParser aggregateParser; - private final InternalDriverContext context; - - public DseAggregateParser(DataTypeParser dataTypeParser, InternalDriverContext context) { - this.aggregateParser = new AggregateParser(dataTypeParser, context); - this.context = context; - } - - public DseAggregateMetadata parseAggregate( - AdminRow row, - CqlIdentifier keyspaceId, - Map userDefinedTypes) { - AggregateMetadata aggregate = aggregateParser.parseAggregate(row, keyspaceId, userDefinedTypes); - // parse the DSE extended columns - final Boolean deterministic = - row.contains("deterministic") ? row.getBoolean("deterministic") : null; - - return new DefaultDseAggregateMetadata( - aggregate.getKeyspace(), - aggregate.getSignature(), - aggregate.getFinalFuncSignature().orElse(null), - aggregate.getInitCond().orElse(null), - aggregate.getReturnType(), - aggregate.getStateFuncSignature(), - aggregate.getStateType(), - context.getCodecRegistry().codecFor(aggregate.getStateType()), - deterministic); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/parsing/DseFunctionParser.java b/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/parsing/DseFunctionParser.java deleted file mode 100644 index 0d88bce8740..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/parsing/DseFunctionParser.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.metadata.schema.parsing; - -import com.datastax.dse.driver.api.core.metadata.schema.DseFunctionMetadata; -import com.datastax.dse.driver.internal.core.metadata.schema.DefaultDseFunctionMetadata; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.metadata.schema.FunctionMetadata; -import com.datastax.oss.driver.api.core.type.UserDefinedType; -import com.datastax.oss.driver.internal.core.adminrequest.AdminRow; -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import com.datastax.oss.driver.internal.core.metadata.schema.parsing.DataTypeParser; -import com.datastax.oss.driver.internal.core.metadata.schema.parsing.FunctionParser; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import net.jcip.annotations.ThreadSafe; - -@ThreadSafe -public class DseFunctionParser { - - private final FunctionParser functionParser; - - public DseFunctionParser(DataTypeParser dataTypeParser, InternalDriverContext context) { - this.functionParser = new FunctionParser(dataTypeParser, context); - } - - public DseFunctionMetadata parseFunction( - AdminRow row, - CqlIdentifier keyspaceId, - Map userDefinedTypes) { - FunctionMetadata function = functionParser.parseFunction(row, keyspaceId, userDefinedTypes); - // parse the DSE extended columns - final Boolean deterministic = - row.contains("deterministic") ? row.getBoolean("deterministic") : null; - final Boolean monotonic = row.contains("monotonic") ? row.getBoolean("monotonic") : null; - // stream the list of strings into a list of CqlIdentifiers - final List monotonicOn = - row.contains("monotonic_on") - ? row.getListOfString("monotonic_on").stream() - .map(CqlIdentifier::fromInternal) - .collect(Collectors.toList()) - : Collections.emptyList(); - - return new DefaultDseFunctionMetadata( - function.getKeyspace(), - function.getSignature(), - function.getParameterNames(), - function.getBody(), - function.isCalledOnNullInput(), - function.getLanguage(), - function.getReturnType(), - deterministic, - monotonic, - monotonicOn); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/parsing/DseSchemaParser.java b/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/parsing/DseSchemaParser.java deleted file mode 100644 index ca7fb74a746..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/parsing/DseSchemaParser.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.metadata.schema.parsing; - -import com.datastax.dse.driver.api.core.metadata.schema.DseAggregateMetadata; -import com.datastax.dse.driver.api.core.metadata.schema.DseFunctionMetadata; -import com.datastax.dse.driver.api.core.metadata.schema.DseKeyspaceMetadata; -import com.datastax.dse.driver.api.core.metadata.schema.DseTableMetadata; -import com.datastax.dse.driver.api.core.metadata.schema.DseViewMetadata; -import com.datastax.dse.driver.internal.core.metadata.schema.DefaultDseKeyspaceMetadata; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.metadata.schema.AggregateMetadata; -import com.datastax.oss.driver.api.core.metadata.schema.FunctionMetadata; -import com.datastax.oss.driver.api.core.metadata.schema.FunctionSignature; -import com.datastax.oss.driver.api.core.metadata.schema.KeyspaceMetadata; -import com.datastax.oss.driver.api.core.metadata.schema.TableMetadata; -import com.datastax.oss.driver.api.core.metadata.schema.ViewMetadata; -import com.datastax.oss.driver.api.core.type.UserDefinedType; -import com.datastax.oss.driver.internal.core.adminrequest.AdminRow; -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import com.datastax.oss.driver.internal.core.metadata.schema.parsing.CassandraSchemaParser; -import com.datastax.oss.driver.internal.core.metadata.schema.parsing.SchemaParser; -import com.datastax.oss.driver.internal.core.metadata.schema.parsing.SimpleJsonParser; -import com.datastax.oss.driver.internal.core.metadata.schema.parsing.UserDefinedTypeParser; -import com.datastax.oss.driver.internal.core.metadata.schema.queries.SchemaRows; -import com.datastax.oss.driver.internal.core.metadata.schema.refresh.SchemaRefresh; -import com.datastax.oss.driver.internal.core.util.NanoTime; -import com.datastax.oss.driver.shaded.guava.common.base.MoreObjects; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import com.datastax.oss.driver.shaded.guava.common.collect.Multimap; -import java.util.Collections; -import java.util.Map; -import net.jcip.annotations.ThreadSafe; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Default parser implementation for DSE. - * - *

For modularity, the code for each element row is split into separate classes (schema stuff is - * not on the hot path, so creating a few extra objects doesn't matter). - */ -@ThreadSafe -public class DseSchemaParser implements SchemaParser { - - private static final Logger LOG = LoggerFactory.getLogger(CassandraSchemaParser.class); - - private final SchemaRows rows; - private final UserDefinedTypeParser userDefinedTypeParser; - private final DseTableParser tableParser; - private final DseViewParser viewParser; - private final DseFunctionParser functionParser; - private final DseAggregateParser aggregateParser; - private final String logPrefix; - private final long startTimeNs = System.nanoTime(); - - public DseSchemaParser(SchemaRows rows, InternalDriverContext context) { - this.rows = rows; - this.logPrefix = context.getSessionName(); - - this.userDefinedTypeParser = new UserDefinedTypeParser(rows.dataTypeParser(), context); - this.tableParser = new DseTableParser(rows, context); - this.viewParser = new DseViewParser(rows, context); - this.functionParser = new DseFunctionParser(rows.dataTypeParser(), context); - this.aggregateParser = new DseAggregateParser(rows.dataTypeParser(), context); - } - - @Override - public SchemaRefresh parse() { - ImmutableMap.Builder keyspacesBuilder = ImmutableMap.builder(); - for (AdminRow row : rows.keyspaces()) { - DseKeyspaceMetadata keyspace = parseKeyspace(row); - keyspacesBuilder.put(keyspace.getName(), keyspace); - } - for (AdminRow row : rows.virtualKeyspaces()) { - DseKeyspaceMetadata keyspace = parseVirtualKeyspace(row); - keyspacesBuilder.put(keyspace.getName(), keyspace); - } - SchemaRefresh refresh = new SchemaRefresh(keyspacesBuilder.build()); - LOG.debug("[{}] Schema parsing took {}", logPrefix, NanoTime.formatTimeSince(startTimeNs)); - return refresh; - } - - private DseKeyspaceMetadata parseKeyspace(AdminRow keyspaceRow) { - - // Cassandra <= 2.2 - // CREATE TABLE system.schema_keyspaces ( - // keyspace_name text PRIMARY KEY, - // durable_writes boolean, - // strategy_class text, - // strategy_options text - // ) - // - // Cassandra >= 3.0: - // CREATE TABLE system_schema.keyspaces ( - // keyspace_name text PRIMARY KEY, - // durable_writes boolean, - // replication frozen> - // ) - // - // DSE >= 6.8: same as Cassandra 3 + graph_engine text - CqlIdentifier keyspaceId = CqlIdentifier.fromInternal(keyspaceRow.getString("keyspace_name")); - boolean durableWrites = - MoreObjects.firstNonNull(keyspaceRow.getBoolean("durable_writes"), false); - String graphEngine = keyspaceRow.getString("graph_engine"); - - Map replicationOptions; - if (keyspaceRow.contains("strategy_class")) { - String strategyClass = keyspaceRow.getString("strategy_class"); - Map strategyOptions = - SimpleJsonParser.parseStringMap(keyspaceRow.getString("strategy_options")); - replicationOptions = - ImmutableMap.builder() - .putAll(strategyOptions) - .put("class", strategyClass) - .build(); - } else { - replicationOptions = keyspaceRow.getMapOfStringToString("replication"); - } - - Map types = parseTypes(keyspaceId); - - return new DefaultDseKeyspaceMetadata( - keyspaceId, - durableWrites, - false, - graphEngine, - replicationOptions, - types, - parseTables(keyspaceId, types), - parseViews(keyspaceId, types), - parseFunctions(keyspaceId, types), - parseAggregates(keyspaceId, types)); - } - - private Map parseTypes(CqlIdentifier keyspaceId) { - return userDefinedTypeParser.parse(rows.types().get(keyspaceId), keyspaceId); - } - - private Map parseTables( - CqlIdentifier keyspaceId, Map types) { - ImmutableMap.Builder tablesBuilder = ImmutableMap.builder(); - Multimap vertices = rows.vertices().get(keyspaceId); - Multimap edges = rows.edges().get(keyspaceId); - for (AdminRow tableRow : rows.tables().get(keyspaceId)) { - DseTableMetadata table = tableParser.parseTable(tableRow, keyspaceId, types, vertices, edges); - if (table != null) { - tablesBuilder.put(table.getName(), table); - } - } - return tablesBuilder.build(); - } - - private Map parseViews( - CqlIdentifier keyspaceId, Map types) { - ImmutableMap.Builder viewsBuilder = ImmutableMap.builder(); - for (AdminRow viewRow : rows.views().get(keyspaceId)) { - DseViewMetadata view = viewParser.parseView(viewRow, keyspaceId, types); - if (view != null) { - viewsBuilder.put(view.getName(), view); - } - } - return viewsBuilder.build(); - } - - private Map parseFunctions( - CqlIdentifier keyspaceId, Map types) { - ImmutableMap.Builder functionsBuilder = - ImmutableMap.builder(); - for (AdminRow functionRow : rows.functions().get(keyspaceId)) { - DseFunctionMetadata function = functionParser.parseFunction(functionRow, keyspaceId, types); - if (function != null) { - functionsBuilder.put(function.getSignature(), function); - } - } - return functionsBuilder.build(); - } - - private Map parseAggregates( - CqlIdentifier keyspaceId, Map types) { - ImmutableMap.Builder aggregatesBuilder = - ImmutableMap.builder(); - for (AdminRow aggregateRow : rows.aggregates().get(keyspaceId)) { - DseAggregateMetadata aggregate = - aggregateParser.parseAggregate(aggregateRow, keyspaceId, types); - if (aggregate != null) { - aggregatesBuilder.put(aggregate.getSignature(), aggregate); - } - } - return aggregatesBuilder.build(); - } - - private DseKeyspaceMetadata parseVirtualKeyspace(AdminRow keyspaceRow) { - - CqlIdentifier keyspaceId = CqlIdentifier.fromInternal(keyspaceRow.getString("keyspace_name")); - boolean durableWrites = - MoreObjects.firstNonNull(keyspaceRow.getBoolean("durable_writes"), false); - - return new DefaultDseKeyspaceMetadata( - keyspaceId, - durableWrites, - true, - null, - Collections.emptyMap(), - Collections.emptyMap(), - parseVirtualTables(keyspaceId), - Collections.emptyMap(), - Collections.emptyMap(), - Collections.emptyMap()); - } - - private Map parseVirtualTables(CqlIdentifier keyspaceId) { - ImmutableMap.Builder tablesBuilder = ImmutableMap.builder(); - for (AdminRow tableRow : rows.virtualTables().get(keyspaceId)) { - DseTableMetadata table = tableParser.parseVirtualTable(tableRow, keyspaceId); - if (table != null) { - tablesBuilder.put(table.getName(), table); - } - } - return tablesBuilder.build(); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/parsing/DseTableParser.java b/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/parsing/DseTableParser.java deleted file mode 100644 index 7fd4a5f0167..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/parsing/DseTableParser.java +++ /dev/null @@ -1,425 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.metadata.schema.parsing; - -import com.datastax.dse.driver.api.core.metadata.schema.DseColumnMetadata; -import com.datastax.dse.driver.api.core.metadata.schema.DseEdgeMetadata; -import com.datastax.dse.driver.api.core.metadata.schema.DseIndexMetadata; -import com.datastax.dse.driver.api.core.metadata.schema.DseTableMetadata; -import com.datastax.dse.driver.api.core.metadata.schema.DseVertexMetadata; -import com.datastax.dse.driver.internal.core.metadata.schema.DefaultDseColumnMetadata; -import com.datastax.dse.driver.internal.core.metadata.schema.DefaultDseEdgeMetadata; -import com.datastax.dse.driver.internal.core.metadata.schema.DefaultDseIndexMetadata; -import com.datastax.dse.driver.internal.core.metadata.schema.DefaultDseTableMetadata; -import com.datastax.dse.driver.internal.core.metadata.schema.DefaultDseVertexMetadata; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.metadata.schema.ClusteringOrder; -import com.datastax.oss.driver.api.core.metadata.schema.ColumnMetadata; -import com.datastax.oss.driver.api.core.metadata.schema.IndexKind; -import com.datastax.oss.driver.api.core.metadata.schema.IndexMetadata; -import com.datastax.oss.driver.api.core.type.DataType; -import com.datastax.oss.driver.api.core.type.ListType; -import com.datastax.oss.driver.api.core.type.MapType; -import com.datastax.oss.driver.api.core.type.SetType; -import com.datastax.oss.driver.api.core.type.UserDefinedType; -import com.datastax.oss.driver.internal.core.CqlIdentifiers; -import com.datastax.oss.driver.internal.core.adminrequest.AdminRow; -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import com.datastax.oss.driver.internal.core.metadata.schema.parsing.DataTypeClassNameCompositeParser; -import com.datastax.oss.driver.internal.core.metadata.schema.parsing.RawColumn; -import com.datastax.oss.driver.internal.core.metadata.schema.parsing.RelationParser; -import com.datastax.oss.driver.internal.core.metadata.schema.parsing.TableParser; -import com.datastax.oss.driver.internal.core.metadata.schema.queries.SchemaRows; -import com.datastax.oss.driver.internal.core.util.Loggers; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMultimap; -import com.datastax.oss.driver.shaded.guava.common.collect.Multimap; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import net.jcip.annotations.ThreadSafe; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@ThreadSafe -public class DseTableParser extends RelationParser { - - private static final Logger LOG = LoggerFactory.getLogger(TableParser.class); - - public DseTableParser(SchemaRows rows, InternalDriverContext context) { - super(rows, context); - } - - public DseTableMetadata parseTable( - AdminRow tableRow, - CqlIdentifier keyspaceId, - Map userTypes, - Multimap vertices, - Multimap edges) { - // Cassandra <= 2.2: - // CREATE TABLE system.schema_columnfamilies ( - // keyspace_name text, - // columnfamily_name text, - // bloom_filter_fp_chance double, - // caching text, - // cf_id uuid, - // column_aliases text, (2.1 only) - // comment text, - // compaction_strategy_class text, - // compaction_strategy_options text, - // comparator text, - // compression_parameters text, - // default_time_to_live int, - // default_validator text, - // dropped_columns map, - // gc_grace_seconds int, - // index_interval int, - // is_dense boolean, (2.1 only) - // key_aliases text, (2.1 only) - // key_validator text, - // local_read_repair_chance double, - // max_compaction_threshold int, - // max_index_interval int, - // memtable_flush_period_in_ms int, - // min_compaction_threshold int, - // min_index_interval int, - // read_repair_chance double, - // speculative_retry text, - // subcomparator text, - // type text, - // value_alias text, (2.1 only) - // PRIMARY KEY (keyspace_name, columnfamily_name) - // ) WITH CLUSTERING ORDER BY (columnfamily_name ASC) - // - // Cassandra 3.0: - // CREATE TABLE system_schema.tables ( - // keyspace_name text, - // table_name text, - // bloom_filter_fp_chance double, - // caching frozen>, - // cdc boolean, - // comment text, - // compaction frozen>, - // compression frozen>, - // crc_check_chance double, - // dclocal_read_repair_chance double, - // default_time_to_live int, - // extensions frozen>, - // flags frozen>, - // gc_grace_seconds int, - // id uuid, - // max_index_interval int, - // memtable_flush_period_in_ms int, - // min_index_interval int, - // read_repair_chance double, - // speculative_retry text, - // PRIMARY KEY (keyspace_name, table_name) - // ) WITH CLUSTERING ORDER BY (table_name ASC) - CqlIdentifier tableId = - CqlIdentifier.fromInternal( - tableRow.getString( - tableRow.contains("table_name") ? "table_name" : "columnfamily_name")); - - UUID uuid = tableRow.contains("id") ? tableRow.getUuid("id") : tableRow.getUuid("cf_id"); - - List rawColumns = - RawColumn.toRawColumns( - rows.columns().getOrDefault(keyspaceId, ImmutableMultimap.of()).get(tableId)); - if (rawColumns.isEmpty()) { - LOG.warn( - "[{}] Processing TABLE refresh for {}.{} but found no matching rows, skipping", - logPrefix, - keyspaceId, - tableId); - return null; - } - - boolean isCompactStorage; - if (tableRow.contains("flags")) { - Set flags = tableRow.getSetOfString("flags"); - boolean isDense = flags.contains("dense"); - boolean isSuper = flags.contains("super"); - boolean isCompound = flags.contains("compound"); - isCompactStorage = isSuper || isDense || !isCompound; - boolean isStaticCompact = !isSuper && !isDense && !isCompound; - if (isStaticCompact) { - RawColumn.pruneStaticCompactTableColumns(rawColumns); - } else if (isDense) { - RawColumn.pruneDenseTableColumnsV3(rawColumns); - } - } else { - boolean isDense = tableRow.getBoolean("is_dense"); - if (isDense) { - RawColumn.pruneDenseTableColumnsV2(rawColumns); - } - DataTypeClassNameCompositeParser.ParseResult comparator = - new DataTypeClassNameCompositeParser() - .parseWithComposite(tableRow.getString("comparator"), keyspaceId, userTypes, context); - isCompactStorage = isDense || !comparator.isComposite; - } - - Collections.sort(rawColumns); - ImmutableMap.Builder allColumnsBuilder = ImmutableMap.builder(); - ImmutableList.Builder partitionKeyBuilder = ImmutableList.builder(); - ImmutableMap.Builder clusteringColumnsBuilder = - ImmutableMap.builder(); - ImmutableMap.Builder indexesBuilder = ImmutableMap.builder(); - - for (RawColumn raw : rawColumns) { - DataType dataType = rows.dataTypeParser().parse(keyspaceId, raw.dataType, userTypes, context); - DseColumnMetadata column = - new DefaultDseColumnMetadata( - keyspaceId, tableId, raw.name, dataType, raw.kind.equals(RawColumn.KIND_STATIC)); - switch (raw.kind) { - case RawColumn.KIND_PARTITION_KEY: - partitionKeyBuilder.add(column); - break; - case RawColumn.KIND_CLUSTERING_COLUMN: - clusteringColumnsBuilder.put( - column, raw.reversed ? ClusteringOrder.DESC : ClusteringOrder.ASC); - break; - default: - // nothing to do - } - allColumnsBuilder.put(column.getName(), column); - - DseIndexMetadata index = buildLegacyIndex(raw, column); - if (index != null) { - indexesBuilder.put(index.getName(), index); - } - } - - Map options; - try { - options = parseOptions(tableRow); - } catch (Exception e) { - // Options change the most often, so be especially lenient if anything goes wrong. - Loggers.warnWithException( - LOG, - "[{}] Error while parsing options for {}.{}, getOptions() will be empty", - logPrefix, - keyspaceId, - tableId, - e); - options = Collections.emptyMap(); - } - - Collection indexRows = - rows.indexes().getOrDefault(keyspaceId, ImmutableMultimap.of()).get(tableId); - for (AdminRow indexRow : indexRows) { - DseIndexMetadata index = buildModernIndex(keyspaceId, tableId, indexRow); - indexesBuilder.put(index.getName(), index); - } - - return new DefaultDseTableMetadata( - keyspaceId, - tableId, - uuid, - isCompactStorage, - false, - partitionKeyBuilder.build(), - clusteringColumnsBuilder.build(), - allColumnsBuilder.build(), - options, - indexesBuilder.build(), - buildVertex(tableId, vertices), - buildEdge(tableId, edges, vertices)); - } - - DseTableMetadata parseVirtualTable(AdminRow tableRow, CqlIdentifier keyspaceId) { - - CqlIdentifier tableId = CqlIdentifier.fromInternal(tableRow.getString("table_name")); - - List rawColumns = - RawColumn.toRawColumns( - rows.virtualColumns().getOrDefault(keyspaceId, ImmutableMultimap.of()).get(tableId)); - if (rawColumns.isEmpty()) { - LOG.warn( - "[{}] Processing TABLE refresh for {}.{} but found no matching rows, skipping", - logPrefix, - keyspaceId, - tableId); - return null; - } - - Collections.sort(rawColumns); - ImmutableMap.Builder allColumnsBuilder = ImmutableMap.builder(); - ImmutableList.Builder partitionKeyBuilder = ImmutableList.builder(); - ImmutableMap.Builder clusteringColumnsBuilder = - ImmutableMap.builder(); - - for (RawColumn raw : rawColumns) { - DataType dataType = - rows.dataTypeParser().parse(keyspaceId, raw.dataType, Collections.emptyMap(), context); - DseColumnMetadata column = - new DefaultDseColumnMetadata( - keyspaceId, tableId, raw.name, dataType, raw.kind.equals(RawColumn.KIND_STATIC)); - switch (raw.kind) { - case RawColumn.KIND_PARTITION_KEY: - partitionKeyBuilder.add(column); - break; - case RawColumn.KIND_CLUSTERING_COLUMN: - clusteringColumnsBuilder.put( - column, raw.reversed ? ClusteringOrder.DESC : ClusteringOrder.ASC); - break; - default: - } - - allColumnsBuilder.put(column.getName(), column); - } - - return new DefaultDseTableMetadata( - keyspaceId, - tableId, - null, - false, - true, - partitionKeyBuilder.build(), - clusteringColumnsBuilder.build(), - allColumnsBuilder.build(), - Collections.emptyMap(), - Collections.emptyMap(), - null, - null); - } - - // In C*<=2.2, index information is stored alongside the column. - private DseIndexMetadata buildLegacyIndex(RawColumn raw, ColumnMetadata column) { - if (raw.indexName == null) { - return null; - } - return new DefaultDseIndexMetadata( - column.getKeyspace(), - column.getParent(), - CqlIdentifier.fromInternal(raw.indexName), - IndexKind.valueOf(raw.indexType), - buildLegacyIndexTarget(column, raw.indexOptions), - raw.indexOptions); - } - - private static String buildLegacyIndexTarget(ColumnMetadata column, Map options) { - String columnName = column.getName().asCql(true); - DataType columnType = column.getType(); - if (options.containsKey("index_keys")) { - return String.format("keys(%s)", columnName); - } - if (options.containsKey("index_keys_and_values")) { - return String.format("entries(%s)", columnName); - } - if ((columnType instanceof ListType && ((ListType) columnType).isFrozen()) - || (columnType instanceof SetType && ((SetType) columnType).isFrozen()) - || (columnType instanceof MapType && ((MapType) columnType).isFrozen())) { - return String.format("full(%s)", columnName); - } - // Note: the keyword 'values' is not accepted as a valid index target function until 3.0 - return columnName; - } - - // In C*>=3.0, index information is stored in a dedicated table: - // CREATE TABLE system_schema.indexes ( - // keyspace_name text, - // table_name text, - // index_name text, - // kind text, - // options frozen>, - // PRIMARY KEY (keyspace_name, table_name, index_name) - // ) WITH CLUSTERING ORDER BY (table_name ASC, index_name ASC) - private DseIndexMetadata buildModernIndex( - CqlIdentifier keyspaceId, CqlIdentifier tableId, AdminRow row) { - CqlIdentifier name = CqlIdentifier.fromInternal(row.getString("index_name")); - IndexKind kind = IndexKind.valueOf(row.getString("kind")); - Map options = row.getMapOfStringToString("options"); - String target = options.get("target"); - return new DefaultDseIndexMetadata(keyspaceId, tableId, name, kind, target, options); - } - - private DseVertexMetadata buildVertex( - CqlIdentifier tableId, Multimap keyspaceVertices) { - - if (keyspaceVertices == null) { - return null; - } - Collection tableVertices = keyspaceVertices.get(tableId); - if (tableVertices == null || tableVertices.isEmpty()) { - return null; - } - - AdminRow row = tableVertices.iterator().next(); - return new DefaultDseVertexMetadata(getLabel(row)); - } - - private DseEdgeMetadata buildEdge( - CqlIdentifier tableId, - Multimap keyspaceEdges, - Multimap keyspaceVertices) { - - if (keyspaceEdges == null) { - return null; - } - - Collection tableEdges = keyspaceEdges.get(tableId); - if (tableEdges == null || tableEdges.isEmpty()) { - return null; - } - - AdminRow row = tableEdges.iterator().next(); - - CqlIdentifier fromTable = CqlIdentifier.fromInternal(row.getString("from_table")); - - CqlIdentifier toTable = CqlIdentifier.fromInternal(row.getString("to_table")); - - return new DefaultDseEdgeMetadata( - getLabel(row), - fromTable, - findVertexLabel(fromTable, keyspaceVertices, "incoming"), - CqlIdentifiers.wrapInternal(row.getListOfString("from_partition_key_columns")), - CqlIdentifiers.wrapInternal(row.getListOfString("from_clustering_columns")), - toTable, - findVertexLabel(toTable, keyspaceVertices, "outgoing"), - CqlIdentifiers.wrapInternal(row.getListOfString("to_partition_key_columns")), - CqlIdentifiers.wrapInternal(row.getListOfString("to_clustering_columns"))); - } - - private CqlIdentifier getLabel(AdminRow row) { - String rawLabel = row.getString("label_name"); - return (rawLabel == null || rawLabel.isEmpty()) ? null : CqlIdentifier.fromInternal(rawLabel); - } - - // system_schema.edges only contains vertex table names. We also expose the labels in our metadata - // objects, so we need to look them up in system_schema.vertices. - private CqlIdentifier findVertexLabel( - CqlIdentifier table, - Multimap keyspaceVertices, - String directionForErrorMessage) { - Collection tableVertices = - (keyspaceVertices == null) ? null : keyspaceVertices.get(table); - if (tableVertices == null || tableVertices.isEmpty()) { - throw new IllegalArgumentException( - String.format( - "Missing vertex definition for %s table %s", - directionForErrorMessage, table.asCql(true))); - } - - AdminRow row = tableVertices.iterator().next(); - return getLabel(row); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/parsing/DseViewParser.java b/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/parsing/DseViewParser.java deleted file mode 100644 index 07a1e2b5c39..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/metadata/schema/parsing/DseViewParser.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.metadata.schema.parsing; - -import com.datastax.dse.driver.api.core.metadata.schema.DseColumnMetadata; -import com.datastax.dse.driver.api.core.metadata.schema.DseViewMetadata; -import com.datastax.dse.driver.internal.core.metadata.schema.DefaultDseColumnMetadata; -import com.datastax.dse.driver.internal.core.metadata.schema.DefaultDseViewMetadata; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.metadata.schema.ClusteringOrder; -import com.datastax.oss.driver.api.core.metadata.schema.ColumnMetadata; -import com.datastax.oss.driver.api.core.type.DataType; -import com.datastax.oss.driver.api.core.type.UserDefinedType; -import com.datastax.oss.driver.internal.core.adminrequest.AdminRow; -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import com.datastax.oss.driver.internal.core.metadata.schema.parsing.RawColumn; -import com.datastax.oss.driver.internal.core.metadata.schema.parsing.RelationParser; -import com.datastax.oss.driver.internal.core.metadata.schema.queries.SchemaRows; -import com.datastax.oss.driver.internal.core.util.Loggers; -import com.datastax.oss.driver.shaded.guava.common.base.MoreObjects; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMultimap; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import net.jcip.annotations.ThreadSafe; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@ThreadSafe -public class DseViewParser extends RelationParser { - - private static final Logger LOG = LoggerFactory.getLogger(DseViewParser.class); - - public DseViewParser(SchemaRows rows, InternalDriverContext context) { - super(rows, context); - } - - public DseViewMetadata parseView( - AdminRow viewRow, CqlIdentifier keyspaceId, Map userTypes) { - // Cassandra 3.0 (no views in earlier versions): - // CREATE TABLE system_schema.views ( - // keyspace_name text, - // view_name text, - // base_table_id uuid, - // base_table_name text, - // bloom_filter_fp_chance double, - // caching frozen>, - // cdc boolean, - // comment text, - // compaction frozen>, - // compression frozen>, - // crc_check_chance double, - // dclocal_read_repair_chance double, - // default_time_to_live int, - // extensions frozen>, - // gc_grace_seconds int, - // id uuid, - // include_all_columns boolean, - // max_index_interval int, - // memtable_flush_period_in_ms int, - // min_index_interval int, - // read_repair_chance double, - // speculative_retry text, - // where_clause text, - // PRIMARY KEY (keyspace_name, view_name) - // ) WITH CLUSTERING ORDER BY (view_name ASC) - CqlIdentifier viewId = CqlIdentifier.fromInternal(viewRow.getString("view_name")); - - UUID uuid = viewRow.getUuid("id"); - CqlIdentifier baseTableId = CqlIdentifier.fromInternal(viewRow.getString("base_table_name")); - boolean includesAllColumns = - MoreObjects.firstNonNull(viewRow.getBoolean("include_all_columns"), false); - String whereClause = viewRow.getString("where_clause"); - - List rawColumns = - RawColumn.toRawColumns( - rows.columns().getOrDefault(keyspaceId, ImmutableMultimap.of()).get(viewId)); - if (rawColumns.isEmpty()) { - LOG.warn( - "[{}] Processing VIEW refresh for {}.{} but found no matching rows, skipping", - logPrefix, - keyspaceId, - viewId); - return null; - } - - Collections.sort(rawColumns); - ImmutableMap.Builder allColumnsBuilder = ImmutableMap.builder(); - ImmutableList.Builder partitionKeyBuilder = ImmutableList.builder(); - ImmutableMap.Builder clusteringColumnsBuilder = - ImmutableMap.builder(); - - for (RawColumn raw : rawColumns) { - DataType dataType = rows.dataTypeParser().parse(keyspaceId, raw.dataType, userTypes, context); - DseColumnMetadata column = - new DefaultDseColumnMetadata( - keyspaceId, viewId, raw.name, dataType, raw.kind.equals(RawColumn.KIND_STATIC)); - switch (raw.kind) { - case RawColumn.KIND_PARTITION_KEY: - partitionKeyBuilder.add(column); - break; - case RawColumn.KIND_CLUSTERING_COLUMN: - clusteringColumnsBuilder.put( - column, raw.reversed ? ClusteringOrder.DESC : ClusteringOrder.ASC); - break; - default: - // nothing to do - } - allColumnsBuilder.put(column.getName(), column); - } - - Map options; - try { - options = parseOptions(viewRow); - } catch (Exception e) { - // Options change the most often, so be especially lenient if anything goes wrong. - Loggers.warnWithException( - LOG, - "[{}] Error while parsing options for {}.{}, getOptions() will be empty", - logPrefix, - keyspaceId, - viewId, - e); - options = Collections.emptyMap(); - } - - return new DefaultDseViewMetadata( - keyspaceId, - viewId, - baseTableId, - includesAllColumns, - whereClause, - uuid, - partitionKeyBuilder.build(), - clusteringColumnsBuilder.build(), - allColumnsBuilder.build(), - options); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/protocol/TinkerpopBufferPrimitiveCodec.java b/core/src/main/java/com/datastax/dse/driver/internal/core/protocol/TinkerpopBufferPrimitiveCodec.java deleted file mode 100644 index 13238519e06..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/protocol/TinkerpopBufferPrimitiveCodec.java +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.protocol; - -import com.datastax.dse.driver.internal.core.graph.binary.buffer.DseNettyBufferFactory; -import com.datastax.oss.driver.internal.core.protocol.ByteBufPrimitiveCodec; -import com.datastax.oss.driver.shaded.guava.common.base.Charsets; -import com.datastax.oss.protocol.internal.PrimitiveCodec; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.zip.CRC32; -import org.apache.tinkerpop.gremlin.structure.io.Buffer; - -/** - * Minimal implementation of {@link PrimitiveCodec} for Tinkerpop {@link Buffer} instances. - * - *

This approach represents a temporary design compromise. PrimitiveCodec is primarily used for - * handling data directly from Netty, a task satisfied by {@link ByteBufPrimitiveCodec}. But - * PrimitiveCodec is also used to implement graph serialization for some of the "dynamic" types - * (notably UDTs and tuples). Since we're converting graph serialization to use the new Tinkerpop - * Buffer API we need just enough of a PrimitiveCodec impl to satisfy the needs of graph - * serialization... and nothing more. - * - *

A more explicit approach would be to change graph serialization to use a different interface, - * some kind of subset of PrimitiveCodec.... and then make PrimitiveCodec extend this interface. - * This is left as future work for now since it involves changes to the native-protocol lib(s). - */ -public class TinkerpopBufferPrimitiveCodec implements PrimitiveCodec { - - private final DseNettyBufferFactory factory; - - public TinkerpopBufferPrimitiveCodec(DseNettyBufferFactory factory) { - this.factory = factory; - } - - @Override - public Buffer allocate(int size) { - // Note: we use io() here to match up to what ByteBufPrimitiveCodec does, but be warned that - // ByteBufs created in this way don't support the array() method used elsewhere in this codec - // (readString() specifically). As such usage of this method to create Buffer instances is - // discouraged; we have a factory for that. - return this.factory.io(size, size); - } - - @Override - public void release(Buffer toRelease) { - toRelease.release(); - } - - @Override - public int sizeOf(Buffer toMeasure) { - return toMeasure.readableBytes(); - } - - // TODO - @Override - public Buffer concat(Buffer left, Buffer right) { - boolean leftReadable = left.readableBytes() > 0; - boolean rightReadable = right.readableBytes() > 0; - if (!(leftReadable || rightReadable)) { - return factory.heap(); - } - if (!leftReadable) { - return right; - } - if (!rightReadable) { - return left; - } - Buffer rv = factory.composite(left, right); - // c.readerIndex() is 0, which is the first readable byte in left - rv.writerIndex( - left.writerIndex() - left.readerIndex() + right.writerIndex() - right.readerIndex()); - return rv; - } - - @Override - public void markReaderIndex(Buffer source) { - throw new UnsupportedOperationException(); - } - - @Override - public void resetReaderIndex(Buffer source) { - throw new UnsupportedOperationException(); - } - - @Override - public byte readByte(Buffer source) { - return source.readByte(); - } - - @Override - public int readInt(Buffer source) { - return source.readInt(); - } - - @Override - public int readInt(Buffer source, int offset) { - throw new UnsupportedOperationException(); - } - - @Override - public InetAddress readInetAddr(Buffer source) { - int length = readByte(source) & 0xFF; - byte[] bytes = new byte[length]; - source.readBytes(bytes); - return newInetAddress(bytes); - } - - @Override - public long readLong(Buffer source) { - return source.readLong(); - } - - @Override - public int readUnsignedShort(Buffer source) { - return source.readShort() & 0xFFFF; - } - - @Override - public ByteBuffer readBytes(Buffer source) { - int length = readInt(source); - if (length < 0) return null; - return source.nioBuffer(source.readerIndex(), length); - } - - @Override - public byte[] readShortBytes(Buffer source) { - try { - int length = readUnsignedShort(source); - byte[] bytes = new byte[length]; - source.readBytes(bytes); - return bytes; - } catch (IndexOutOfBoundsException e) { - throw new IllegalArgumentException( - "Not enough bytes to read a byte array preceded by its 2 bytes length"); - } - } - - // Copy of PrimitiveCodec impl - @Override - public String readString(Buffer source) { - int length = readUnsignedShort(source); - return readString(source, length); - } - - @Override - public String readLongString(Buffer source) { - int length = readInt(source); - return readString(source, length); - } - - @Override - public Buffer readRetainedSlice(Buffer source, int sliceLength) { - throw new UnsupportedOperationException(); - } - - @Override - public void updateCrc(Buffer source, CRC32 crc) { - throw new UnsupportedOperationException(); - } - - @Override - public void writeByte(byte b, Buffer dest) { - dest.writeByte(b); - } - - @Override - public void writeInt(int i, Buffer dest) { - dest.writeInt(i); - } - - @Override - public void writeInetAddr(InetAddress address, Buffer dest) { - byte[] bytes = address.getAddress(); - writeByte((byte) bytes.length, dest); - dest.writeBytes(bytes); - } - - @Override - public void writeLong(long l, Buffer dest) { - dest.writeLong(l); - } - - @Override - public void writeUnsignedShort(int i, Buffer dest) { - dest.writeShort(i); - } - - // Copy of PrimitiveCodec impl - @Override - public void writeString(String s, Buffer dest) { - - byte[] bytes = s.getBytes(Charsets.UTF_8); - writeUnsignedShort(bytes.length, dest); - dest.writeBytes(bytes); - } - - @Override - public void writeLongString(String s, Buffer dest) { - byte[] bytes = s.getBytes(Charsets.UTF_8); - writeInt(bytes.length, dest); - dest.writeBytes(bytes); - } - - @Override - public void writeBytes(ByteBuffer bytes, Buffer dest) { - if (bytes == null) { - writeInt(-1, dest); - } else { - writeInt(bytes.remaining(), dest); - dest.writeBytes(bytes.duplicate()); - } - } - - @Override - public void writeBytes(byte[] bytes, Buffer dest) { - if (bytes == null) { - writeInt(-1, dest); - } else { - writeInt(bytes.length, dest); - dest.writeBytes(bytes); - } - } - - @Override - public void writeShortBytes(byte[] bytes, Buffer dest) { - writeUnsignedShort(bytes.length, dest); - dest.writeBytes(bytes); - } - - // Based on PrimitiveCodec impl, although that method leverages some - // Netty built-ins which we have to do manually here - private static String readString(Buffer buff, int length) { - try { - - // Basically what io.netty.buffer.ByteBufUtil.decodeString() does minus some extra - // ByteBuf-specific ops - int offset; - byte[] bytes; - ByteBuffer byteBuff = buff.nioBuffer(); - if (byteBuff.hasArray()) { - - bytes = byteBuff.array(); - offset = byteBuff.arrayOffset(); - } else { - - bytes = new byte[length]; - byteBuff.get(bytes, 0, length); - offset = 0; - } - - String str = new String(bytes, offset, length, Charsets.UTF_8); - - // Ops against the NIO buffers don't impact the read/write indexes for he Buffer - // itself so we have to do that manually - buff.readerIndex(buff.readerIndex() + length); - return str; - } catch (IndexOutOfBoundsException e) { - throw new IllegalArgumentException( - "Not enough bytes to read an UTF-8 serialized string of size " + length, e); - } - } - - // TODO: Code below copied directly from ByteBufPrimitiveCodec, probably want to consolidate this - // somewhere - private static InetAddress newInetAddress(byte[] bytes) { - try { - return InetAddress.getByAddress(bytes); - } catch (UnknownHostException e) { - // Per the Javadoc, the only way this can happen is if the length is illegal - throw new IllegalArgumentException( - String.format("Invalid address length: %d (%s)", bytes.length, Arrays.toString(bytes))); - } - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/search/DateRangeUtil.java b/core/src/main/java/com/datastax/dse/driver/internal/core/search/DateRangeUtil.java deleted file mode 100644 index 15e278260c5..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/search/DateRangeUtil.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.search; - -import com.datastax.dse.driver.api.core.data.time.DateRangePrecision; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.text.ParseException; -import java.time.LocalDateTime; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; -import java.time.temporal.ChronoField; -import java.time.temporal.ChronoUnit; -import java.time.temporal.TemporalAdjusters; -import java.util.Calendar; -import java.util.Locale; -import java.util.Map; -import java.util.TimeZone; - -public class DateRangeUtil { - - /** Sets all the fields smaller than the given unit to their lowest possible value. */ - @NonNull - public static ZonedDateTime roundDown(@NonNull ZonedDateTime date, @NonNull ChronoUnit unit) { - switch (unit) { - case YEARS: - return date.with(TemporalAdjusters.firstDayOfYear()).truncatedTo(ChronoUnit.DAYS); - case MONTHS: - return date.with(TemporalAdjusters.firstDayOfMonth()).truncatedTo(ChronoUnit.DAYS); - case DAYS: - case HOURS: - case MINUTES: - case SECONDS: - case MILLIS: - return date.truncatedTo(unit); - default: - throw new IllegalArgumentException("Unsupported unit for rounding: " + unit); - } - } - - /** Sets all the fields smaller than the given unit to their highest possible value. */ - @NonNull - public static ZonedDateTime roundUp(@NonNull ZonedDateTime date, @NonNull ChronoUnit unit) { - return roundDown(date, unit) - .plus(1, unit) - // Even though ZDT has nanosecond-precision, DSE only rounds to millisecond precision so be - // consistent with that - .minus(1, ChronoUnit.MILLIS); - } - - /** - * Parses the given string as a date in a range bound. - * - *

This method deliberately uses legacy time APIs, in order to be as close as possible to the - * server-side parsing logic. We want the client to behave exactly like the server, i.e. parsing a - * date locally and inlining it in a CQL query should always yield the same result as binding the - * date as a value. - */ - public static Calendar parseCalendar(String source) throws ParseException { - // The contents of this method are based on Lucene's DateRangePrefixTree#parseCalendar, released - // under the Apache License, Version 2.0. - // Following is the original notice from that file: - - // Licensed to the Apache Software Foundation (ASF) under one or more - // contributor license agreements. See the NOTICE file distributed with - // this work for additional information regarding copyright ownership. - // The ASF licenses this file to You under the Apache License, Version 2.0 - // (the "License"); you may not use this file except in compliance with - // the License. You may obtain a copy of the License at - // - // http://www.apache.org/licenses/LICENSE-2.0 - // - // Unless required by applicable law or agreed to in writing, software - // distributed under the License is distributed on an "AS IS" BASIS, - // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - // See the License for the specific language governing permissions and - // limitations under the License. - - if (source == null || source.isEmpty()) { - throw new IllegalArgumentException("Can't parse a null or blank string"); - } - - Calendar calendar = newCalendar(); - if (source.equals("*")) { - return calendar; - } - int offset = 0; // a pointer - try { - // year & era: - int lastOffset = - (source.charAt(source.length() - 1) == 'Z') ? source.length() - 1 : source.length(); - int hyphenIdx = source.indexOf('-', 1); // look past possible leading hyphen - if (hyphenIdx < 0) { - hyphenIdx = lastOffset; - } - int year = Integer.parseInt(source.substring(offset, hyphenIdx)); - calendar.set(Calendar.ERA, year <= 0 ? 0 : 1); - calendar.set(Calendar.YEAR, year <= 0 ? -1 * year + 1 : year); - offset = hyphenIdx + 1; - if (lastOffset < offset) { - return calendar; - } - - // NOTE: We aren't validating separator chars, and we unintentionally accept leading +/-. - // The str.substring()'s hopefully get optimized to be stack-allocated. - - // month: - calendar.set( - Calendar.MONTH, - Integer.parseInt(source.substring(offset, offset + 2)) - 1); // starts at 0 - offset += 3; - if (lastOffset < offset) { - return calendar; - } - // day: - calendar.set(Calendar.DAY_OF_MONTH, Integer.parseInt(source.substring(offset, offset + 2))); - offset += 3; - if (lastOffset < offset) { - return calendar; - } - // hour: - calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(source.substring(offset, offset + 2))); - offset += 3; - if (lastOffset < offset) { - return calendar; - } - // minute: - calendar.set(Calendar.MINUTE, Integer.parseInt(source.substring(offset, offset + 2))); - offset += 3; - if (lastOffset < offset) { - return calendar; - } - // second: - calendar.set(Calendar.SECOND, Integer.parseInt(source.substring(offset, offset + 2))); - offset += 3; - if (lastOffset < offset) { - return calendar; - } - // ms: - calendar.set(Calendar.MILLISECOND, Integer.parseInt(source.substring(offset, offset + 3))); - offset += 3; // last one, move to next char - if (lastOffset == offset) { - return calendar; - } - } catch (Exception e) { - ParseException pe = new ParseException("Improperly formatted date: " + source, offset); - pe.initCause(e); - throw pe; - } - throw new ParseException("Improperly formatted date: " + source, offset); - } - - private static Calendar newCalendar() { - Calendar calendar = Calendar.getInstance(UTC, Locale.ROOT); - calendar.clear(); - return calendar; - } - - private static final TimeZone UTC = TimeZone.getTimeZone("UTC"); - - /** - * Returns the precision of a calendar obtained through {@link #parseCalendar(String)}, or {@code - * null} if no field was set. - */ - @Nullable - public static DateRangePrecision getPrecision(Calendar calendar) { - DateRangePrecision lastPrecision = null; - for (Map.Entry entry : FIELD_BY_PRECISION.entrySet()) { - DateRangePrecision precision = entry.getKey(); - int field = entry.getValue(); - if (calendar.isSet(field)) { - lastPrecision = precision; - } else { - break; - } - } - return lastPrecision; - } - - // Note: this could be a field on DateRangePrecision, but it's only used within this class so it's - // better not to expose it. - private static final ImmutableMap FIELD_BY_PRECISION = - ImmutableMap.builder() - .put(DateRangePrecision.YEAR, Calendar.YEAR) - .put(DateRangePrecision.MONTH, Calendar.MONTH) - .put(DateRangePrecision.DAY, Calendar.DAY_OF_MONTH) - .put(DateRangePrecision.HOUR, Calendar.HOUR_OF_DAY) - .put(DateRangePrecision.MINUTE, Calendar.MINUTE) - .put(DateRangePrecision.SECOND, Calendar.SECOND) - .put(DateRangePrecision.MILLISECOND, Calendar.MILLISECOND) - .build(); - - public static ZonedDateTime toZonedDateTime(Calendar calendar) { - int year = calendar.get(Calendar.YEAR); - if (calendar.get(Calendar.ERA) == 0) { - // BC era; 1 BC == 0 AD, 0 BD == -1 AD, etc - year -= 1; - if (year > 0) { - year = -year; - } - } - LocalDateTime localDateTime = - LocalDateTime.of( - year, - calendar.get(Calendar.MONTH) + 1, - calendar.get(Calendar.DAY_OF_MONTH), - calendar.get(Calendar.HOUR_OF_DAY), - calendar.get(Calendar.MINUTE), - calendar.get(Calendar.SECOND)); - localDateTime = - localDateTime.with(ChronoField.MILLI_OF_SECOND, calendar.get(Calendar.MILLISECOND)); - return ZonedDateTime.of(localDateTime, ZoneOffset.UTC); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/session/DefaultDseSession.java b/core/src/main/java/com/datastax/dse/driver/internal/core/session/DefaultDseSession.java deleted file mode 100644 index 183f385aa4a..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/session/DefaultDseSession.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.session; - -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.session.Session; -import com.datastax.oss.driver.internal.core.session.DefaultSession; -import com.datastax.oss.driver.internal.core.session.SessionWrapper; -import net.jcip.annotations.ThreadSafe; - -/** - * @deprecated DSE functionality is now exposed directly on {@link CqlSession}. This class is - * preserved for backward compatibility, but {@link DefaultSession} should be used instead. - */ -@ThreadSafe -@Deprecated -public class DefaultDseSession extends SessionWrapper - implements com.datastax.dse.driver.api.core.DseSession { - - public DefaultDseSession(Session delegate) { - super(delegate); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/type/codec/DseTypeCodecsRegistrar.java b/core/src/main/java/com/datastax/dse/driver/internal/core/type/codec/DseTypeCodecsRegistrar.java deleted file mode 100644 index 55da2a9475f..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/type/codec/DseTypeCodecsRegistrar.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.type.codec; - -import static com.datastax.oss.driver.internal.core.util.Dependency.ESRI; - -import com.datastax.dse.driver.api.core.type.codec.DseTypeCodecs; -import com.datastax.oss.driver.api.core.type.codec.registry.MutableCodecRegistry; -import com.datastax.oss.driver.internal.core.util.DefaultDependencyChecker; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DseTypeCodecsRegistrar { - - private static final Logger LOG = LoggerFactory.getLogger(DseTypeCodecsRegistrar.class); - - public static void registerDseCodecs(MutableCodecRegistry registry) { - registry.register(DseTypeCodecs.DATE_RANGE); - if (DefaultDependencyChecker.isPresent(ESRI)) { - registry.register(DseTypeCodecs.LINE_STRING, DseTypeCodecs.POINT, DseTypeCodecs.POLYGON); - } else { - LOG.debug("ESRI was not found on the classpath: geo codecs will not be available"); - } - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/type/codec/DseTypeCodecsRegistrarSubstitutions.java b/core/src/main/java/com/datastax/dse/driver/internal/core/type/codec/DseTypeCodecsRegistrarSubstitutions.java deleted file mode 100644 index afd8d6cf9f6..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/type/codec/DseTypeCodecsRegistrarSubstitutions.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.type.codec; - -import static com.datastax.oss.driver.internal.core.util.Dependency.ESRI; - -import com.datastax.dse.driver.api.core.type.codec.DseTypeCodecs; -import com.datastax.oss.driver.api.core.type.codec.registry.MutableCodecRegistry; -import com.datastax.oss.driver.internal.core.util.GraalDependencyChecker; -import com.oracle.svm.core.annotate.Substitute; -import com.oracle.svm.core.annotate.TargetClass; -import java.util.function.BooleanSupplier; - -@SuppressWarnings("unused") -public class DseTypeCodecsRegistrarSubstitutions { - - @TargetClass(value = DseTypeCodecsRegistrar.class, onlyWith = EsriMissing.class) - public static final class DseTypeCodecsRegistrarEsriMissing { - - @Substitute - public static void registerDseCodecs(MutableCodecRegistry registry) { - registry.register(DseTypeCodecs.DATE_RANGE); - } - } - - public static class EsriMissing implements BooleanSupplier { - @Override - public boolean getAsBoolean() { - return !GraalDependencyChecker.isPresent(ESRI); - } - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/type/codec/geometry/GeometryCodec.java b/core/src/main/java/com/datastax/dse/driver/internal/core/type/codec/geometry/GeometryCodec.java deleted file mode 100644 index f6309bc1860..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/type/codec/geometry/GeometryCodec.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.type.codec.geometry; - -import static com.datastax.oss.driver.internal.core.util.Strings.isQuoted; - -import com.datastax.dse.driver.api.core.data.geometry.Geometry; -import com.datastax.oss.driver.api.core.ProtocolVersion; -import com.datastax.oss.driver.api.core.type.codec.TypeCodec; -import com.datastax.oss.driver.internal.core.util.Strings; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.nio.ByteBuffer; -import net.jcip.annotations.ThreadSafe; - -/** Base class for geospatial type codecs. */ -@ThreadSafe -public abstract class GeometryCodec implements TypeCodec { - - @Nullable - @Override - public T decode(@Nullable ByteBuffer bb, @NonNull ProtocolVersion protocolVersion) { - return bb == null || bb.remaining() == 0 ? null : fromWellKnownBinary(bb.slice()); - } - - @Nullable - @Override - public ByteBuffer encode(@Nullable T geometry, @NonNull ProtocolVersion protocolVersion) { - return geometry == null ? null : toWellKnownBinary(geometry); - } - - @Nullable - @Override - public T parse(@Nullable String s) { - if (s == null) { - return null; - } - s = s.trim(); - if (s.isEmpty() || s.equalsIgnoreCase("NULL")) { - return null; - } - if (!isQuoted(s)) { - throw new IllegalArgumentException("Geometry values must be enclosed by single quotes"); - } - return fromWellKnownText(Strings.unquote(s)); - } - - @NonNull - @Override - public String format(@Nullable T geometry) throws IllegalArgumentException { - return geometry == null ? "NULL" : Strings.quote(toWellKnownText(geometry)); - } - - /** - * Creates an instance of this codec's geospatial type from its Well-known Text (WKT) representation. - * - * @param source the Well-known Text representation to parse. Cannot be null. - * @return A new instance of this codec's geospatial type. - * @throws IllegalArgumentException if the string does not contain a valid Well-known Text - * representation. - */ - @NonNull - protected abstract T fromWellKnownText(@NonNull String source); - - /** - * Creates an instance of a geospatial type from its Well-known Binary - * (WKB) representation. - * - * @param bb the Well-known Binary representation to parse. Cannot be null. - * @return A new instance of this codec's geospatial type. - * @throws IllegalArgumentException if the given {@link ByteBuffer} does not contain a valid - * Well-known Binary representation. - */ - @NonNull - protected abstract T fromWellKnownBinary(@NonNull ByteBuffer bb); - - /** - * Returns a Well-known Text (WKT) - * representation of the given geospatial object. - * - * @param geometry the geospatial object to convert. Cannot be null. - * @return A Well-known Text representation of the given object. - */ - @NonNull - protected abstract String toWellKnownText(@NonNull T geometry); - - /** - * Returns a Well-known - * Binary (WKB) representation of the given geospatial object. - * - * @param geometry the geospatial object to convert. Cannot be null. - * @return A Well-known Binary representation of the given object. - */ - @NonNull - protected abstract ByteBuffer toWellKnownBinary(@NonNull T geometry); -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/type/codec/geometry/LineStringCodec.java b/core/src/main/java/com/datastax/dse/driver/internal/core/type/codec/geometry/LineStringCodec.java deleted file mode 100644 index bbec99a4103..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/type/codec/geometry/LineStringCodec.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.type.codec.geometry; - -import com.datastax.dse.driver.api.core.data.geometry.LineString; -import com.datastax.dse.driver.api.core.type.DseDataTypes; -import com.datastax.dse.driver.internal.core.data.geometry.DefaultGeometry; -import com.datastax.dse.driver.internal.core.data.geometry.DefaultLineString; -import com.datastax.oss.driver.api.core.type.DataType; -import com.datastax.oss.driver.api.core.type.reflect.GenericType; -import com.esri.core.geometry.ogc.OGCLineString; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.nio.ByteBuffer; -import net.jcip.annotations.ThreadSafe; - -/** - * A custom type codec to use {@link LineString} instances in driver. - * - *

If you use {@link com.datastax.dse.driver.api.core.DseSessionBuilder} to build your cluster, - * it will automatically register this codec. - */ -@ThreadSafe -public class LineStringCodec extends GeometryCodec { - - private static final GenericType JAVA_TYPE = GenericType.of(LineString.class); - - @NonNull - @Override - public GenericType getJavaType() { - return JAVA_TYPE; - } - - @NonNull - @Override - protected LineString fromWellKnownText(@NonNull String source) { - return new DefaultLineString(DefaultGeometry.fromOgcWellKnownText(source, OGCLineString.class)); - } - - @Override - public boolean accepts(@NonNull Class javaClass) { - return javaClass == LineString.class; - } - - @Override - public boolean accepts(@NonNull Object value) { - return value instanceof LineString; - } - - @NonNull - @Override - protected LineString fromWellKnownBinary(@NonNull ByteBuffer bb) { - return new DefaultLineString(DefaultGeometry.fromOgcWellKnownBinary(bb, OGCLineString.class)); - } - - @NonNull - @Override - protected String toWellKnownText(@NonNull LineString geometry) { - return geometry.asWellKnownText(); - } - - @NonNull - @Override - protected ByteBuffer toWellKnownBinary(@NonNull LineString geometry) { - return geometry.asWellKnownBinary(); - } - - @NonNull - @Override - public DataType getCqlType() { - return DseDataTypes.LINE_STRING; - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/type/codec/geometry/PointCodec.java b/core/src/main/java/com/datastax/dse/driver/internal/core/type/codec/geometry/PointCodec.java deleted file mode 100644 index 5ebae64cbab..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/type/codec/geometry/PointCodec.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.type.codec.geometry; - -import com.datastax.dse.driver.api.core.data.geometry.Point; -import com.datastax.dse.driver.api.core.type.DseDataTypes; -import com.datastax.dse.driver.internal.core.data.geometry.DefaultGeometry; -import com.datastax.dse.driver.internal.core.data.geometry.DefaultPoint; -import com.datastax.oss.driver.api.core.type.DataType; -import com.datastax.oss.driver.api.core.type.reflect.GenericType; -import com.esri.core.geometry.ogc.OGCPoint; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.nio.ByteBuffer; -import net.jcip.annotations.ThreadSafe; - -/** - * A custom type codec to use {@link Point} instances in the driver. - * - *

If you use {@link com.datastax.dse.driver.api.core.DseSessionBuilder} to build your cluster, - * it will automatically register this codec. - */ -@ThreadSafe -public class PointCodec extends GeometryCodec { - - private static final GenericType JAVA_TYPE = GenericType.of(Point.class); - - @NonNull - @Override - public GenericType getJavaType() { - return JAVA_TYPE; - } - - @NonNull - @Override - public DataType getCqlType() { - return DseDataTypes.POINT; - } - - @Override - public boolean accepts(@NonNull Class javaClass) { - return javaClass == Point.class; - } - - @Override - public boolean accepts(@NonNull Object value) { - return value instanceof Point; - } - - @NonNull - @Override - protected String toWellKnownText(@NonNull Point geometry) { - return geometry.asWellKnownText(); - } - - @NonNull - @Override - protected ByteBuffer toWellKnownBinary(@NonNull Point geometry) { - return geometry.asWellKnownBinary(); - } - - @NonNull - @Override - protected Point fromWellKnownText(@NonNull String source) { - return new DefaultPoint(DefaultGeometry.fromOgcWellKnownText(source, OGCPoint.class)); - } - - @NonNull - @Override - protected Point fromWellKnownBinary(@NonNull ByteBuffer source) { - return new DefaultPoint(DefaultGeometry.fromOgcWellKnownBinary(source, OGCPoint.class)); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/type/codec/geometry/PolygonCodec.java b/core/src/main/java/com/datastax/dse/driver/internal/core/type/codec/geometry/PolygonCodec.java deleted file mode 100644 index 00a070a4b4a..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/type/codec/geometry/PolygonCodec.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.type.codec.geometry; - -import com.datastax.dse.driver.api.core.data.geometry.Polygon; -import com.datastax.dse.driver.api.core.type.DseDataTypes; -import com.datastax.dse.driver.internal.core.data.geometry.DefaultGeometry; -import com.datastax.dse.driver.internal.core.data.geometry.DefaultPolygon; -import com.datastax.oss.driver.api.core.type.DataType; -import com.datastax.oss.driver.api.core.type.reflect.GenericType; -import com.esri.core.geometry.ogc.OGCPolygon; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.nio.ByteBuffer; -import net.jcip.annotations.ThreadSafe; - -/** - * A custom type codec to use {@link Polygon} instances in the driver. - * - *

If you use {@link com.datastax.dse.driver.api.core.DseSessionBuilder} to build your cluster, - * it will automatically register this codec. - */ -@ThreadSafe -public class PolygonCodec extends GeometryCodec { - - private static final GenericType JAVA_TYPE = GenericType.of(Polygon.class); - - @NonNull - @Override - public GenericType getJavaType() { - return JAVA_TYPE; - } - - @NonNull - @Override - public DataType getCqlType() { - return DseDataTypes.POLYGON; - } - - @Override - public boolean accepts(@NonNull Class javaClass) { - return javaClass == Polygon.class; - } - - @Override - public boolean accepts(@NonNull Object value) { - return value instanceof Polygon; - } - - @NonNull - @Override - protected Polygon fromWellKnownText(@NonNull String source) { - return new DefaultPolygon(DefaultGeometry.fromOgcWellKnownText(source, OGCPolygon.class)); - } - - @NonNull - @Override - protected Polygon fromWellKnownBinary(@NonNull ByteBuffer bb) { - return new DefaultPolygon(DefaultGeometry.fromOgcWellKnownBinary(bb, OGCPolygon.class)); - } - - @NonNull - @Override - protected String toWellKnownText(@NonNull Polygon geometry) { - return geometry.asWellKnownText(); - } - - @NonNull - @Override - protected ByteBuffer toWellKnownBinary(@NonNull Polygon geometry) { - return geometry.asWellKnownBinary(); - } -} diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/type/codec/time/DateRangeCodec.java b/core/src/main/java/com/datastax/dse/driver/internal/core/type/codec/time/DateRangeCodec.java deleted file mode 100644 index e8a23e88848..00000000000 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/type/codec/time/DateRangeCodec.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.type.codec.time; - -import com.datastax.dse.driver.api.core.data.time.DateRange; -import com.datastax.dse.driver.api.core.data.time.DateRangeBound; -import com.datastax.dse.driver.api.core.data.time.DateRangePrecision; -import com.datastax.dse.driver.api.core.type.DseDataTypes; -import com.datastax.oss.driver.api.core.ProtocolVersion; -import com.datastax.oss.driver.api.core.type.DataType; -import com.datastax.oss.driver.api.core.type.codec.TypeCodec; -import com.datastax.oss.driver.api.core.type.reflect.GenericType; -import com.datastax.oss.driver.internal.core.util.Strings; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.nio.ByteBuffer; -import java.text.ParseException; -import java.time.Instant; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; -import java.util.Optional; - -public class DateRangeCodec implements TypeCodec { - - private static final GenericType JAVA_TYPE = GenericType.of(DateRange.class); - private static final DataType CQL_TYPE = DseDataTypes.DATE_RANGE; - - // e.g. [2001-01-01] - private static final byte DATE_RANGE_TYPE_SINGLE_DATE = 0x00; - // e.g. [2001-01-01 TO 2001-01-31] - private static final byte DATE_RANGE_TYPE_CLOSED_RANGE = 0x01; - // e.g. [2001-01-01 TO *] - private static final byte DATE_RANGE_TYPE_OPEN_RANGE_HIGH = 0x02; - // e.g. [* TO 2001-01-01] - private static final byte DATE_RANGE_TYPE_OPEN_RANGE_LOW = 0x03; - // [* TO *] - private static final byte DATE_RANGE_TYPE_BOTH_OPEN_RANGE = 0x04; - // * - private static final byte DATE_RANGE_TYPE_SINGLE_DATE_OPEN = 0x05; - - @NonNull - @Override - public GenericType getJavaType() { - return JAVA_TYPE; - } - - @NonNull - @Override - public DataType getCqlType() { - return CQL_TYPE; - } - - @Override - public boolean accepts(@NonNull Class javaClass) { - return javaClass == DateRange.class; - } - - @Nullable - @Override - public ByteBuffer encode( - @Nullable DateRange dateRange, @NonNull ProtocolVersion protocolVersion) { - if (dateRange == null) { - return null; - } - byte rangeType = encodeType(dateRange); - int bufferSize = 1; - DateRangeBound lowerBound = dateRange.getLowerBound(); - Optional maybeUpperBound = dateRange.getUpperBound(); - bufferSize += lowerBound.isUnbounded() ? 0 : 9; - bufferSize += maybeUpperBound.map(upperBound -> upperBound.isUnbounded() ? 0 : 9).orElse(0); - ByteBuffer buffer = ByteBuffer.allocate(bufferSize); - buffer.put(rangeType); - if (!lowerBound.isUnbounded()) { - put(buffer, lowerBound); - } - maybeUpperBound.ifPresent( - upperBound -> { - if (!upperBound.isUnbounded()) { - put(buffer, upperBound); - } - }); - return (ByteBuffer) buffer.flip(); - } - - private static byte encodeType(DateRange dateRange) { - if (dateRange.isSingleBounded()) { - return dateRange.getLowerBound().isUnbounded() - ? DATE_RANGE_TYPE_SINGLE_DATE_OPEN - : DATE_RANGE_TYPE_SINGLE_DATE; - } else { - DateRangeBound upperBound = - dateRange - .getUpperBound() - .orElseThrow( - () -> - new IllegalStateException("Upper bound should be set if !isSingleBounded()")); - if (dateRange.getLowerBound().isUnbounded()) { - return upperBound.isUnbounded() - ? DATE_RANGE_TYPE_BOTH_OPEN_RANGE - : DATE_RANGE_TYPE_OPEN_RANGE_LOW; - } else { - return upperBound.isUnbounded() - ? DATE_RANGE_TYPE_OPEN_RANGE_HIGH - : DATE_RANGE_TYPE_CLOSED_RANGE; - } - } - } - - private static void put(ByteBuffer buffer, DateRangeBound bound) { - buffer.putLong(bound.getTimestamp().toInstant().toEpochMilli()); - buffer.put(bound.getPrecision().getEncoding()); - } - - @Nullable - @Override - public DateRange decode(@Nullable ByteBuffer bytes, @NonNull ProtocolVersion protocolVersion) { - if (bytes == null || bytes.remaining() == 0) { - return null; - } - byte type = bytes.get(); - switch (type) { - case DATE_RANGE_TYPE_SINGLE_DATE: - return new DateRange(decodeLowerBound(bytes)); - case DATE_RANGE_TYPE_CLOSED_RANGE: - return new DateRange(decodeLowerBound(bytes), decodeUpperBound(bytes)); - case DATE_RANGE_TYPE_OPEN_RANGE_HIGH: - return new DateRange(decodeLowerBound(bytes), DateRangeBound.UNBOUNDED); - case DATE_RANGE_TYPE_OPEN_RANGE_LOW: - return new DateRange(DateRangeBound.UNBOUNDED, decodeUpperBound(bytes)); - case DATE_RANGE_TYPE_BOTH_OPEN_RANGE: - return new DateRange(DateRangeBound.UNBOUNDED, DateRangeBound.UNBOUNDED); - case DATE_RANGE_TYPE_SINGLE_DATE_OPEN: - return new DateRange(DateRangeBound.UNBOUNDED); - default: - throw new IllegalArgumentException("Unknown date range type: " + type); - } - } - - private static DateRangeBound decodeLowerBound(ByteBuffer bytes) { - long epochMilli = bytes.getLong(); - ZonedDateTime timestamp = - ZonedDateTime.ofInstant(Instant.ofEpochMilli(epochMilli), ZoneOffset.UTC); - DateRangePrecision precision = DateRangePrecision.fromEncoding(bytes.get()); - return DateRangeBound.lowerBound(timestamp, precision); - } - - private static DateRangeBound decodeUpperBound(ByteBuffer bytes) { - long epochMilli = bytes.getLong(); - ZonedDateTime timestamp = - ZonedDateTime.ofInstant(Instant.ofEpochMilli(epochMilli), ZoneOffset.UTC); - DateRangePrecision precision = DateRangePrecision.fromEncoding(bytes.get()); - return DateRangeBound.upperBound(timestamp, precision); - } - - @NonNull - @Override - public String format(@Nullable DateRange dateRange) { - return (dateRange == null) ? "NULL" : Strings.quote(dateRange.toString()); - } - - @Nullable - @Override - public DateRange parse(@Nullable String value) { - if (value == null || value.isEmpty() || value.equalsIgnoreCase("NULL")) { - return null; - } - try { - return DateRange.parse(Strings.unquote(value)); - } catch (ParseException e) { - throw new IllegalArgumentException(String.format("Invalid date range literal: %s", value), e); - } - } -} diff --git a/core/src/main/java/com/datastax/oss/driver/api/core/CqlSession.java b/core/src/main/java/com/datastax/oss/driver/api/core/CqlSession.java index ff096719f3e..0d03fd98b0f 100644 --- a/core/src/main/java/com/datastax/oss/driver/api/core/CqlSession.java +++ b/core/src/main/java/com/datastax/oss/driver/api/core/CqlSession.java @@ -17,11 +17,7 @@ */ package com.datastax.oss.driver.api.core; -import com.datastax.dse.driver.api.core.cql.continuous.ContinuousSession; -import com.datastax.dse.driver.api.core.cql.continuous.reactive.ContinuousReactiveSession; import com.datastax.dse.driver.api.core.cql.reactive.ReactiveSession; -import com.datastax.dse.driver.api.core.graph.GraphSession; -import com.datastax.dse.driver.api.core.graph.reactive.ReactiveGraphSession; import com.datastax.oss.driver.api.core.cql.AsyncCqlSession; import com.datastax.oss.driver.api.core.cql.SyncCqlSession; import com.datastax.oss.driver.api.core.session.Session; @@ -30,31 +26,10 @@ /** * The default session type built by the driver. * - *

It provides user-friendly execution methods for: - * - *

    - *
  • CQL requests: synchronous, asynchronous or reactive mode; - *
  • requests specific to DataStax Enterprise: graph and continuous paging. - *
- * - * Client applications can use this interface even if they don't need all the features. In - * particular, it can be used with a regular Apache Cassandra ® cluster, as long as you don't - * call any of the DSE-specific execute methods. If you're in that situation, you might also want to - * exclude certain dependencies from your classpath (see the "Integration" page in the user manual). - * - *

Note that the name "CQL session" is no longer really accurate since this interface can now - * execute other request types; but it was preserved for backward compatibility with previous driver - * versions. + *

It provides user-friendly execution methods for synchronous, asynchronous, and reactive CQL + * requests. */ -public interface CqlSession - extends Session, - SyncCqlSession, - AsyncCqlSession, - ReactiveSession, - ContinuousSession, - GraphSession, - ContinuousReactiveSession, - ReactiveGraphSession { +public interface CqlSession extends Session, SyncCqlSession, AsyncCqlSession, ReactiveSession { /** * Returns a builder to create a new instance. diff --git a/core/src/main/java/com/datastax/oss/driver/api/core/ProtocolVersion.java b/core/src/main/java/com/datastax/oss/driver/api/core/ProtocolVersion.java index f999d217b2b..a8a659525dc 100644 --- a/core/src/main/java/com/datastax/oss/driver/api/core/ProtocolVersion.java +++ b/core/src/main/java/com/datastax/oss/driver/api/core/ProtocolVersion.java @@ -23,7 +23,6 @@ */ package com.datastax.oss.driver.api.core; -import com.datastax.dse.driver.api.core.DseProtocolVersion; import com.datastax.oss.driver.api.core.detach.Detachable; import edu.umd.cs.findbugs.annotations.NonNull; @@ -40,8 +39,6 @@ public interface ProtocolVersion { ProtocolVersion V4 = DefaultProtocolVersion.V4; ProtocolVersion V5 = DefaultProtocolVersion.V5; ProtocolVersion V6 = DefaultProtocolVersion.V6; - ProtocolVersion DSE_V1 = DseProtocolVersion.DSE_V1; - ProtocolVersion DSE_V2 = DseProtocolVersion.DSE_V2; /** The default version used for {@link Detachable detached} objects. */ // Implementation note: we can't use the ProtocolVersionRegistry here, this has to be a diff --git a/core/src/main/java/com/datastax/oss/driver/api/core/Version.java b/core/src/main/java/com/datastax/oss/driver/api/core/Version.java index 9b3226c45cf..67b86c19baa 100644 --- a/core/src/main/java/com/datastax/oss/driver/api/core/Version.java +++ b/core/src/main/java/com/datastax/oss/driver/api/core/Version.java @@ -62,8 +62,8 @@ public class Version implements Comparable, Serializable { private final int major; private final int minor; private final int patch; + // Keep the legacy name to preserve the serialized form used by previous driver releases. private final int dsePatch; - private final String[] preReleases; private final String build; @@ -112,12 +112,11 @@ public static Version parse(@Nullable String version) { : Integer.parseInt( pa.substring(1)); // dropping the initial '.' since it's included this time - String dse = matcher.group(4); - int dsePatch = - dse == null || dse.isEmpty() + String revisionGroup = matcher.group(4); + int revision = + revisionGroup == null || revisionGroup.isEmpty() ? -1 - : Integer.parseInt( - dse.substring(1)); // dropping the initial '.' since it's included this time + : Integer.parseInt(revisionGroup.substring(1)); String pr = matcher.group(5); String[] preReleases = @@ -131,7 +130,7 @@ public static Version parse(@Nullable String version) { String bl = matcher.group(6); String build = bl == null || bl.isEmpty() ? null : bl.substring(1); // drop the initial '+' - return new Version(major, minor, patch, dsePatch, preReleases, build); + return new Version(major, minor, patch, revision, preReleases, build); } catch (NumberFormatException e) { throw new IllegalArgumentException("Invalid version number: " + version); } @@ -165,16 +164,11 @@ public int getPatch() { } /** - * The DSE patch version number (will only be present for version of Cassandra in DSE). - * - *

DataStax Entreprise (DSE) adds a fourth number to the version number to track potential hot - * fixes and/or DSE specific patches that may have been applied to the Cassandra version. In that - * case, this method returns that fourth number. + * The optional fourth version component. * - * @return the DSE patch version number, i.e. D in X.Y.Z.D, or -1 if the version number is not - * from DSE. + * @return the revision, i.e. R in X.Y.Z.R, or -1 if it is absent. */ - public int getDSEPatch() { + public int getRevision() { return dsePatch; } @@ -234,22 +228,11 @@ public int compareTo(@NonNull Version other) { return 1; } - if (dsePatch < 0) { - if (other.dsePatch >= 0) { - return -1; - } - } else { - if (other.dsePatch < 0) { - return 1; - } - - // Both are >= 0 - if (dsePatch < other.dsePatch) { - return -1; - } - if (dsePatch > other.dsePatch) { - return 1; - } + if (dsePatch < other.dsePatch) { + return -1; + } + if (dsePatch > other.dsePatch) { + return 1; } if (preReleases == null) { diff --git a/core/src/main/java/com/datastax/oss/driver/api/core/auth/PlainTextAuthProviderBase.java b/core/src/main/java/com/datastax/oss/driver/api/core/auth/PlainTextAuthProviderBase.java index fb85797af9e..9f31ac6c7b0 100644 --- a/core/src/main/java/com/datastax/oss/driver/api/core/auth/PlainTextAuthProviderBase.java +++ b/core/src/main/java/com/datastax/oss/driver/api/core/auth/PlainTextAuthProviderBase.java @@ -17,17 +17,13 @@ */ package com.datastax.oss.driver.api.core.auth; -import com.datastax.dse.driver.api.core.auth.BaseDseAuthenticator; import com.datastax.oss.driver.api.core.metadata.EndPoint; import com.datastax.oss.driver.api.core.session.Session; import com.datastax.oss.driver.shaded.guava.common.base.Charsets; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; -import java.net.InetSocketAddress; -import java.net.SocketAddress; import java.nio.ByteBuffer; import java.nio.CharBuffer; -import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Objects; import net.jcip.annotations.ThreadSafe; @@ -74,8 +70,7 @@ protected abstract Credentials getCredentials( public Authenticator newAuthenticator( @NonNull EndPoint endPoint, @NonNull String serverAuthenticator) throws AuthenticationException { - return new PlainTextAuthenticator( - getCredentials(endPoint, serverAuthenticator), endPoint, serverAuthenticator); + return new PlainTextAuthenticator(getCredentials(endPoint, serverAuthenticator), endPoint); } @Override @@ -96,25 +91,10 @@ public static class Credentials { private final char[] username; private final char[] password; - private final char[] authorizationId; - - /** - * Builds an instance for username/password authentication, and proxy authentication with the - * given authorizationId. - * - *

This feature is only available with DataStax Enterprise. If the target server is Apache - * Cassandra, the authorizationId will be ignored. - */ - public Credentials( - @NonNull char[] username, @NonNull char[] password, @NonNull char[] authorizationId) { + /** Builds an instance for username/password authentication. */ + public Credentials(@NonNull char[] username, @NonNull char[] password) { this.username = Objects.requireNonNull(username); this.password = Objects.requireNonNull(password); - this.authorizationId = Objects.requireNonNull(authorizationId); - } - - /** Builds an instance for simple username/password authentication. */ - public Credentials(@NonNull char[] username, @NonNull char[] password) { - this(username, password, new char[0]); } @NonNull @@ -137,11 +117,6 @@ public char[] getPassword() { return password; } - @NonNull - public char[] getAuthorizationId() { - return authorizationId; - } - /** Clears the credentials from memory when they're no longer needed. */ protected void clear() { // Note: this is a bit irrelevant with the built-in provider, because the config already @@ -149,85 +124,35 @@ protected void clear() { // retrieves the credentials from a different source. Arrays.fill(getUsername(), (char) 0); Arrays.fill(getPassword(), (char) 0); - Arrays.fill(getAuthorizationId(), (char) 0); } } - // Implementation note: BaseDseAuthenticator is backward compatible with Cassandra authenticators. - // This will work with both Cassandra (as long as no authorizationId is set) and DSE. - protected static class PlainTextAuthenticator extends BaseDseAuthenticator { - - private static final ByteBuffer MECHANISM = - ByteBuffer.wrap("PLAIN".getBytes(StandardCharsets.UTF_8)).asReadOnlyBuffer(); - - private static final ByteBuffer SERVER_INITIAL_CHALLENGE = - ByteBuffer.wrap("PLAIN-START".getBytes(StandardCharsets.UTF_8)).asReadOnlyBuffer(); - - private static final EndPoint DUMMY_END_POINT = - new EndPoint() { - @NonNull - @Override - public SocketAddress resolve() { - return new InetSocketAddress("127.0.0.1", 9042); - } - - @NonNull - @Override - public String asMetricPrefix() { - return ""; // will never be used - } - }; + protected static class PlainTextAuthenticator implements SyncAuthenticator { private final ByteBuffer encodedCredentials; private final EndPoint endPoint; - protected PlainTextAuthenticator( - @NonNull Credentials credentials, - @NonNull EndPoint endPoint, - @NonNull String serverAuthenticator) { - super(serverAuthenticator); - + protected PlainTextAuthenticator(@NonNull Credentials credentials, @NonNull EndPoint endPoint) { Objects.requireNonNull(credentials); Objects.requireNonNull(endPoint); - ByteBuffer authorizationId = toUtf8Bytes(credentials.getAuthorizationId()); ByteBuffer username = toUtf8Bytes(credentials.getUsername()); ByteBuffer password = toUtf8Bytes(credentials.getPassword()); this.encodedCredentials = - ByteBuffer.allocate( - authorizationId.remaining() + username.remaining() + password.remaining() + 2); - encodedCredentials.put(authorizationId); + ByteBuffer.allocate(username.remaining() + password.remaining() + 2); encodedCredentials.put((byte) 0); encodedCredentials.put(username); encodedCredentials.put((byte) 0); encodedCredentials.put(password); encodedCredentials.flip(); - clear(authorizationId); clear(username); clear(password); this.endPoint = endPoint; } - /** - * @deprecated Preserved for backward compatibility, implementors should use the 3-arg - * constructor {@code PlainTextAuthenticator(Credentials, EndPoint, String)} instead. - */ - @Deprecated - protected PlainTextAuthenticator(@NonNull Credentials credentials) { - this( - credentials, - // It's unlikely that this class was ever extended by third parties, but if it was, assume - // that it was not written for DSE: - // - dummy end point because we should never need to build an auth exception - DUMMY_END_POINT, - // - default OSS authenticator name (the only thing that matters is how this string - // compares to "DseAuthenticator") - "org.apache.cassandra.auth.PasswordAuthenticator"); - } - private static ByteBuffer toUtf8Bytes(char[] charArray) { CharBuffer charBuffer = CharBuffer.wrap(charArray); return Charsets.UTF_8.encode(charBuffer); @@ -240,25 +165,19 @@ private static void clear(ByteBuffer buffer) { } } - @NonNull - @Override - public ByteBuffer getMechanism() { - return MECHANISM; - } - - @NonNull + @Nullable @Override - public ByteBuffer getInitialServerChallenge() { - return SERVER_INITIAL_CHALLENGE; + public ByteBuffer initialResponseSync() { + return encodedCredentials; } @Nullable @Override public ByteBuffer evaluateChallengeSync(@Nullable ByteBuffer challenge) { - if (SERVER_INITIAL_CHALLENGE.equals(challenge)) { - return encodedCredentials; - } throw new AuthenticationException(endPoint, "Incorrect challenge from server"); } + + @Override + public void onAuthenticationSuccessSync(@Nullable ByteBuffer token) {} } } diff --git a/core/src/main/java/com/datastax/oss/driver/api/core/auth/ProgrammaticPlainTextAuthProvider.java b/core/src/main/java/com/datastax/oss/driver/api/core/auth/ProgrammaticPlainTextAuthProvider.java index d991f5c5cb5..14e1c8c6d94 100644 --- a/core/src/main/java/com/datastax/oss/driver/api/core/auth/ProgrammaticPlainTextAuthProvider.java +++ b/core/src/main/java/com/datastax/oss/driver/api/core/auth/ProgrammaticPlainTextAuthProvider.java @@ -21,7 +21,6 @@ import com.datastax.oss.driver.api.core.session.SessionBuilder; import com.datastax.oss.driver.internal.core.util.Strings; import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Objects; import net.jcip.annotations.ThreadSafe; /** @@ -51,37 +50,20 @@ * * @see SessionBuilder#withAuthProvider(AuthProvider) * @see SessionBuilder#withAuthCredentials(String, String) - * @see SessionBuilder#withAuthCredentials(String, String, String) */ @ThreadSafe public class ProgrammaticPlainTextAuthProvider extends PlainTextAuthProviderBase { private volatile char[] username; private volatile char[] password; - private volatile char[] authorizationId; /** Builds an instance for simple username/password authentication. */ public ProgrammaticPlainTextAuthProvider(@NonNull String username, @NonNull String password) { - this(username, password, ""); - } - - /** - * Builds an instance for username/password authentication, and proxy authentication with the - * given authorizationId. - * - *

This feature is only available with DataStax Enterprise. If the target server is Apache - * Cassandra, use {@link #ProgrammaticPlainTextAuthProvider(String, String)} instead, or set the - * authorizationId to an empty string. - */ - public ProgrammaticPlainTextAuthProvider( - @NonNull String username, @NonNull String password, @NonNull String authorizationId) { // This will typically be built before the session so we don't know the log prefix yet. Pass an // empty string, it's only used in one log message. super(""); this.username = Strings.requireNotEmpty(username, "username").toCharArray(); this.password = Strings.requireNotEmpty(password, "password").toCharArray(); - this.authorizationId = - Objects.requireNonNull(authorizationId, "authorizationId cannot be null").toCharArray(); } /** @@ -106,21 +88,6 @@ public void setPassword(@NonNull String password) { this.password = Strings.requireNotEmpty(password, "password").toCharArray(); } - /** - * Changes the authorization id. - * - *

The new credentials will be used for all connections initiated after this method was called. - * - *

This feature is only available with DataStax Enterprise. If the target server is Apache - * Cassandra, this method should not be used. - * - * @param authorizationId the new authorization id. - */ - public void setAuthorizationId(@NonNull String authorizationId) { - this.authorizationId = - Objects.requireNonNull(authorizationId, "authorizationId cannot be null").toCharArray(); - } - /** * {@inheritDoc} * @@ -131,6 +98,6 @@ public void setAuthorizationId(@NonNull String authorizationId) { @Override protected Credentials getCredentials( @NonNull EndPoint endPoint, @NonNull String serverAuthenticator) { - return new Credentials(username.clone(), password.clone(), authorizationId.clone()); + return new Credentials(username.clone(), password.clone()); } } diff --git a/core/src/main/java/com/datastax/oss/driver/api/core/config/DefaultDriverOption.java b/core/src/main/java/com/datastax/oss/driver/api/core/config/DefaultDriverOption.java index dd60a2487fb..c3c19fc80f1 100644 --- a/core/src/main/java/com/datastax/oss/driver/api/core/config/DefaultDriverOption.java +++ b/core/src/main/java/com/datastax/oss/driver/api/core/config/DefaultDriverOption.java @@ -43,6 +43,18 @@ public enum DefaultDriverOption implements DriverOption { *

Value-type: {@link String} */ SESSION_KEYSPACE("basic.session-keyspace"), + /** + * The name of the application using the session. + * + *

Value-type: {@link String} + */ + APPLICATION_NAME("basic.application.name"), + /** + * The version of the application using the session. + * + *

Value-type: {@link String} + */ + APPLICATION_VERSION("basic.application.version"), /** * How often the driver tries to reload the configuration. * @@ -869,14 +881,6 @@ public enum DefaultDriverOption implements DriverOption { */ NETTY_DAEMON("advanced.netty.daemon"), - /** - * The location of the cloud secure bundle used to connect to DataStax Apache Cassandra as a - * service. - * - *

Value-type: {@link String} - */ - CLOUD_SECURE_CONNECT_BUNDLE("basic.cloud.secure-connect-bundle"), - /** * Whether the slow replica avoidance should be enabled in the default LBP. * diff --git a/core/src/main/java/com/datastax/oss/driver/api/core/config/OptionsMap.java b/core/src/main/java/com/datastax/oss/driver/api/core/config/OptionsMap.java index c1a428b3524..dcfd4e7be78 100644 --- a/core/src/main/java/com/datastax/oss/driver/api/core/config/OptionsMap.java +++ b/core/src/main/java/com/datastax/oss/driver/api/core/config/OptionsMap.java @@ -249,9 +249,6 @@ protected static void fillWithDriverDefaults(OptionsMap map) { Duration initQueryTimeout = Duration.ofSeconds(5); Duration requestTimeout = Duration.ofSeconds(2); int requestPageSize = 5000; - int continuousMaxPages = 0; - int continuousMaxPagesPerSecond = 0; - int continuousMaxEnqueuedPages = 4; // Sorted by order of appearance in reference.conf: @@ -264,7 +261,6 @@ protected static void fillWithDriverDefaults(OptionsMap map) { CQL4SkipMetadataResolveMethod.SMART.toString()); map.put(TypedDriverOption.REQUEST_SERIAL_CONSISTENCY, "SERIAL"); map.put(TypedDriverOption.REQUEST_DEFAULT_IDEMPOTENCE, false); - map.put(TypedDriverOption.GRAPH_TRAVERSAL_SOURCE, "g"); map.put(TypedDriverOption.LOAD_BALANCING_POLICY_CLASS, "DefaultLoadBalancingPolicy"); map.put(TypedDriverOption.LOAD_BALANCING_POLICY_SLOW_AVOIDANCE, true); map.put(TypedDriverOption.SESSION_LEAK_THRESHOLD, 4); @@ -299,22 +295,6 @@ protected static void fillWithDriverDefaults(OptionsMap map) { map.put(TypedDriverOption.REQUEST_TRACE_INTERVAL, Duration.ofMillis(3)); map.put(TypedDriverOption.REQUEST_TRACE_CONSISTENCY, "ONE"); map.put(TypedDriverOption.REQUEST_LOG_WARNINGS, true); - map.put(TypedDriverOption.GRAPH_PAGING_ENABLED, "AUTO"); - map.put(TypedDriverOption.GRAPH_CONTINUOUS_PAGING_PAGE_SIZE, requestPageSize); - map.put(TypedDriverOption.GRAPH_CONTINUOUS_PAGING_MAX_PAGES, continuousMaxPages); - map.put( - TypedDriverOption.GRAPH_CONTINUOUS_PAGING_MAX_PAGES_PER_SECOND, - continuousMaxPagesPerSecond); - map.put( - TypedDriverOption.GRAPH_CONTINUOUS_PAGING_MAX_ENQUEUED_PAGES, continuousMaxEnqueuedPages); - map.put(TypedDriverOption.CONTINUOUS_PAGING_PAGE_SIZE, requestPageSize); - map.put(TypedDriverOption.CONTINUOUS_PAGING_PAGE_SIZE_BYTES, false); - map.put(TypedDriverOption.CONTINUOUS_PAGING_MAX_PAGES, continuousMaxPages); - map.put(TypedDriverOption.CONTINUOUS_PAGING_MAX_PAGES_PER_SECOND, continuousMaxPagesPerSecond); - map.put(TypedDriverOption.CONTINUOUS_PAGING_MAX_ENQUEUED_PAGES, continuousMaxEnqueuedPages); - map.put(TypedDriverOption.CONTINUOUS_PAGING_TIMEOUT_FIRST_PAGE, Duration.ofSeconds(2)); - map.put(TypedDriverOption.CONTINUOUS_PAGING_TIMEOUT_OTHER_PAGES, Duration.ofSeconds(1)); - map.put(TypedDriverOption.MONITOR_REPORTING_ENABLED, true); map.put(TypedDriverOption.METRICS_SESSION_ENABLED, Collections.emptyList()); map.put(TypedDriverOption.METRICS_SESSION_CQL_REQUESTS_HIGHEST, Duration.ofSeconds(3)); map.put(TypedDriverOption.METRICS_SESSION_CQL_REQUESTS_LOWEST, Duration.ofMillis(1)); @@ -324,31 +304,13 @@ protected static void fillWithDriverDefaults(OptionsMap map) { map.put(TypedDriverOption.METRICS_SESSION_THROTTLING_LOWEST, Duration.ofMillis(1)); map.put(TypedDriverOption.METRICS_SESSION_THROTTLING_DIGITS, 3); map.put(TypedDriverOption.METRICS_SESSION_THROTTLING_INTERVAL, Duration.ofMinutes(5)); - map.put( - TypedDriverOption.CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_HIGHEST, - Duration.ofMinutes(2)); - map.put( - TypedDriverOption.CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_LOWEST, - Duration.ofMillis(10)); - map.put(TypedDriverOption.CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_DIGITS, 3); - map.put( - TypedDriverOption.CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_INTERVAL, - Duration.ofMinutes(5)); map.put(TypedDriverOption.METRICS_FACTORY_CLASS, "DefaultMetricsFactory"); map.put(TypedDriverOption.METRICS_ID_GENERATOR_CLASS, "DefaultMetricIdGenerator"); - map.put(TypedDriverOption.METRICS_SESSION_GRAPH_REQUESTS_HIGHEST, Duration.ofSeconds(12)); - map.put(TypedDriverOption.METRICS_SESSION_GRAPH_REQUESTS_LOWEST, Duration.ofMillis(1)); - map.put(TypedDriverOption.METRICS_SESSION_GRAPH_REQUESTS_DIGITS, 3); - map.put(TypedDriverOption.METRICS_SESSION_GRAPH_REQUESTS_INTERVAL, Duration.ofMinutes(5)); map.put(TypedDriverOption.METRICS_NODE_ENABLED, Collections.emptyList()); map.put(TypedDriverOption.METRICS_NODE_CQL_MESSAGES_HIGHEST, Duration.ofSeconds(3)); map.put(TypedDriverOption.METRICS_NODE_CQL_MESSAGES_LOWEST, Duration.ofMillis(1)); map.put(TypedDriverOption.METRICS_NODE_CQL_MESSAGES_DIGITS, 3); map.put(TypedDriverOption.METRICS_NODE_CQL_MESSAGES_INTERVAL, Duration.ofMinutes(5)); - map.put(TypedDriverOption.METRICS_NODE_GRAPH_MESSAGES_HIGHEST, Duration.ofSeconds(3)); - map.put(TypedDriverOption.METRICS_NODE_GRAPH_MESSAGES_LOWEST, Duration.ofMillis(1)); - map.put(TypedDriverOption.METRICS_NODE_GRAPH_MESSAGES_DIGITS, 3); - map.put(TypedDriverOption.METRICS_NODE_GRAPH_MESSAGES_INTERVAL, Duration.ofMinutes(5)); map.put(TypedDriverOption.METRICS_NODE_EXPIRE_AFTER, Duration.ofHours(1)); map.put(TypedDriverOption.SOCKET_TCP_NODELAY, true); map.put(TypedDriverOption.HEARTBEAT_INTERVAL, Duration.ofSeconds(30)); @@ -359,7 +321,7 @@ protected static void fillWithDriverDefaults(OptionsMap map) { map.put(TypedDriverOption.METADATA_SCHEMA_ENABLED, true); map.put( TypedDriverOption.METADATA_SCHEMA_REFRESHED_KEYSPACES, - ImmutableList.of("!system", "!/^system_.*/", "!/^dse_.*/", "!solr_admin", "!OpsCenter")); + ImmutableList.of("!system", "!/^system_.*/")); map.put(TypedDriverOption.METADATA_SCHEMA_REQUEST_TIMEOUT, Duration.ofSeconds(20)); map.put(TypedDriverOption.METADATA_SCHEMA_REQUEST_PAGE_SIZE, requestPageSize); map.put(TypedDriverOption.METADATA_SCHEMA_WINDOW, Duration.ofSeconds(1)); diff --git a/core/src/main/java/com/datastax/oss/driver/api/core/config/TypedDriverOption.java b/core/src/main/java/com/datastax/oss/driver/api/core/config/TypedDriverOption.java index af93e734ef1..76fff1a5ded 100644 --- a/core/src/main/java/com/datastax/oss/driver/api/core/config/TypedDriverOption.java +++ b/core/src/main/java/com/datastax/oss/driver/api/core/config/TypedDriverOption.java @@ -17,7 +17,6 @@ */ package com.datastax.oss.driver.api.core.config; -import com.datastax.dse.driver.api.core.config.DseDriverOption; import com.datastax.oss.driver.api.core.type.reflect.GenericType; import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; import edu.umd.cs.findbugs.annotations.NonNull; @@ -685,12 +684,6 @@ public String toString() { /** Whether the threads created by the driver should be daemon threads. */ public static final TypedDriverOption NETTY_DAEMON = new TypedDriverOption<>(DefaultDriverOption.NETTY_DAEMON, GenericType.BOOLEAN); - /** - * The location of the cloud secure bundle used to connect to DataStax Apache Cassandra as a - * service. - */ - public static final TypedDriverOption CLOUD_SECURE_CONNECT_BUNDLE = - new TypedDriverOption<>(DefaultDriverOption.CLOUD_SECURE_CONNECT_BUNDLE, GenericType.STRING); /** Whether the slow replica avoidance should be enabled in the default LBP. */ public static final TypedDriverOption LOAD_BALANCING_POLICY_SLOW_AVOIDANCE = new TypedDriverOption<>( @@ -704,204 +697,10 @@ public String toString() { /** The name of the application using the session. */ public static final TypedDriverOption APPLICATION_NAME = - new TypedDriverOption<>(DseDriverOption.APPLICATION_NAME, GenericType.STRING); + new TypedDriverOption<>(DefaultDriverOption.APPLICATION_NAME, GenericType.STRING); /** The version of the application using the session. */ public static final TypedDriverOption APPLICATION_VERSION = - new TypedDriverOption<>(DseDriverOption.APPLICATION_VERSION, GenericType.STRING); - /** Proxy authentication for GSSAPI authentication: allows to login as another user or role. */ - public static final TypedDriverOption AUTH_PROVIDER_AUTHORIZATION_ID = - new TypedDriverOption<>(DseDriverOption.AUTH_PROVIDER_AUTHORIZATION_ID, GenericType.STRING); - /** Service name for GSSAPI authentication. */ - public static final TypedDriverOption AUTH_PROVIDER_SERVICE = - new TypedDriverOption<>(DseDriverOption.AUTH_PROVIDER_SERVICE, GenericType.STRING); - /** Login configuration for GSSAPI authentication. */ - public static final TypedDriverOption AUTH_PROVIDER_LOGIN_CONFIGURATION = - new TypedDriverOption<>( - DseDriverOption.AUTH_PROVIDER_LOGIN_CONFIGURATION, GenericType.STRING); - /** Internal SASL properties, if any, such as QOP, for GSSAPI authentication. */ - public static final TypedDriverOption> AUTH_PROVIDER_SASL_PROPERTIES = - new TypedDriverOption<>( - DseDriverOption.AUTH_PROVIDER_SASL_PROPERTIES, - GenericType.mapOf(GenericType.STRING, GenericType.STRING)); - /** The page size for continuous paging. */ - public static final TypedDriverOption CONTINUOUS_PAGING_PAGE_SIZE = - new TypedDriverOption<>(DseDriverOption.CONTINUOUS_PAGING_PAGE_SIZE, GenericType.INTEGER); - /** - * Whether {@link #CONTINUOUS_PAGING_PAGE_SIZE} should be interpreted in number of rows or bytes. - */ - public static final TypedDriverOption CONTINUOUS_PAGING_PAGE_SIZE_BYTES = - new TypedDriverOption<>( - DseDriverOption.CONTINUOUS_PAGING_PAGE_SIZE_BYTES, GenericType.BOOLEAN); - /** The maximum number of continuous pages to return. */ - public static final TypedDriverOption CONTINUOUS_PAGING_MAX_PAGES = - new TypedDriverOption<>(DseDriverOption.CONTINUOUS_PAGING_MAX_PAGES, GenericType.INTEGER); - /** The maximum number of continuous pages per second. */ - public static final TypedDriverOption CONTINUOUS_PAGING_MAX_PAGES_PER_SECOND = - new TypedDriverOption<>( - DseDriverOption.CONTINUOUS_PAGING_MAX_PAGES_PER_SECOND, GenericType.INTEGER); - /** The maximum number of continuous pages that can be stored in the local queue. */ - public static final TypedDriverOption CONTINUOUS_PAGING_MAX_ENQUEUED_PAGES = - new TypedDriverOption<>( - DseDriverOption.CONTINUOUS_PAGING_MAX_ENQUEUED_PAGES, GenericType.INTEGER); - /** How long to wait for the coordinator to send the first continuous page. */ - public static final TypedDriverOption CONTINUOUS_PAGING_TIMEOUT_FIRST_PAGE = - new TypedDriverOption<>( - DseDriverOption.CONTINUOUS_PAGING_TIMEOUT_FIRST_PAGE, GenericType.DURATION); - /** How long to wait for the coordinator to send subsequent continuous pages. */ - public static final TypedDriverOption CONTINUOUS_PAGING_TIMEOUT_OTHER_PAGES = - new TypedDriverOption<>( - DseDriverOption.CONTINUOUS_PAGING_TIMEOUT_OTHER_PAGES, GenericType.DURATION); - /** The largest latency that we expect to record for continuous requests. */ - public static final TypedDriverOption - CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_HIGHEST = - new TypedDriverOption<>( - DseDriverOption.CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_HIGHEST, - GenericType.DURATION); - /** The shortest latency that we expect to record for continuous requests. */ - public static final TypedDriverOption - CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_LOWEST = - new TypedDriverOption<>( - DseDriverOption.CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_LOWEST, - GenericType.DURATION); - /** Optional service-level objectives to meet, as a list of latencies to track. */ - public static final TypedDriverOption> - CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_SLO = - new TypedDriverOption<>( - DseDriverOption.CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_SLO, - GenericType.listOf(GenericType.DURATION)); - /** - * Optional pre-defined percentile of continuous paging cql requests to publish, as a list of - * percentiles . - */ - public static final TypedDriverOption> - CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_PUBLISH_PERCENTILES = - new TypedDriverOption<>( - DseDriverOption.CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_PUBLISH_PERCENTILES, - GenericType.listOf(GenericType.DOUBLE)); - /** - * The number of significant decimal digits to which internal structures will maintain for - * continuous requests. - */ - public static final TypedDriverOption - CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_DIGITS = - new TypedDriverOption<>( - DseDriverOption.CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_DIGITS, - GenericType.INTEGER); - /** The interval at which percentile data is refreshed for continuous requests. */ - public static final TypedDriverOption - CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_INTERVAL = - new TypedDriverOption<>( - DseDriverOption.CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_INTERVAL, - GenericType.DURATION); - /** The read consistency level to use for graph statements. */ - public static final TypedDriverOption GRAPH_READ_CONSISTENCY_LEVEL = - new TypedDriverOption<>(DseDriverOption.GRAPH_READ_CONSISTENCY_LEVEL, GenericType.STRING); - /** The write consistency level to use for graph statements. */ - public static final TypedDriverOption GRAPH_WRITE_CONSISTENCY_LEVEL = - new TypedDriverOption<>(DseDriverOption.GRAPH_WRITE_CONSISTENCY_LEVEL, GenericType.STRING); - /** The traversal source to use for graph statements. */ - public static final TypedDriverOption GRAPH_TRAVERSAL_SOURCE = - new TypedDriverOption<>(DseDriverOption.GRAPH_TRAVERSAL_SOURCE, GenericType.STRING); - /** - * The sub-protocol the driver will use to communicate with DSE Graph, on top of the Cassandra - * native protocol. - */ - public static final TypedDriverOption GRAPH_SUB_PROTOCOL = - new TypedDriverOption<>(DseDriverOption.GRAPH_SUB_PROTOCOL, GenericType.STRING); - /** Whether a script statement represents a system query. */ - public static final TypedDriverOption GRAPH_IS_SYSTEM_QUERY = - new TypedDriverOption<>(DseDriverOption.GRAPH_IS_SYSTEM_QUERY, GenericType.BOOLEAN); - /** The name of the graph targeted by graph statements. */ - public static final TypedDriverOption GRAPH_NAME = - new TypedDriverOption<>(DseDriverOption.GRAPH_NAME, GenericType.STRING); - /** How long the driver waits for a graph request to complete. */ - public static final TypedDriverOption GRAPH_TIMEOUT = - new TypedDriverOption<>(DseDriverOption.GRAPH_TIMEOUT, GenericType.DURATION); - /** Whether to send events for Insights monitoring. */ - public static final TypedDriverOption MONITOR_REPORTING_ENABLED = - new TypedDriverOption<>(DseDriverOption.MONITOR_REPORTING_ENABLED, GenericType.BOOLEAN); - /** Whether to enable paging for Graph queries. */ - public static final TypedDriverOption GRAPH_PAGING_ENABLED = - new TypedDriverOption<>(DseDriverOption.GRAPH_PAGING_ENABLED, GenericType.STRING); - /** The page size for Graph continuous paging. */ - public static final TypedDriverOption GRAPH_CONTINUOUS_PAGING_PAGE_SIZE = - new TypedDriverOption<>( - DseDriverOption.GRAPH_CONTINUOUS_PAGING_PAGE_SIZE, GenericType.INTEGER); - /** The maximum number of Graph continuous pages to return. */ - public static final TypedDriverOption GRAPH_CONTINUOUS_PAGING_MAX_PAGES = - new TypedDriverOption<>( - DseDriverOption.GRAPH_CONTINUOUS_PAGING_MAX_PAGES, GenericType.INTEGER); - /** The maximum number of Graph continuous pages per second. */ - public static final TypedDriverOption GRAPH_CONTINUOUS_PAGING_MAX_PAGES_PER_SECOND = - new TypedDriverOption<>( - DseDriverOption.GRAPH_CONTINUOUS_PAGING_MAX_PAGES_PER_SECOND, GenericType.INTEGER); - /** The maximum number of Graph continuous pages that can be stored in the local queue. */ - public static final TypedDriverOption GRAPH_CONTINUOUS_PAGING_MAX_ENQUEUED_PAGES = - new TypedDriverOption<>( - DseDriverOption.GRAPH_CONTINUOUS_PAGING_MAX_ENQUEUED_PAGES, GenericType.INTEGER); - /** The largest latency that we expect to record for graph requests. */ - public static final TypedDriverOption METRICS_SESSION_GRAPH_REQUESTS_HIGHEST = - new TypedDriverOption<>( - DseDriverOption.METRICS_SESSION_GRAPH_REQUESTS_HIGHEST, GenericType.DURATION); - /** The shortest latency that we expect to record for graph requests. */ - public static final TypedDriverOption METRICS_SESSION_GRAPH_REQUESTS_LOWEST = - new TypedDriverOption<>( - DseDriverOption.METRICS_SESSION_GRAPH_REQUESTS_LOWEST, GenericType.DURATION); - /** Optional service-level objectives to meet, as a list of latencies to track. */ - public static final TypedDriverOption> METRICS_SESSION_GRAPH_REQUESTS_SLO = - new TypedDriverOption<>( - DseDriverOption.METRICS_SESSION_GRAPH_REQUESTS_SLO, - GenericType.listOf(GenericType.DURATION)); - /** Optional pre-defined percentile of graph requests to publish, as a list of percentiles . */ - public static final TypedDriverOption> - METRICS_SESSION_GRAPH_REQUESTS_PUBLISH_PERCENTILES = - new TypedDriverOption<>( - DseDriverOption.METRICS_SESSION_GRAPH_REQUESTS_PUBLISH_PERCENTILES, - GenericType.listOf(GenericType.DOUBLE)); - /** - * The number of significant decimal digits to which internal structures will maintain for graph - * requests. - */ - public static final TypedDriverOption METRICS_SESSION_GRAPH_REQUESTS_DIGITS = - new TypedDriverOption<>( - DseDriverOption.METRICS_SESSION_GRAPH_REQUESTS_DIGITS, GenericType.INTEGER); - /** The interval at which percentile data is refreshed for graph requests. */ - public static final TypedDriverOption METRICS_SESSION_GRAPH_REQUESTS_INTERVAL = - new TypedDriverOption<>( - DseDriverOption.METRICS_SESSION_GRAPH_REQUESTS_INTERVAL, GenericType.DURATION); - /** The largest latency that we expect to record for graph requests. */ - public static final TypedDriverOption METRICS_NODE_GRAPH_MESSAGES_HIGHEST = - new TypedDriverOption<>( - DseDriverOption.METRICS_NODE_GRAPH_MESSAGES_HIGHEST, GenericType.DURATION); - /** The shortest latency that we expect to record for graph requests. */ - public static final TypedDriverOption METRICS_NODE_GRAPH_MESSAGES_LOWEST = - new TypedDriverOption<>( - DseDriverOption.METRICS_NODE_GRAPH_MESSAGES_LOWEST, GenericType.DURATION); - /** Optional service-level objectives to meet, as a list of latencies to track. */ - public static final TypedDriverOption> METRICS_NODE_GRAPH_MESSAGES_SLO = - new TypedDriverOption<>( - DseDriverOption.METRICS_NODE_GRAPH_MESSAGES_SLO, - GenericType.listOf(GenericType.DURATION)); - /** - * Optional pre-defined percentile of node graph requests to publish, as a list of percentiles . - */ - public static final TypedDriverOption> - METRICS_NODE_GRAPH_MESSAGES_PUBLISH_PERCENTILES = - new TypedDriverOption<>( - DseDriverOption.METRICS_NODE_GRAPH_MESSAGES_PUBLISH_PERCENTILES, - GenericType.listOf(GenericType.DOUBLE)); - /** - * The number of significant decimal digits to which internal structures will maintain for graph - * requests. - */ - public static final TypedDriverOption METRICS_NODE_GRAPH_MESSAGES_DIGITS = - new TypedDriverOption<>( - DseDriverOption.METRICS_NODE_GRAPH_MESSAGES_DIGITS, GenericType.INTEGER); - /** The interval at which percentile data is refreshed for graph requests. */ - public static final TypedDriverOption METRICS_NODE_GRAPH_MESSAGES_INTERVAL = - new TypedDriverOption<>( - DseDriverOption.METRICS_NODE_GRAPH_MESSAGES_INTERVAL, GenericType.DURATION); - + new TypedDriverOption<>(DefaultDriverOption.APPLICATION_VERSION, GenericType.STRING); /** The time after which the node level metrics will be evicted. */ public static final TypedDriverOption METRICS_NODE_EXPIRE_AFTER = new TypedDriverOption<>(DefaultDriverOption.METRICS_NODE_EXPIRE_AFTER, GenericType.DURATION); diff --git a/core/src/main/java/com/datastax/oss/driver/api/core/metrics/NodeMetric.java b/core/src/main/java/com/datastax/oss/driver/api/core/metrics/NodeMetric.java index b31c0ed8bcf..1c108fd6022 100644 --- a/core/src/main/java/com/datastax/oss/driver/api/core/metrics/NodeMetric.java +++ b/core/src/main/java/com/datastax/oss/driver/api/core/metrics/NodeMetric.java @@ -23,9 +23,8 @@ /** * A node-level metric exposed through {@link Session#getMetrics()}. * - *

All metrics exposed out of the box by the driver are instances of {@link DefaultNodeMetric} or - * {@link com.datastax.dse.driver.api.core.metrics.DseNodeMetric DseNodeMetric} (this interface only - * exists to allow custom metrics in driver extensions). + *

All metrics exposed out of the box by the driver are instances of {@link DefaultNodeMetric} + * (this interface only exists to allow custom metrics in driver extensions). * * @see SessionMetric */ diff --git a/core/src/main/java/com/datastax/oss/driver/api/core/metrics/SessionMetric.java b/core/src/main/java/com/datastax/oss/driver/api/core/metrics/SessionMetric.java index 2a1ee599754..a76f3b269da 100644 --- a/core/src/main/java/com/datastax/oss/driver/api/core/metrics/SessionMetric.java +++ b/core/src/main/java/com/datastax/oss/driver/api/core/metrics/SessionMetric.java @@ -24,8 +24,7 @@ * A session-level metric exposed through {@link Session#getMetrics()}. * *

All metrics exposed out of the box by the driver are instances of {@link DefaultSessionMetric} - * or {@link com.datastax.dse.driver.api.core.metrics.DseSessionMetric DseSessionMetric} (this - * interface only exists to allow custom metrics in driver extensions). + * (this interface only exists to allow custom metrics in driver extensions). * * @see NodeMetric */ diff --git a/core/src/main/java/com/datastax/oss/driver/api/core/session/ProgrammaticArguments.java b/core/src/main/java/com/datastax/oss/driver/api/core/session/ProgrammaticArguments.java index 4db44655dc2..d70bf780593 100644 --- a/core/src/main/java/com/datastax/oss/driver/api/core/session/ProgrammaticArguments.java +++ b/core/src/main/java/com/datastax/oss/driver/api/core/session/ProgrammaticArguments.java @@ -36,7 +36,6 @@ import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; -import java.net.InetSocketAddress; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -68,7 +67,6 @@ public static Builder builder() { private final ClassLoader classLoader; private final AuthProvider authProvider; private final SslEngineFactory sslEngineFactory; - private final InetSocketAddress cloudProxyAddress; private final UUID startupClientId; private final String startupApplicationName; private final String startupApplicationVersion; @@ -88,7 +86,6 @@ private ProgrammaticArguments( @Nullable ClassLoader classLoader, @Nullable AuthProvider authProvider, @Nullable SslEngineFactory sslEngineFactory, - @Nullable InetSocketAddress cloudProxyAddress, @Nullable UUID startupClientId, @Nullable String startupApplicationName, @Nullable String startupApplicationVersion, @@ -107,7 +104,6 @@ private ProgrammaticArguments( this.classLoader = classLoader; this.authProvider = authProvider; this.sslEngineFactory = sslEngineFactory; - this.cloudProxyAddress = cloudProxyAddress; this.startupClientId = startupClientId; this.startupApplicationName = startupApplicationName; this.startupApplicationVersion = startupApplicationVersion; @@ -173,11 +169,6 @@ public SslEngineFactory getSslEngineFactory() { return sslEngineFactory; } - @Nullable - public InetSocketAddress getCloudProxyAddress() { - return cloudProxyAddress; - } - @Nullable public UUID getStartupClientId() { return startupClientId; @@ -223,7 +214,6 @@ public static class Builder { private ClassLoader classLoader; private AuthProvider authProvider; private SslEngineFactory sslEngineFactory; - private InetSocketAddress cloudProxyAddress; private UUID startupClientId; private String startupApplicationName; private String startupApplicationVersion; @@ -388,12 +378,6 @@ public Builder withClassLoader(@Nullable ClassLoader classLoader) { return this; } - @NonNull - public Builder withCloudProxyAddress(@Nullable InetSocketAddress cloudAddress) { - this.cloudProxyAddress = cloudAddress; - return this; - } - @NonNull public Builder withAuthProvider(@Nullable AuthProvider authProvider) { this.authProvider = authProvider; @@ -456,7 +440,6 @@ public ProgrammaticArguments build() { classLoader, authProvider, sslEngineFactory, - cloudProxyAddress, startupClientId, startupApplicationName, startupApplicationVersion, diff --git a/core/src/main/java/com/datastax/oss/driver/api/core/session/SessionBuilder.java b/core/src/main/java/com/datastax/oss/driver/api/core/session/SessionBuilder.java index 8375f0ef30b..ce5630ac671 100644 --- a/core/src/main/java/com/datastax/oss/driver/api/core/session/SessionBuilder.java +++ b/core/src/main/java/com/datastax/oss/driver/api/core/session/SessionBuilder.java @@ -30,7 +30,6 @@ import com.datastax.oss.driver.api.core.auth.ProgrammaticPlainTextAuthProvider; import com.datastax.oss.driver.api.core.config.ClientRoutesConfig; import com.datastax.oss.driver.api.core.config.DefaultDriverOption; -import com.datastax.oss.driver.api.core.config.DriverConfig; import com.datastax.oss.driver.api.core.config.DriverConfigLoader; import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; import com.datastax.oss.driver.api.core.context.DriverContext; @@ -48,24 +47,16 @@ import com.datastax.oss.driver.api.core.type.codec.registry.MutableCodecRegistry; import com.datastax.oss.driver.api.core.uuid.Uuids; import com.datastax.oss.driver.internal.core.ContactPoints; -import com.datastax.oss.driver.internal.core.config.cloud.CloudConfig; -import com.datastax.oss.driver.internal.core.config.cloud.CloudConfigFactory; import com.datastax.oss.driver.internal.core.config.typesafe.DefaultDriverConfigLoader; import com.datastax.oss.driver.internal.core.context.DefaultDriverContext; import com.datastax.oss.driver.internal.core.context.InternalDriverContext; import com.datastax.oss.driver.internal.core.metadata.DefaultEndPoint; import com.datastax.oss.driver.internal.core.session.DefaultSession; -import com.datastax.oss.driver.internal.core.tracker.W3CContextRequestIdGenerator; import com.datastax.oss.driver.internal.core.util.concurrent.BlockingOperation; import com.datastax.oss.driver.internal.core.util.concurrent.CompletableFutures; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; -import java.io.InputStream; import java.net.InetSocketAddress; -import java.net.MalformedURLException; -import java.net.URL; -import java.nio.file.Path; -import java.nio.file.Paths; import java.util.Collection; import java.util.Collections; import java.util.HashSet; @@ -73,7 +64,6 @@ import java.util.Map; import java.util.Set; import java.util.UUID; -import java.util.concurrent.Callable; import java.util.concurrent.CompletionStage; import java.util.function.Predicate; import javax.net.ssl.SSLContext; @@ -92,8 +82,6 @@ @NotThreadSafe public abstract class SessionBuilder { - public static final String ASTRA_PAYLOAD_KEY = "traceparent"; - private static final Logger LOG = LoggerFactory.getLogger(SessionBuilder.class); @SuppressWarnings("unchecked") @@ -102,11 +90,8 @@ public abstract class SessionBuilder { protected DriverConfigLoader configLoader; protected Set programmaticContactPoints = new HashSet<>(); protected CqlIdentifier keyspace; - protected Callable cloudConfigInputStream; protected ProgrammaticArguments.Builder programmaticArgumentsBuilder = ProgrammaticArguments.builder(); - private boolean programmaticSslFactory = false; - private boolean programmaticLocalDatacenter = false; /** * Sets the configuration loader to use. @@ -370,32 +355,6 @@ public SelfT withAuthCredentials(@NonNull String username, @NonNull String passw return withAuthProvider(new ProgrammaticPlainTextAuthProvider(username, password)); } - /** - * Configures the session to use DSE plaintext authentication with the given username and - * password, and perform proxy authentication with the given authorization id. - * - *

This feature is only available in DataStax Enterprise. If connecting to Apache Cassandra, - * the authorization id will be ignored; it is recommended to use {@link - * #withAuthCredentials(String, String)} instead. - * - *

This methods calls {@link #withAuthProvider(AuthProvider)} to register a special provider - * implementation. Therefore calling it overrides the configuration (that is, the {@code - * advanced.auth-provider.class} option will be ignored). - * - *

Note that this approach holds the credentials in clear text in memory, which makes them - * vulnerable to an attacker who is able to perform memory dumps. If this is not acceptable for - * you, consider writing your own {@link AuthProvider} implementation (the internal class {@code - * PlainTextAuthProviderBase} is a good starting point), and providing it either with {@link - * #withAuthProvider(AuthProvider)} or via the configuration ({@code - * advanced.auth-provider.class}). - */ - @NonNull - public SelfT withAuthCredentials( - @NonNull String username, @NonNull String password, @NonNull String authorizationId) { - return withAuthProvider( - new ProgrammaticPlainTextAuthProvider(username, password, authorizationId)); - } - /** * @deprecated this method only exists to ease the transition from driver 3, it is an alias for * {@link #withAuthCredentials(String, String)}. @@ -406,17 +365,6 @@ public SelfT withCredentials(@NonNull String username, @NonNull String password) return withAuthCredentials(username, password); } - /** - * @deprecated this method only exists to ease the transition from driver 3, it is an alias for - * {@link #withAuthCredentials(String, String,String)}. - */ - @Deprecated - @NonNull - public SelfT withCredentials( - @NonNull String username, @NonNull String password, @NonNull String authorizationId) { - return withAuthCredentials(username, password, authorizationId); - } - /** * Registers an SSL engine factory for the session. * @@ -427,7 +375,6 @@ public SelfT withCredentials( */ @NonNull public SelfT withSslEngineFactory(@Nullable SslEngineFactory sslEngineFactory) { - this.programmaticSslFactory = true; this.programmaticArgumentsBuilder.withSslEngineFactory(sslEngineFactory); return self; } @@ -465,7 +412,6 @@ public SelfT withSslContext(@Nullable SSLContext sslContext) { * if you use a third-party implementation, refer to their documentation. */ public SelfT withLocalDatacenter(@NonNull String profileName, @NonNull String localDatacenter) { - this.programmaticLocalDatacenter = true; this.programmaticArgumentsBuilder.withLocalDatacenter(profileName, localDatacenter); return self; } @@ -647,31 +593,6 @@ public SelfT withClassLoader(@Nullable ClassLoader classLoader) { return self; } - /** - * Configures this SessionBuilder for Cloud deployments by retrieving connection information from - * the provided {@link Path}. - * - *

To connect to a Cloud database, you must first download the secure database bundle from the - * DataStax Astra console that contains the connection information, then instruct the driver to - * read its contents using either this method or one if its variants. - * - *

For more information, please refer to the DataStax Astra documentation. - * - * @param cloudConfigPath Path to the secure connect bundle zip file. - * @see #withCloudSecureConnectBundle(URL) - * @see #withCloudSecureConnectBundle(InputStream) - */ - @NonNull - public SelfT withCloudSecureConnectBundle(@NonNull Path cloudConfigPath) { - try { - URL cloudConfigUrl = cloudConfigPath.toAbsolutePath().normalize().toUri().toURL(); - this.cloudConfigInputStream = cloudConfigUrl::openStream; - } catch (MalformedURLException e) { - throw new IllegalArgumentException("Incorrect format of cloudConfigPath", e); - } - return self; - } - /** * Registers a CodecRegistry to use for the session. * @@ -684,72 +605,6 @@ public SelfT withCodecRegistry(@Nullable MutableCodecRegistry codecRegistry) { return self; } - /** - * Configures this SessionBuilder for Cloud deployments by retrieving connection information from - * the provided {@link URL}. - * - *

To connect to a Cloud database, you must first download the secure database bundle from the - * DataStax Astra console that contains the connection information, then instruct the driver to - * read its contents using either this method or one if its variants. - * - *

For more information, please refer to the DataStax Astra documentation. - * - * @param cloudConfigUrl URL to the secure connect bundle zip file. - * @see #withCloudSecureConnectBundle(Path) - * @see #withCloudSecureConnectBundle(InputStream) - */ - @NonNull - public SelfT withCloudSecureConnectBundle(@NonNull URL cloudConfigUrl) { - this.cloudConfigInputStream = cloudConfigUrl::openStream; - return self; - } - - /** - * Configures this SessionBuilder for Cloud deployments by retrieving connection information from - * the provided {@link InputStream}. - * - *

To connect to a Cloud database, you must first download the secure database bundle from the - * DataStax Astra console that contains the connection information, then instruct the driver to - * read its contents using either this method or one if its variants. - * - *

For more information, please refer to the DataStax Astra documentation. - * - *

Note that the provided stream will be consumed and closed when either {@link - * #build()} or {@link #buildAsync()} are called; attempting to reuse it afterwards will result in - * an error being thrown. - * - * @param cloudConfigInputStream A stream containing the secure connect bundle zip file. - * @see #withCloudSecureConnectBundle(Path) - * @see #withCloudSecureConnectBundle(URL) - */ - @NonNull - public SelfT withCloudSecureConnectBundle(@NonNull InputStream cloudConfigInputStream) { - this.cloudConfigInputStream = () -> cloudConfigInputStream; - return self; - } - - /** - * Configures this SessionBuilder to use the provided Cloud proxy endpoint. - * - *

Normally, this method should not be called directly; the normal and easiest way to configure - * the driver for Cloud deployments is through a {@linkplain #withCloudSecureConnectBundle(URL) - * secure connect bundle}. - * - *

Setting this option to any non-null address will make the driver use a special topology - * monitor tailored for Cloud deployments. This topology monitor assumes that the target cluster - * should be contacted through the proxy specified here, using SNI routing. - * - *

For more information, please refer to the DataStax Astra documentation. - * - * @param cloudProxyAddress The address of the Cloud proxy to use. - * @see Server Name Indication - */ - @NonNull - public SelfT withCloudProxyAddress(@Nullable InetSocketAddress cloudProxyAddress) { - this.programmaticArgumentsBuilder.withCloudProxyAddress(cloudProxyAddress); - return self; - } - /** * Configures this session to use client routes for cloud private-endpoint deployments. * @@ -790,9 +645,8 @@ public SelfT withClientRoutesConfig(@Nullable ClientRoutesConfig clientRoutesCon * A unique identifier for the created session. * *

It will be sent in the {@code STARTUP} protocol message, under the key {@code CLIENT_ID}, - * for each new connection established by the driver. Currently, this information is used by - * Insights monitoring (if the target cluster does not support Insights, the entry will be ignored - * by the server). + * for each new connection established by the driver. Servers that do not recognize this option + * ignore it. * *

If you don't call this method, the driver will generate an identifier with {@link * Uuids#random()}. @@ -807,9 +661,8 @@ public SelfT withClientId(@Nullable UUID clientId) { * The name of the application using the created session. * *

It will be sent in the {@code STARTUP} protocol message, under the key {@code - * APPLICATION_NAME}, for each new connection established by the driver. Currently, this - * information is used by Insights monitoring (if the target cluster does not support Insights, - * the entry will be ignored by the server). + * APPLICATION_NAME}, for each new connection established by the driver. Servers that do not + * recognize this option ignore it. * *

This can also be defined in the driver configuration with the option {@code * basic.application.name}; if you specify both, this method takes precedence and the @@ -826,9 +679,8 @@ public SelfT withApplicationName(@Nullable String applicationName) { * The version of the application using the created session. * *

It will be sent in the {@code STARTUP} protocol message, under the key {@code - * APPLICATION_VERSION}, for each new connection established by the driver. Currently, this - * information is used by Insights monitoring (if the target cluster does not support Insights, - * the entry will be ignored by the server). + * APPLICATION_VERSION}, for each new connection established by the driver. Servers that do not + * recognize this option ignore it. * *

This can also be defined in the driver configuration with the option {@code * basic.application.version}; if you specify both, this method takes precedence and the @@ -910,52 +762,8 @@ protected final CompletionStage buildDefaultSessionAsync() { : defaultConfigLoader(programmaticArguments.getClassLoader()); DriverExecutionProfile defaultConfig = configLoader.getInitialConfig().getDefaultProfile(); - if (cloudConfigInputStream == null) { - String configUrlString = - defaultConfig.getString(DefaultDriverOption.CLOUD_SECURE_CONNECT_BUNDLE, null); - if (configUrlString != null) { - cloudConfigInputStream = () -> getURL(configUrlString).openStream(); - } - } List configContactPoints = defaultConfig.getStringList(DefaultDriverOption.CONTACT_POINTS, Collections.emptyList()); - if (cloudConfigInputStream != null) { - // override request id generator, unless user has already set it - if (programmaticArguments.getRequestIdGenerator() == null) { - programmaticArgumentsBuilder.withRequestIdGenerator( - new W3CContextRequestIdGenerator(ASTRA_PAYLOAD_KEY)); - LOG.debug( - "A secure connect bundle is provided, using W3CContextRequestIdGenerator as request ID generator."); - } - if (!programmaticContactPoints.isEmpty() || !configContactPoints.isEmpty()) { - LOG.info( - "Both a secure connect bundle and contact points were provided. These are mutually exclusive. The contact points from the secure bundle will have priority."); - // clear the contact points provided in the setting file and via addContactPoints - configContactPoints = Collections.emptyList(); - programmaticContactPoints = new HashSet<>(); - } - - if (programmaticSslFactory - || defaultConfig.isDefined(DefaultDriverOption.SSL_ENGINE_FACTORY_CLASS)) { - LOG.info( - "Both a secure connect bundle and SSL options were provided. They are mutually exclusive. The SSL options from the secure bundle will have priority."); - } - CloudConfig cloudConfig = - new CloudConfigFactory().createCloudConfig(cloudConfigInputStream.call()); - addContactEndPoints(cloudConfig.getEndPoints()); - - boolean localDataCenterDefined = - anyProfileHasDatacenterDefined(configLoader.getInitialConfig()); - if (programmaticLocalDatacenter || localDataCenterDefined) { - LOG.info( - "Both a secure connect bundle and a local datacenter were provided. They are mutually exclusive. The local datacenter from the secure bundle will have priority."); - programmaticArgumentsBuilder.clearDatacenters(); - } - withLocalDatacenter(cloudConfig.getLocalDatacenter()); - withSslEngineFactory(cloudConfig.getSslEngineFactory()); - withCloudProxyAddress(cloudConfig.getProxyAddress()); - programmaticArguments = programmaticArgumentsBuilder.build(); - } boolean resolveAddresses = defaultConfig.getBoolean(DefaultDriverOption.RESOLVE_CONTACT_POINTS, false); @@ -980,36 +788,6 @@ protected final CompletionStage buildDefaultSessionAsync() { } } - private boolean anyProfileHasDatacenterDefined(DriverConfig driverConfig) { - for (DriverExecutionProfile driverExecutionProfile : driverConfig.getProfiles().values()) { - if (driverExecutionProfile.isDefined(DefaultDriverOption.LOAD_BALANCING_LOCAL_DATACENTER)) { - return true; - } - } - return false; - } - - /** - * Returns URL based on the configUrl setting. If the configUrl has no protocol provided, the - * method will fallback to file:// protocol and return URL that has file protocol specified. - * - * @param configUrl url to config secure bundle - * @return URL with file protocol if there was not explicit protocol provided in the configUrl - * setting - */ - private URL getURL(String configUrl) throws MalformedURLException { - try { - return new URL(configUrl); - } catch (MalformedURLException e1) { - try { - return Paths.get(configUrl).toAbsolutePath().normalize().toUri().toURL(); - } catch (MalformedURLException e2) { - e2.addSuppressed(e1); - throw e2; - } - } - } - /** * This must return an instance of {@code InternalDriverContext} (it's not expressed * directly in the signature to avoid leaking that type through the protected API). diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/DefaultProtocolVersionRegistry.java b/core/src/main/java/com/datastax/oss/driver/internal/core/DefaultProtocolVersionRegistry.java index 80850e8e95a..9899af80199 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/DefaultProtocolVersionRegistry.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/DefaultProtocolVersionRegistry.java @@ -1,11 +1,11 @@ /* * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file + * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file + * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at + * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -17,54 +17,28 @@ */ package com.datastax.oss.driver.internal.core; -import com.datastax.dse.driver.api.core.DseProtocolVersion; -import com.datastax.dse.driver.api.core.metadata.DseNodeProperties; -import com.datastax.dse.driver.internal.core.DseProtocolFeature; import com.datastax.oss.driver.api.core.DefaultProtocolVersion; import com.datastax.oss.driver.api.core.ProtocolVersion; import com.datastax.oss.driver.api.core.UnsupportedProtocolVersionException; import com.datastax.oss.driver.api.core.Version; import com.datastax.oss.driver.api.core.metadata.Node; -import com.datastax.oss.driver.shaded.guava.common.annotations.VisibleForTesting; import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; import java.util.Collection; import java.util.LinkedHashSet; import java.util.List; -import java.util.Objects; import java.util.Optional; import java.util.Set; import net.jcip.annotations.ThreadSafe; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -/** - * Built-in implementation of the protocol version registry, supports all Cassandra and DSE - * versions. - */ +/** Built-in implementation of the protocol version registry. */ @ThreadSafe public class DefaultProtocolVersionRegistry implements ProtocolVersionRegistry { private static final Logger LOG = LoggerFactory.getLogger(DefaultProtocolVersionRegistry.class); - private static final List allVersions = - ImmutableList.builder() - .add(DefaultProtocolVersion.values()) - .add(DseProtocolVersion.values()) - .build(); - - @VisibleForTesting - static final Version DSE_4_7_0 = Objects.requireNonNull(Version.parse("4.7.0")); - - @VisibleForTesting - static final Version DSE_5_0_0 = Objects.requireNonNull(Version.parse("5.0.0")); - - @VisibleForTesting - static final Version DSE_5_1_0 = Objects.requireNonNull(Version.parse("5.1.0")); - - @VisibleForTesting - static final Version DSE_6_0_0 = Objects.requireNonNull(Version.parse("6.0.0")); - - @VisibleForTesting - static final Version DSE_7_0_0 = Objects.requireNonNull(Version.parse("7.0.0")); + private static final List ALL_VERSIONS = + ImmutableList.copyOf(DefaultProtocolVersion.values()); private final String logPrefix; @@ -76,39 +50,30 @@ public DefaultProtocolVersionRegistry(String logPrefix) { public ProtocolVersion fromName(String name) { try { return DefaultProtocolVersion.valueOf(name); - } catch (IllegalArgumentException noOssVersion) { - try { - return DseProtocolVersion.valueOf(name); - } catch (IllegalArgumentException noDseVersion) { - throw new IllegalArgumentException("Unknown protocol version name: " + name); - } + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Unknown protocol version name: " + name); } } @Override public ProtocolVersion highestNonBeta() { - ProtocolVersion highest = allVersions.get(allVersions.size() - 1); - if (!highest.isBeta()) { - return highest; - } else { - return downgrade(highest) - .orElseThrow(() -> new AssertionError("There should be at least one non-beta version")); - } + ProtocolVersion highest = ALL_VERSIONS.get(ALL_VERSIONS.size() - 1); + return highest.isBeta() + ? downgrade(highest) + .orElseThrow(() -> new AssertionError("There should be at least one non-beta version")) + : highest; } @Override public Optional downgrade(ProtocolVersion version) { - int index = allVersions.indexOf(version); + int index = ALL_VERSIONS.indexOf(version); if (index < 0) { - // This method is called with a value obtained from fromName, so this should never happen throw new AssertionError(version + " is not a known version"); } else if (index == 0) { return Optional.empty(); - } else { - ProtocolVersion previousVersion = allVersions.get(index - 1); - // Beta versions are skipped during negotiation - return previousVersion.isBeta() ? downgrade(previousVersion) : Optional.of(previousVersion); } + ProtocolVersion previousVersion = ALL_VERSIONS.get(index - 1); + return previousVersion.isBeta() ? downgrade(previousVersion) : Optional.of(previousVersion); } @Override @@ -117,96 +82,54 @@ public ProtocolVersion highestCommon(Collection nodes) { throw new IllegalArgumentException("Expected at least one node"); } - // Start with all non-beta versions (beta versions are always forced, and we don't call this - // method if the version was forced). Set candidates = new LinkedHashSet<>(); - for (ProtocolVersion version : allVersions) { + for (ProtocolVersion version : ALL_VERSIONS) { if (!version.isBeta()) { candidates.add(version); } } - // Keep an unfiltered copy in case we need to throw an exception below ImmutableList initialCandidates = ImmutableList.copyOf(candidates); - // For each node, remove the versions it doesn't support for (Node node : nodes) { - - // We can't trust the Cassandra version reported by DSE to infer the maximum OSS protocol - // supported. For example DSE 6 reports release_version 4.0-SNAPSHOT, but only supports OSS - // protocol v4 (while Cassandra 4 will support v5). So we treat DSE separately. - Version dseVersion = (Version) node.getExtras().get(DseNodeProperties.DSE_VERSION); - if (dseVersion != null) { - LOG.debug("[{}] Node {} reports DSE version {}", logPrefix, node.getEndPoint(), dseVersion); - dseVersion = dseVersion.nextStable(); - if (dseVersion.compareTo(DSE_4_7_0) < 0) { - throw new UnsupportedProtocolVersionException( - node.getEndPoint(), - String.format( - "Node %s reports DSE version %s, " - + "but the driver only supports 4.7.0 and above", - node.getEndPoint(), dseVersion), - initialCandidates); - } else if (dseVersion.compareTo(DSE_5_0_0) < 0) { - // DSE 4.7.x, 4.8.x - removeHigherThan(DefaultProtocolVersion.V3, null, candidates); - } else if (dseVersion.compareTo(DSE_5_1_0) < 0) { - // DSE 5.0 - removeHigherThan(DefaultProtocolVersion.V4, null, candidates); - } else if (dseVersion.compareTo(DSE_6_0_0) < 0) { - // DSE 5.1 - removeHigherThan(DefaultProtocolVersion.V4, DseProtocolVersion.DSE_V1, candidates); - } else if (dseVersion.compareTo(DSE_7_0_0) < 0) { - // DSE 6 - removeHigherThan(DefaultProtocolVersion.V4, DseProtocolVersion.DSE_V2, candidates); - } else { - // DSE 7.0 - removeHigherThan(DefaultProtocolVersion.V5, DseProtocolVersion.DSE_V2, candidates); - } - } else { // not DSE - Version cassandraVersion = node.getCassandraVersion(); - if (cassandraVersion == null) { - LOG.warn( - "[{}] Node {} reports neither DSE version nor Cassandra version, " - + "ignoring it from optimal protocol version computation", - logPrefix, - node.getEndPoint()); - continue; - } - cassandraVersion = cassandraVersion.nextStable(); - LOG.debug( - "[{}] Node {} reports Cassandra version {}", + Version cassandraVersion = node.getCassandraVersion(); + if (cassandraVersion == null) { + LOG.warn( + "[{}] Node {} does not report a Cassandra version, " + + "ignoring it from optimal protocol version computation", logPrefix, + node.getEndPoint()); + continue; + } + cassandraVersion = cassandraVersion.nextStable(); + LOG.debug( + "[{}] Node {} reports Cassandra version {}", + logPrefix, + node.getEndPoint(), + cassandraVersion); + if (cassandraVersion.compareTo(Version.V2_1_0) < 0) { + throw new UnsupportedProtocolVersionException( node.getEndPoint(), - cassandraVersion); - if (cassandraVersion.compareTo(Version.V2_1_0) < 0) { - throw new UnsupportedProtocolVersionException( - node.getEndPoint(), - String.format( - "Node %s reports Cassandra version %s, " - + "but the driver only supports 2.1.0 and above", - node.getEndPoint(), cassandraVersion), - ImmutableList.of(DefaultProtocolVersion.V3, DefaultProtocolVersion.V4)); - } else if (cassandraVersion.compareTo(Version.V2_2_0) < 0) { - // 2.1.0 - removeHigherThan(DefaultProtocolVersion.V3, null, candidates); - } else if (cassandraVersion.compareTo(Version.V4_0_0) < 0) { - // 2.2, 3.x - removeHigherThan(DefaultProtocolVersion.V4, null, candidates); - } else { - // 4.0 - removeHigherThan(DefaultProtocolVersion.V5, null, candidates); - } + String.format( + "Node %s reports Cassandra version %s, " + + "but the driver only supports 2.1.0 and above", + node.getEndPoint(), cassandraVersion), + ImmutableList.of(DefaultProtocolVersion.V3, DefaultProtocolVersion.V4)); + } else if (cassandraVersion.compareTo(Version.V2_2_0) < 0) { + removeHigherThan(DefaultProtocolVersion.V3, candidates); + } else if (cassandraVersion.compareTo(Version.V4_0_0) < 0) { + removeHigherThan(DefaultProtocolVersion.V4, candidates); + } else { + removeHigherThan(DefaultProtocolVersion.V5, candidates); } } - // If we have versions left, return the highest one ProtocolVersion max = null; for (ProtocolVersion candidate : candidates) { if (max == null || max.getCode() < candidate.getCode()) { max = candidate; } } - if (max == null) { // Note: with the current algorithm, this never happens + if (max == null) { throw new UnsupportedProtocolVersionException( null, String.format( @@ -214,26 +137,15 @@ public ProtocolVersion highestCommon(Collection nodes) { + "enable DEBUG logs for '%s' for more details", LOG.getName()), initialCandidates); - } else { - return max; } + return max; } - // Removes all versions strictly higher than the given versions from candidates. A null - // maxDseVersion means "remove all DSE versions". private void removeHigherThan( - DefaultProtocolVersion maxOssVersion, - DseProtocolVersion maxDseVersion, - Set candidates) { - for (DefaultProtocolVersion ossVersion : DefaultProtocolVersion.values()) { - if (ossVersion.compareTo(maxOssVersion) > 0 && candidates.remove(ossVersion)) { - LOG.debug("[{}] Excluding protocol {}", logPrefix, ossVersion); - } - } - for (DseProtocolVersion dseVersion : DseProtocolVersion.values()) { - if ((maxDseVersion == null || dseVersion.compareTo(maxDseVersion) > 0) - && candidates.remove(dseVersion)) { - LOG.debug("[{}] Excluding protocol {}", logPrefix, dseVersion); + DefaultProtocolVersion maxVersion, Set candidates) { + for (DefaultProtocolVersion version : DefaultProtocolVersion.values()) { + if (version.compareTo(maxVersion) > 0 && candidates.remove(version)) { + LOG.debug("[{}] Excluding protocol {}", logPrefix, version); } } } @@ -244,23 +156,12 @@ public boolean supports(ProtocolVersion version, ProtocolFeature feature) { if (DefaultProtocolFeature.SMALLINT_AND_TINYINT_TYPES.equals(feature) || DefaultProtocolFeature.DATE_TYPE.equals(feature) || DefaultProtocolFeature.UNSET_BOUND_VALUES.equals(feature)) { - // All DSE versions and all OSS V4+ return DefaultProtocolVersion.V4.getCode() <= code; - } else if (DefaultProtocolFeature.PER_REQUEST_KEYSPACE.equals(feature)) { - // Only DSE_V2+ and OSS V5+ - return (DefaultProtocolVersion.V5.getCode() <= code - && code < DseProtocolVersion.DSE_V1.getCode()) - || DseProtocolVersion.DSE_V2.getCode() <= code; - } else if (DefaultProtocolFeature.NOW_IN_SECONDS.equals(feature) + } else if (DefaultProtocolFeature.PER_REQUEST_KEYSPACE.equals(feature) + || DefaultProtocolFeature.NOW_IN_SECONDS.equals(feature) || DefaultProtocolFeature.MODERN_FRAMING.equals(feature)) { - // OSS only, V5+ - return DefaultProtocolVersion.V5.getCode() <= code - && code < DseProtocolVersion.DSE_V1.getCode(); - } else if (DseProtocolFeature.CONTINUOUS_PAGING.equals(feature)) { - // All DSE versions - return DseProtocolVersion.DSE_V1.getCode() <= code; - } else { - throw new IllegalArgumentException("Unhandled protocol feature: " + feature); + return DefaultProtocolVersion.V5.getCode() <= code; } + throw new IllegalArgumentException("Unhandled protocol feature: " + feature); } } diff --git a/core/src/main/java/com/datastax/dse/driver/internal/core/auth/AuthUtils.java b/core/src/main/java/com/datastax/oss/driver/internal/core/auth/AuthUtils.java similarity index 57% rename from core/src/main/java/com/datastax/dse/driver/internal/core/auth/AuthUtils.java rename to core/src/main/java/com/datastax/oss/driver/internal/core/auth/AuthUtils.java index 38f1644bcb7..c6a25c63517 100644 --- a/core/src/main/java/com/datastax/dse/driver/internal/core/auth/AuthUtils.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/auth/AuthUtils.java @@ -1,11 +1,11 @@ /* * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file + * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file + * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at + * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -15,7 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.datastax.dse.driver.internal.core.auth; +package com.datastax.oss.driver.internal.core.auth; import com.datastax.oss.driver.api.core.auth.AuthenticationException; import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; @@ -25,15 +25,7 @@ import java.util.List; public class AuthUtils { - /** - * Utility function that checks for the existence of settings and throws an exception if they - * aren't present - * - * @param config Current working driver configuration - * @param authenticatorName name of authenticator for logging purposes - * @param endPoint the host we are attempting to authenticate to - * @param options a list of DriverOptions to check to see if they are present - */ + public static void validateConfigPresent( DriverExecutionProfile config, String authenticatorName, @@ -41,18 +33,19 @@ public static void validateConfigPresent( DriverOption... options) { List missingOptions = new ArrayList<>(); for (DriverOption option : options) { - if (!config.isDefined(option)) { missingOptions.add(option); } - if (missingOptions.size() > 0) { - String message = - "Missing required configuration options for authenticator " + authenticatorName + ":"; - for (DriverOption missingOption : missingOptions) { - message = message + " " + missingOption.getPath(); - } - throw new AuthenticationException(endPoint, message); + } + if (!missingOptions.isEmpty()) { + StringBuilder message = + new StringBuilder("Missing required configuration options for authenticator ") + .append(authenticatorName) + .append(':'); + for (DriverOption missingOption : missingOptions) { + message.append(' ').append(missingOption.getPath()); } + throw new AuthenticationException(endPoint, message.toString()); } } } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/auth/PlainTextAuthProvider.java b/core/src/main/java/com/datastax/oss/driver/internal/core/auth/PlainTextAuthProvider.java index f2dfdf14171..3a6d42410e0 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/auth/PlainTextAuthProvider.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/auth/PlainTextAuthProvider.java @@ -17,8 +17,6 @@ */ package com.datastax.oss.driver.internal.core.auth; -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.dse.driver.internal.core.auth.AuthUtils; import com.datastax.oss.driver.api.core.auth.PlainTextAuthProviderBase; import com.datastax.oss.driver.api.core.config.DefaultDriverOption; import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; @@ -40,10 +38,6 @@ * class = com.datastax.driver.api.core.auth.PlainTextAuthProvider * username = cassandra * password = cassandra - * - * // If connecting to DataStax Enterprise, this additional option allows proxy authentication - * // (login as another user or role) - * authorization-id = userOrRole * } * } * @@ -77,11 +71,8 @@ protected Credentials getCredentials( DefaultDriverOption.AUTH_PROVIDER_USER_NAME, DefaultDriverOption.AUTH_PROVIDER_PASSWORD); - String authorizationId = config.getString(DseDriverOption.AUTH_PROVIDER_AUTHORIZATION_ID, ""); - assert authorizationId != null; // per the default above return new Credentials( config.getString(DefaultDriverOption.AUTH_PROVIDER_USER_NAME).toCharArray(), - config.getString(DefaultDriverOption.AUTH_PROVIDER_PASSWORD).toCharArray(), - authorizationId.toCharArray()); + config.getString(DefaultDriverOption.AUTH_PROVIDER_PASSWORD).toCharArray()); } } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/channel/ChannelFactory.java b/core/src/main/java/com/datastax/oss/driver/internal/core/channel/ChannelFactory.java index 35190afa3f4..d45def5515b 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/channel/ChannelFactory.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/channel/ChannelFactory.java @@ -23,11 +23,9 @@ */ package com.datastax.oss.driver.internal.core.channel; -import com.datastax.oss.driver.api.core.ConsistencyLevel; import com.datastax.oss.driver.api.core.ProtocolVersion; import com.datastax.oss.driver.api.core.UnsupportedProtocolVersionException; import com.datastax.oss.driver.api.core.config.DefaultDriverOption; -import com.datastax.oss.driver.api.core.config.DriverConfig; import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; import com.datastax.oss.driver.api.core.context.DriverContext; import com.datastax.oss.driver.api.core.metadata.EndPoint; @@ -35,7 +33,6 @@ import com.datastax.oss.driver.api.core.metadata.NodeShardingInfo; import com.datastax.oss.driver.api.core.metrics.DefaultNodeMetric; import com.datastax.oss.driver.api.core.metrics.DefaultSessionMetric; -import com.datastax.oss.driver.internal.core.config.typesafe.TypesafeDriverConfig; import com.datastax.oss.driver.internal.core.context.InternalDriverContext; import com.datastax.oss.driver.internal.core.context.NettyOptions; import com.datastax.oss.driver.internal.core.metadata.DefaultNode; @@ -46,7 +43,6 @@ import com.datastax.oss.driver.internal.core.protocol.FrameEncoder; import com.datastax.oss.driver.shaded.guava.common.annotations.VisibleForTesting; import com.datastax.oss.driver.shaded.guava.common.base.Preconditions; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; import com.datastax.oss.protocol.internal.ProtocolFeatures; import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; @@ -76,12 +72,6 @@ public class ChannelFactory { private static final Logger LOG = LoggerFactory.getLogger(ChannelFactory.class); - /** - * A value for {@link #productType} that indicates that we are connected to DataStax Cloud. This - * value matches the one defined at DSE DB server side at {@code ProductType.java}. - */ - private static final String DATASTAX_CLOUD_PRODUCT_TYPE = "DATASTAX_APOLLO"; - private static final AtomicBoolean LOGGED_ORPHAN_WARNING = new AtomicBoolean(); /** @@ -304,15 +294,6 @@ private void connect( ? productTypes.get(0) : UNKNOWN_PRODUCT_TYPE; ChannelFactory.this.productType = productType; - DriverConfig driverConfig = context.getConfig(); - if (driverConfig instanceof TypesafeDriverConfig - && productType.equals(DATASTAX_CLOUD_PRODUCT_TYPE)) { - ((TypesafeDriverConfig) driverConfig) - .overrideDefaults( - ImmutableMap.of( - DefaultDriverOption.REQUEST_CONSISTENCY, - ConsistencyLevel.LOCAL_QUORUM.name())); - } } resultFuture.complete(driverChannel); } else { diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/config/cloud/CloudConfig.java b/core/src/main/java/com/datastax/oss/driver/internal/core/config/cloud/CloudConfig.java deleted file mode 100644 index 1a1076e9d78..00000000000 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/config/cloud/CloudConfig.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.oss.driver.internal.core.config.cloud; - -import com.datastax.oss.driver.api.core.metadata.EndPoint; -import com.datastax.oss.driver.api.core.ssl.SslEngineFactory; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.net.InetSocketAddress; -import java.util.List; -import net.jcip.annotations.ThreadSafe; - -@ThreadSafe -public class CloudConfig { - - private final InetSocketAddress proxyAddress; - private final List endPoints; - private final String localDatacenter; - private final SslEngineFactory sslEngineFactory; - - CloudConfig( - @NonNull InetSocketAddress proxyAddress, - @NonNull List endPoints, - @NonNull String localDatacenter, - @NonNull SslEngineFactory sslEngineFactory) { - this.proxyAddress = proxyAddress; - this.endPoints = ImmutableList.copyOf(endPoints); - this.localDatacenter = localDatacenter; - this.sslEngineFactory = sslEngineFactory; - } - - @NonNull - public InetSocketAddress getProxyAddress() { - return proxyAddress; - } - - @NonNull - public List getEndPoints() { - return endPoints; - } - - @NonNull - public String getLocalDatacenter() { - return localDatacenter; - } - - @NonNull - public SslEngineFactory getSslEngineFactory() { - return sslEngineFactory; - } -} diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/config/cloud/CloudConfigFactory.java b/core/src/main/java/com/datastax/oss/driver/internal/core/config/cloud/CloudConfigFactory.java deleted file mode 100644 index 817b3263d25..00000000000 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/config/cloud/CloudConfigFactory.java +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.oss.driver.internal.core.config.cloud; - -import com.datastax.oss.driver.api.core.metadata.EndPoint; -import com.datastax.oss.driver.internal.core.metadata.SniEndPoint; -import com.datastax.oss.driver.internal.core.ssl.SniSslEngineFactory; -import com.datastax.oss.driver.shaded.guava.common.io.ByteStreams; -import com.datastax.oss.driver.shaded.guava.common.net.HostAndPort; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.ConnectException; -import java.net.InetSocketAddress; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.UnknownHostException; -import java.nio.charset.StandardCharsets; -import java.security.GeneralSecurityException; -import java.security.KeyStore; -import java.security.SecureRandom; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManagerFactory; -import net.jcip.annotations.ThreadSafe; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@ThreadSafe -public class CloudConfigFactory { - private static final Logger LOG = LoggerFactory.getLogger(CloudConfigFactory.class); - /** - * Creates a {@link CloudConfig} with information fetched from the specified Cloud configuration - * URL. - * - *

The target URL must point to a valid secure connect bundle archive in ZIP format. - * - * @param cloudConfigUrl the URL to fetch the Cloud configuration from; cannot be null. - * @throws IOException If the Cloud configuration cannot be read. - * @throws GeneralSecurityException If the Cloud SSL context cannot be created. - */ - @NonNull - public CloudConfig createCloudConfig(@NonNull URL cloudConfigUrl) - throws IOException, GeneralSecurityException { - Objects.requireNonNull(cloudConfigUrl, "cloudConfigUrl cannot be null"); - return createCloudConfig(cloudConfigUrl.openStream()); - } - - /** - * Creates a {@link CloudConfig} with information fetched from the specified {@link InputStream}. - * - *

The stream must contain a valid secure connect bundle archive in ZIP format. Note that the - * stream will be closed after a call to that method and cannot be used anymore. - * - * @param cloudConfig the stream to read the Cloud configuration from; cannot be null. - * @throws IOException If the Cloud configuration cannot be read. - * @throws GeneralSecurityException If the Cloud SSL context cannot be created. - */ - @NonNull - public CloudConfig createCloudConfig(@NonNull InputStream cloudConfig) - throws IOException, GeneralSecurityException { - Objects.requireNonNull(cloudConfig, "cloudConfig cannot be null"); - JsonNode configJson = null; - ByteArrayOutputStream keyStoreOutputStream = null; - ByteArrayOutputStream trustStoreOutputStream = null; - ObjectMapper mapper = new ObjectMapper().configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, false); - try (ZipInputStream zipInputStream = new ZipInputStream(cloudConfig)) { - ZipEntry entry; - while ((entry = zipInputStream.getNextEntry()) != null) { - String fileName = entry.getName(); - switch (fileName) { - case "config.json": - configJson = mapper.readTree(zipInputStream); - break; - case "identity.jks": - keyStoreOutputStream = new ByteArrayOutputStream(); - ByteStreams.copy(zipInputStream, keyStoreOutputStream); - break; - case "trustStore.jks": - trustStoreOutputStream = new ByteArrayOutputStream(); - ByteStreams.copy(zipInputStream, trustStoreOutputStream); - break; - } - } - } - if (configJson == null) { - throw new IllegalStateException("Invalid bundle: missing file config.json"); - } - if (keyStoreOutputStream == null) { - throw new IllegalStateException("Invalid bundle: missing file identity.jks"); - } - if (trustStoreOutputStream == null) { - throw new IllegalStateException("Invalid bundle: missing file trustStore.jks"); - } - char[] keyStorePassword = getKeyStorePassword(configJson); - char[] trustStorePassword = getTrustStorePassword(configJson); - ByteArrayInputStream keyStoreInputStream = - new ByteArrayInputStream(keyStoreOutputStream.toByteArray()); - ByteArrayInputStream trustStoreInputStream = - new ByteArrayInputStream(trustStoreOutputStream.toByteArray()); - SSLContext sslContext = - createSslContext( - keyStoreInputStream, keyStorePassword, trustStoreInputStream, trustStorePassword); - URL metadataServiceUrl = getMetadataServiceUrl(configJson); - JsonNode proxyMetadataJson; - try (BufferedReader proxyMetadata = fetchProxyMetadata(metadataServiceUrl, sslContext)) { - proxyMetadataJson = mapper.readTree(proxyMetadata); - } - InetSocketAddress sniProxyAddress = getSniProxyAddress(proxyMetadataJson); - List endPoints = getEndPoints(proxyMetadataJson, sniProxyAddress); - String localDatacenter = getLocalDatacenter(proxyMetadataJson); - SniSslEngineFactory sslEngineFactory = new SniSslEngineFactory(sslContext); - validateIfBundleContainsUsernamePassword(configJson); - return new CloudConfig(sniProxyAddress, endPoints, localDatacenter, sslEngineFactory); - } - - @NonNull - protected char[] getKeyStorePassword(JsonNode configFile) { - if (configFile.has("keyStorePassword")) { - return configFile.get("keyStorePassword").asText().toCharArray(); - } else { - throw new IllegalStateException("Invalid config.json: missing field keyStorePassword"); - } - } - - @NonNull - protected char[] getTrustStorePassword(JsonNode configFile) { - if (configFile.has("trustStorePassword")) { - return configFile.get("trustStorePassword").asText().toCharArray(); - } else { - throw new IllegalStateException("Invalid config.json: missing field trustStorePassword"); - } - } - - @NonNull - protected URL getMetadataServiceUrl(JsonNode configFile) throws MalformedURLException { - if (configFile.has("host")) { - String metadataServiceHost = configFile.get("host").asText(); - if (configFile.has("port")) { - int metadataServicePort = configFile.get("port").asInt(); - return new URL("https", metadataServiceHost, metadataServicePort, "/metadata"); - } else { - throw new IllegalStateException("Invalid config.json: missing field port"); - } - } else { - throw new IllegalStateException("Invalid config.json: missing field host"); - } - } - - protected void validateIfBundleContainsUsernamePassword(JsonNode configFile) { - if (configFile.has("username") || configFile.has("password")) { - LOG.info( - "The bundle contains config.json with username and/or password. Providing it in the bundle is deprecated and ignored."); - } - } - - @NonNull - protected SSLContext createSslContext( - @NonNull ByteArrayInputStream keyStoreInputStream, - @NonNull char[] keyStorePassword, - @NonNull ByteArrayInputStream trustStoreInputStream, - @NonNull char[] trustStorePassword) - throws IOException, GeneralSecurityException { - KeyManagerFactory kmf = createKeyManagerFactory(keyStoreInputStream, keyStorePassword); - TrustManagerFactory tmf = createTrustManagerFactory(trustStoreInputStream, trustStorePassword); - SSLContext sslContext = SSLContext.getInstance("SSL"); - sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom()); - return sslContext; - } - - @NonNull - protected KeyManagerFactory createKeyManagerFactory( - @NonNull InputStream keyStoreInputStream, @NonNull char[] keyStorePassword) - throws IOException, GeneralSecurityException { - KeyStore ks = KeyStore.getInstance("JKS"); - ks.load(keyStoreInputStream, keyStorePassword); - KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - kmf.init(ks, keyStorePassword); - Arrays.fill(keyStorePassword, (char) 0); - return kmf; - } - - @NonNull - protected TrustManagerFactory createTrustManagerFactory( - @NonNull InputStream trustStoreInputStream, @NonNull char[] trustStorePassword) - throws IOException, GeneralSecurityException { - KeyStore ts = KeyStore.getInstance("JKS"); - ts.load(trustStoreInputStream, trustStorePassword); - TrustManagerFactory tmf = - TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - tmf.init(ts); - Arrays.fill(trustStorePassword, (char) 0); - return tmf; - } - - @NonNull - protected BufferedReader fetchProxyMetadata( - @NonNull URL metadataServiceUrl, @NonNull SSLContext sslContext) throws IOException { - try { - HttpsURLConnection connection = (HttpsURLConnection) metadataServiceUrl.openConnection(); - connection.setSSLSocketFactory(sslContext.getSocketFactory()); - connection.setRequestMethod("GET"); - return new BufferedReader( - new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8)); - } catch (ConnectException e) { - throw new IllegalStateException( - "Unable to connect to cloud metadata service. Please make sure your cluster is not parked or terminated", - e); - } catch (UnknownHostException e) { - throw new IllegalStateException( - "Unable to resolve host for cloud metadata service. Please make sure your cluster is not terminated", - e); - } - } - - @NonNull - protected String getLocalDatacenter(@NonNull JsonNode proxyMetadata) { - JsonNode contactInfo = getContactInfo(proxyMetadata); - if (contactInfo.has("local_dc")) { - return contactInfo.get("local_dc").asText(); - } else { - throw new IllegalStateException("Invalid proxy metadata: missing field local_dc"); - } - } - - @NonNull - protected InetSocketAddress getSniProxyAddress(@NonNull JsonNode proxyMetadata) { - JsonNode contactInfo = getContactInfo(proxyMetadata); - if (contactInfo.has("sni_proxy_address")) { - HostAndPort sniProxyHostAndPort = - HostAndPort.fromString(contactInfo.get("sni_proxy_address").asText()); - if (!sniProxyHostAndPort.hasPort()) { - throw new IllegalStateException( - "Invalid proxy metadata: missing port from field sni_proxy_address"); - } - return InetSocketAddress.createUnresolved( - sniProxyHostAndPort.getHost(), sniProxyHostAndPort.getPort()); - } else { - throw new IllegalStateException("Invalid proxy metadata: missing field sni_proxy_address"); - } - } - - @NonNull - protected List getEndPoints( - @NonNull JsonNode proxyMetadata, @NonNull InetSocketAddress sniProxyAddress) { - JsonNode contactInfo = getContactInfo(proxyMetadata); - if (contactInfo.has("contact_points")) { - List endPoints = new ArrayList<>(); - JsonNode hostIdsJson = contactInfo.get("contact_points"); - for (int i = 0; i < hostIdsJson.size(); i++) { - endPoints.add(new SniEndPoint(sniProxyAddress, hostIdsJson.get(i).asText())); - } - return endPoints; - } else { - throw new IllegalStateException("Invalid proxy metadata: missing field contact_points"); - } - } - - @NonNull - protected JsonNode getContactInfo(@NonNull JsonNode proxyMetadata) { - if (proxyMetadata.has("contact_info")) { - return proxyMetadata.get("contact_info"); - } else { - throw new IllegalStateException("Invalid proxy metadata: missing field contact_info"); - } - } -} diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/context/DefaultDriverConfigReporter.java b/core/src/main/java/com/datastax/oss/driver/internal/core/context/DefaultDriverConfigReporter.java index f48d686573c..cbdb0718b76 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/context/DefaultDriverConfigReporter.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/context/DefaultDriverConfigReporter.java @@ -17,8 +17,6 @@ */ package com.datastax.oss.driver.internal.core.context; -import com.datastax.dse.driver.internal.core.loadbalancing.DseDcInferringLoadBalancingPolicy; -import com.datastax.dse.driver.internal.core.loadbalancing.DseLoadBalancingPolicy; import com.datastax.oss.driver.api.core.config.DefaultDriverOption; import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; import com.datastax.oss.driver.api.core.connection.ReconnectionPolicy; @@ -41,7 +39,6 @@ import com.datastax.oss.driver.internal.core.specex.NoSpeculativeExecutionPolicy; import com.datastax.oss.driver.internal.core.ssl.DefaultSslEngineFactory; import com.datastax.oss.driver.internal.core.ssl.JdkSslHandlerFactory; -import com.datastax.oss.driver.internal.core.ssl.SniSslEngineFactory; import com.datastax.oss.driver.internal.core.ssl.SslHandlerFactory; import com.datastax.oss.driver.internal.core.time.AtomicTimestampGenerator; import com.datastax.oss.driver.internal.core.time.ServerSideTimestampGenerator; @@ -684,19 +681,14 @@ private ObjectNode loadBalancingPolicy( // (not instanceof) so an actual user subclass of any of them still falls through to "custom". // // DcInferringLoadBalancingPolicy extends DefaultLoadBalancingPolicy, overriding only how the - // local DC is discovered; DseLoadBalancingPolicy/DseDcInferringLoadBalancingPolicy are - // deprecated, behavior-identical aliases of the two ("equivalent to DefaultLoadBalancingPolicy, - // which should now be used instead" per their own javadoc). All of them extend - // BasicLoadBalancingPolicy, from which they inherit an unconditional shuffle of the replica - // head + // local DC is discovered. Both extend BasicLoadBalancingPolicy, from which they inherit an + // unconditional shuffle of the replica head // and the same DC-failover option; only slow-replica avoidance differs, so it is resolved per // class below and the shared fields are written once. Class policyClass = policy.getClass(); boolean avoidsSlowReplicas; if (policyClass == DefaultLoadBalancingPolicy.class - || policyClass == DcInferringLoadBalancingPolicy.class - || policyClass == DseLoadBalancingPolicy.class - || policyClass == DseDcInferringLoadBalancingPolicy.class) { + || policyClass == DcInferringLoadBalancingPolicy.class) { // Off the running instance, not the profile: DefaultLoadBalancingPolicy latches this flag in // its constructor and never re-reads it, so after a configuration reload the profile can say // one thing while the policy keeps reordering (or not) according to the other. Same reason @@ -900,9 +892,7 @@ private NodeLocation nodeLocation(DriverExecutionProfile config, LoadBalancingPo private static boolean infersLocalDatacenter(LoadBalancingPolicy policy) { Class policyClass = policy.getClass(); return policyClass == DefaultLoadBalancingPolicy.class - || policyClass == DcInferringLoadBalancingPolicy.class - || policyClass == DseLoadBalancingPolicy.class - || policyClass == DseDcInferringLoadBalancingPolicy.class; + || policyClass == DcInferringLoadBalancingPolicy.class; } /** @@ -1137,10 +1127,6 @@ private static Optional hostnameValidation(@Nullable SslEngineFactory e } else if (engineFactory instanceof ProgrammaticSslEngineFactory) { return Optional.of( ((ProgrammaticSslEngineFactory) engineFactory).isHostnameValidationRequired()); - } else if (engineFactory instanceof SniSslEngineFactory) { - // No accessor to read: SniSslEngineFactory sets the "HTTPS" endpoint identification algorithm - // on every engine it builds, unconditionally. - return Optional.of(true); } return Optional.empty(); } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/context/DefaultDriverContext.java b/core/src/main/java/com/datastax/oss/driver/internal/core/context/DefaultDriverContext.java index e6323b6b84c..ab298ccde13 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/context/DefaultDriverContext.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/context/DefaultDriverContext.java @@ -19,12 +19,6 @@ import static com.datastax.oss.driver.internal.core.util.Dependency.JACKSON; -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.dse.driver.internal.core.InsightsClientLifecycleListener; -import com.datastax.dse.driver.internal.core.type.codec.DseTypeCodecsRegistrar; -import com.datastax.dse.protocol.internal.DseProtocolV1ClientCodecs; -import com.datastax.dse.protocol.internal.DseProtocolV2ClientCodecs; -import com.datastax.dse.protocol.internal.ProtocolV4ClientCodecsForDse; import com.datastax.oss.driver.api.core.ProtocolVersion; import com.datastax.oss.driver.api.core.addresstranslation.AddressTranslator; import com.datastax.oss.driver.api.core.auth.AuthProvider; @@ -62,7 +56,6 @@ import com.datastax.oss.driver.internal.core.config.typesafe.TypesafeDriverConfig; import com.datastax.oss.driver.internal.core.control.ControlConnection; import com.datastax.oss.driver.internal.core.metadata.ClientRoutesTopologyMonitor; -import com.datastax.oss.driver.internal.core.metadata.CloudTopologyMonitor; import com.datastax.oss.driver.internal.core.metadata.DefaultTopologyMonitor; import com.datastax.oss.driver.internal.core.metadata.LoadBalancingPolicyWrapper; import com.datastax.oss.driver.internal.core.metadata.MetadataManager; @@ -105,6 +98,7 @@ import com.datastax.oss.protocol.internal.FrameCodec; import com.datastax.oss.protocol.internal.PrimitiveCodec; import com.datastax.oss.protocol.internal.ProtocolV3ClientCodecs; +import com.datastax.oss.protocol.internal.ProtocolV4ClientCodecs; import com.datastax.oss.protocol.internal.ProtocolV5ClientCodecs; import com.datastax.oss.protocol.internal.ProtocolV6ClientCodecs; import com.datastax.oss.protocol.internal.SegmentCodec; @@ -114,7 +108,6 @@ import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import io.netty.buffer.ByteBuf; -import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -254,7 +247,6 @@ public class DefaultDriverContext implements InternalDriverContext { private final Map> nodeFiltersFromBuilder; private final Map nodeDistanceEvaluatorsFromBuilder; private final ClassLoader classLoader; - private final InetSocketAddress cloudProxyAddress; private final ClientRoutesConfig clientRoutesConfigFromBuilder; private final LazyReference requestLogFormatterRef = new LazyReference<>("requestLogFormatter", this::buildRequestLogFormatter, cycleDetector); @@ -262,9 +254,6 @@ public class DefaultDriverContext implements InternalDriverContext { private final String startupApplicationName; private final String startupApplicationVersion; private final Object metricRegistry; - // A stack trace captured in the constructor. Used to extract information about the client - // application. - private final StackTraceElement[] initStackTrace; public DefaultDriverContext( DriverConfigLoader configLoader, ProgrammaticArguments programmaticArguments) { @@ -315,19 +304,10 @@ public DefaultDriverContext( this.nodeFiltersFromBuilder = nodeFilters; this.nodeDistanceEvaluatorsFromBuilder = programmaticArguments.getNodeDistanceEvaluators(); this.classLoader = programmaticArguments.getClassLoader(); - this.cloudProxyAddress = programmaticArguments.getCloudProxyAddress(); this.clientRoutesConfigFromBuilder = programmaticArguments.getClientRoutesConfig(); this.startupClientId = programmaticArguments.getStartupClientId(); this.startupApplicationName = programmaticArguments.getStartupApplicationName(); this.startupApplicationVersion = programmaticArguments.getStartupApplicationVersion(); - StackTraceElement[] stackTrace; - try { - stackTrace = Thread.currentThread().getStackTrace(); - } catch (Exception ex) { - // ignore and use empty - stackTrace = new StackTraceElement[] {}; - } - this.initStackTrace = stackTrace; this.metricRegistry = programmaticArguments.getMetricRegistry(); } @@ -395,9 +375,8 @@ protected DriverConfigReporter buildDriverConfigReporter() { if (DefaultDependencyChecker.isPresent(JACKSON)) { return new DefaultDriverConfigReporter(this); } - // Logged unconditionally, unlike the Insights equivalent in #buildLifecycleListeners: reporting - // ships enabled, so someone who trimmed Jackson never opted out of it and would otherwise have - // no signal that it is off. + // Reporting ships enabled, so someone who trimmed Jackson never opted out of it and would + // otherwise have no signal that it is off. LOG.info( "Could not initialize driver configuration reporting; " + "this is normal if Jackson was explicitly excluded from classpath"); @@ -410,8 +389,7 @@ protected Map buildLoadBalancingPolicies() { DefaultDriverOption.LOAD_BALANCING_POLICY_CLASS, DefaultDriverOption.LOAD_BALANCING_POLICY, LoadBalancingPolicy.class, - "com.datastax.oss.driver.internal.core.loadbalancing", - "com.datastax.dse.driver.internal.core.loadbalancing"); + "com.datastax.oss.driver.internal.core.loadbalancing"); } protected Map buildRetryPolicies() { @@ -630,11 +608,9 @@ protected FrameCodec buildFrameCodec() { getPrimitiveCodec(), getCompressor(), new ProtocolV3ClientCodecs(), - new ProtocolV4ClientCodecsForDse(), + new ProtocolV4ClientCodecs(), new ProtocolV5ClientCodecs(), - new ProtocolV6ClientCodecs(), - new DseProtocolV1ClientCodecs(), - new DseProtocolV2ClientCodecs()); + new ProtocolV6ClientCodecs()); } protected SegmentCodec buildSegmentCodec() { @@ -677,9 +653,6 @@ protected TopologyMonitor buildTopologyMonitor() { ClientRoutesConfig clientRoutesConfig = resolveClientRoutesConfig(); validateClientRoutesConfiguration(clientRoutesConfig); - if (cloudProxyAddress != null) { - return new CloudTopologyMonitor(this, cloudProxyAddress); - } if (clientRoutesConfig != null) { return new ClientRoutesTopologyMonitor(this, clientRoutesConfig); } @@ -690,12 +663,6 @@ private void validateClientRoutesConfiguration(ClientRoutesConfig clientRoutesCo if (clientRoutesConfig == null) { return; } - if (cloudProxyAddress != null) { - throw new IllegalStateException( - "Both a secure connect bundle and client routes configuration were provided. " - + "They are mutually exclusive. Please use either a secure connect bundle OR " - + "client routes configuration, but not both."); - } DriverExecutionProfile defaultProfile = getConfig().getDefaultProfile(); if (defaultProfile.isDefined(DefaultDriverOption.ADDRESS_TRANSLATOR_CLASS)) { String className = defaultProfile.getString(DefaultDriverOption.ADDRESS_TRANSLATOR_CLASS); @@ -747,7 +714,6 @@ protected CodecRegistry buildCodecRegistry(ProgrammaticArguments arguments) { registry = new DefaultCodecRegistry(this.sessionName); } registry.register(arguments.getTypeCodecs()); - DseTypeCodecsRegistrar.registerDseCodecs(registry); return registry; } @@ -955,21 +921,11 @@ protected Optional buildAuthProvider(AuthProvider authProviderFrom this, DefaultDriverOption.AUTH_PROVIDER_CLASS, AuthProvider.class, - "com.datastax.oss.driver.internal.core.auth", - "com.datastax.dse.driver.internal.core.auth"); + "com.datastax.oss.driver.internal.core.auth"); } protected List buildLifecycleListeners() { - if (DefaultDependencyChecker.isPresent(JACKSON)) { - return Collections.singletonList(new InsightsClientLifecycleListener(this, initStackTrace)); - } else { - if (config.getDefaultProfile().getBoolean(DseDriverOption.MONITOR_REPORTING_ENABLED)) { - LOG.info( - "Could not initialize Insights monitoring; " - + "this is normal if Jackson was explicitly excluded from classpath"); - } - return Collections.emptyList(); - } + return Collections.emptyList(); } @NonNull diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/context/InternalDriverContext.java b/core/src/main/java/com/datastax/oss/driver/internal/core/context/InternalDriverContext.java index 87933b7385e..054b487239b 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/context/InternalDriverContext.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/context/InternalDriverContext.java @@ -187,8 +187,7 @@ public interface InternalDriverContext extends DriverContext { * A list of additional components to notify of session lifecycle events. * *

For historical reasons, this method has a default implementation that returns an empty list. - * The built-in {@link DefaultDriverContext} overrides it to plug in the Insights monitoring - * listener. Custom driver extensions might override this method to add their own components. + * Custom driver extensions might override this method to add their own components. * *

Note that the driver assumes that the returned list is constant; there is no way to add * listeners dynamically. diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/context/NoopDriverConfigReporter.java b/core/src/main/java/com/datastax/oss/driver/internal/core/context/NoopDriverConfigReporter.java index 213c3657585..cd95240c171 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/context/NoopDriverConfigReporter.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/context/NoopDriverConfigReporter.java @@ -27,8 +27,7 @@ *

Today that means Jackson is absent from the classpath: the driver declares it as a required * dependency but documents that it can be excluded (see {@code manual/core/integration}), and * {@link DefaultDriverConfigReporter} serializes the report with it. Substituting this - * implementation keeps that exclusion working, the same way {@code - * DefaultDriverContext#buildLifecycleListeners()} skips Insights monitoring. + * implementation keeps that exclusion working. * *

Deliberately free of any reference to Jackson, including in the signatures it inherits — a * single one would make loading this class fail for exactly the deployments it exists to diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/context/StartupOptionsBuilder.java b/core/src/main/java/com/datastax/oss/driver/internal/core/context/StartupOptionsBuilder.java index dd3a0307a79..7c04bafd19d 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/context/StartupOptionsBuilder.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/context/StartupOptionsBuilder.java @@ -17,7 +17,7 @@ */ package com.datastax.oss.driver.internal.core.context; -import com.datastax.dse.driver.api.core.config.DseDriverOption; +import com.datastax.oss.driver.api.core.config.DefaultDriverOption; import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; import com.datastax.oss.driver.api.core.session.Session; import com.datastax.oss.driver.api.core.uuid.Uuids; @@ -115,7 +115,7 @@ public Map build() { builder.put(DRIVER_NAME_KEY, getDriverName()).put(DRIVER_VERSION_KEY, getDriverVersion()); // Identifier of this session, sent on every connection so the server can group them. Not - // derived from the (user-settable, Insights-oriented) CLIENT_ID below, so that it is guaranteed + // derived from the user-settable CLIENT_ID below, so that it is guaranteed // unique per session as the grouping key requires. Generated lazily here rather than eagerly in // a field initializer, mirroring clientId; DefaultDriverContext builds the startup options // exactly once per session (LazyReference), which is what makes the value stable across all of @@ -125,19 +125,19 @@ public Map build() { } builder.put(SESSION_ID_KEY, sessionId.toString()); - // Add Insights entries, falling back to generation / config if no programmatic values provided: + // Add client and application metadata, falling back to configuration when needed: if (clientId == null) { clientId = Uuids.random(); } builder.put(CLIENT_ID_KEY, clientId.toString()); if (applicationName == null) { - applicationName = config.getString(DseDriverOption.APPLICATION_NAME, null); + applicationName = config.getString(DefaultDriverOption.APPLICATION_NAME, null); } if (applicationName != null) { builder.put(APPLICATION_NAME_KEY, applicationName); } if (applicationVersion == null) { - applicationVersion = config.getString(DseDriverOption.APPLICATION_VERSION, null); + applicationVersion = config.getString(DefaultDriverOption.APPLICATION_VERSION, null); } if (applicationVersion != null) { builder.put(APPLICATION_VERSION_KEY, applicationVersion); diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/CloudTopologyMonitor.java b/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/CloudTopologyMonitor.java deleted file mode 100644 index 021824a9b16..00000000000 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/CloudTopologyMonitor.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.oss.driver.internal.core.metadata; - -import com.datastax.oss.driver.api.core.metadata.EndPoint; -import com.datastax.oss.driver.internal.core.adminrequest.AdminRow; -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.net.InetSocketAddress; -import java.util.Objects; -import java.util.UUID; - -public class CloudTopologyMonitor extends DefaultTopologyMonitor { - - private final InetSocketAddress cloudProxyAddress; - - public CloudTopologyMonitor(InternalDriverContext context, InetSocketAddress cloudProxyAddress) { - super(context); - this.cloudProxyAddress = cloudProxyAddress; - } - - @NonNull - @Override - protected EndPoint buildNodeEndPoint( - @NonNull AdminRow row, - @Nullable InetSocketAddress broadcastRpcAddress, - @NonNull EndPoint localEndPoint) { - UUID hostId = Objects.requireNonNull(row.getUuid("host_id")); - return new SniEndPoint(cloudProxyAddress, hostId.toString()); - } -} diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/DefaultTopologyMonitor.java b/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/DefaultTopologyMonitor.java index 5a82bfe2c86..56270373dfc 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/DefaultTopologyMonitor.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/DefaultTopologyMonitor.java @@ -17,8 +17,6 @@ */ package com.datastax.oss.driver.internal.core.metadata; -import com.datastax.dse.driver.api.core.metadata.DseNodeProperties; -import com.datastax.oss.driver.api.core.Version; import com.datastax.oss.driver.api.core.config.DefaultDriverOption; import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; import com.datastax.oss.driver.api.core.metadata.EndPoint; @@ -51,7 +49,6 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; -import java.util.Set; import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; @@ -73,14 +70,13 @@ public class DefaultTopologyMonitor implements TopologyMonitor { // A few system.peers columns which get special handling below private static final String NATIVE_PORT = "native_port"; - private static final String NATIVE_TRANSPORT_PORT = "native_transport_port"; /** * The columns we actually read from {@code system.local}. Used to intersect with the full column * list returned by the first {@code SELECT *} response, so that subsequent projected queries only * fetch columns the driver uses. * - *

Includes DSE-specific columns; absent columns are silently ignored by the intersection step. + *

Absent columns are silently ignored by the intersection step. */ @VisibleForTesting static final ImmutableSet LOCAL_COLUMNS_OF_INTEREST = @@ -93,9 +89,6 @@ public class DefaultTopologyMonitor implements TopologyMonitor { "rpc_address", "rpc_port", "native_address", - "native_transport_address", - "native_transport_port", - "native_transport_port_ssl", // Node metadata "data_center", "rack", @@ -103,16 +96,7 @@ public class DefaultTopologyMonitor implements TopologyMonitor { "tokens", "partitioner", "host_id", - "schema_version", - // DSE-specific - "dse_version", - "graph", - "workload", - "workloads", - "server_id", - "storage_port", - "storage_port_ssl", - "jmx_port"); + "schema_version"); /** * The columns we actually read from {@code system.peers}. Mirrors {@link @@ -130,9 +114,6 @@ public class DefaultTopologyMonitor implements TopologyMonitor { "rpc_address", "rpc_port", "native_address", - "native_transport_address", - "native_transport_port", - "native_transport_port_ssl", // Node metadata "data_center", "rack", @@ -140,16 +121,7 @@ public class DefaultTopologyMonitor implements TopologyMonitor { "tokens", "partitioner", "host_id", - "schema_version", - // DSE-specific - "dse_version", - "graph", - "workload", - "workloads", - "server_id", - "storage_port", - "storage_port_ssl", - "jmx_port"); + "schema_version"); /** * The columns we actually read from {@code system.peers_v2} (Cassandra ≥ 4.0). Replaces {@code @@ -169,9 +141,6 @@ public class DefaultTopologyMonitor implements TopologyMonitor { "broadcast_address", "broadcast_port", "rpc_address", - "native_transport_address", - "native_transport_port", - "native_transport_port_ssl", // Node metadata "data_center", "rack", @@ -179,16 +148,7 @@ public class DefaultTopologyMonitor implements TopologyMonitor { "tokens", "partitioner", "host_id", - "schema_version", - // DSE-specific - "dse_version", - "graph", - "workload", - "workloads", - "server_id", - "storage_port", - "storage_port_ssl", - "jmx_port"); + "schema_version"); private final String logPrefix; protected final InternalDriverContext context; @@ -394,11 +354,7 @@ public CompletionStage> refreshNodeList() { if (t instanceof UnexpectedResponseException && ((UnexpectedResponseException) t).message instanceof Error) { Error error = (Error) ((UnexpectedResponseException) t).message; - if (error.code == ProtocolConstants.ErrorCode.INVALID - // Also downgrade on server error with a specific error message (DSE 6.0.0 to - // 6.0.2 with search enabled) - || (error.code == ProtocolConstants.ErrorCode.SERVER_ERROR - && error.message.contains("Unknown keyspace/cf pair (system.peers_v2)"))) { + if (error.code == ProtocolConstants.ErrorCode.INVALID) { this.isSchemaV2 = false; // We should not attempt this query in the future. CompletableFutures.completeFrom( query(channel, buildQuery(peersColumns, "system.peers")), peersQuery); @@ -586,41 +542,6 @@ protected DefaultNodeInfo.Builder nodeInfoBuilder( "host_id is null in system.local, node may still be bootstrapping")) .withSchemaVersion(row.getUuid("schema_version")); - // Handle DSE-specific columns, if present - String rawVersion = row.getString("dse_version"); - if (rawVersion != null) { - builder.withExtra(DseNodeProperties.DSE_VERSION, Version.parse(rawVersion)); - } - - ImmutableSet.Builder workloadsBuilder = ImmutableSet.builder(); - Boolean legacyGraph = row.getBoolean("graph"); // DSE 5.0 - if (legacyGraph != null && legacyGraph) { - workloadsBuilder.add("Graph"); - } - String legacyWorkload = row.getString("workload"); // DSE 5.0 (other than graph) - if (legacyWorkload != null) { - workloadsBuilder.add(legacyWorkload); - } - Set modernWorkloads = row.getSetOfString("workloads"); // DSE 5.1+ - if (modernWorkloads != null) { - workloadsBuilder.addAll(modernWorkloads); - } - ImmutableSet workloads = workloadsBuilder.build(); - if (!workloads.isEmpty()) { - builder.withExtra(DseNodeProperties.DSE_WORKLOADS, workloads); - } - - // Note: withExtra discards null values - builder - .withExtra(DseNodeProperties.SERVER_ID, row.getString("server_id")) - .withExtra(DseNodeProperties.NATIVE_TRANSPORT_PORT, row.getInteger("native_transport_port")) - .withExtra( - DseNodeProperties.NATIVE_TRANSPORT_PORT_SSL, - row.getInteger("native_transport_port_ssl")) - .withExtra(DseNodeProperties.STORAGE_PORT, row.getInteger("storage_port")) - .withExtra(DseNodeProperties.STORAGE_PORT_SSL, row.getInteger("storage_port_ssl")) - .withExtra(DseNodeProperties.JMX_PORT, row.getInteger("jmx_port")); - return builder; } @@ -731,9 +652,6 @@ protected InetSocketAddress getBroadcastRpcAddress( Iterators.forArray( // in system.peers_v2 (Cassandra >= 4.0) "native_address", - // DSE 6.8 introduced native_transport_address and native_transport_port for the - // listen address. - "native_transport_address", // in system.peers or system.local "rpc_address"); @@ -755,22 +673,12 @@ protected InetSocketAddress getBroadcastRpcAddress( Iterators.forArray( // in system.peers_v2 (Cassandra >= 4.0) NATIVE_PORT, - // DSE 6.8 introduced native_transport_address and native_transport_port for the - // listen address. - NATIVE_TRANSPORT_PORT, // system.local for Cassandra >= 4.0 "rpc_port"); while ((broadcastRpcPort == null || broadcastRpcPort == 0) && portCandidates.hasNext()) { - String colName = portCandidates.next(); - broadcastRpcPort = row.getInteger(colName); - // Support override for SSL port (if enabled) in DSE - if (NATIVE_TRANSPORT_PORT.equals(colName) && context.getSslEngineFactory().isPresent()) { - - String sslColName = colName + "_ssl"; - broadcastRpcPort = row.getInteger(sslColName); - } + broadcastRpcPort = row.getInteger(portCandidates.next()); } // use the default port if no port information was found in the row; // note that in rare situations, the default port might not be known, in which case we diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/SniEndPoint.java b/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/SniEndPoint.java deleted file mode 100644 index d1ab8eec98d..00000000000 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/SniEndPoint.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.oss.driver.internal.core.metadata; - -import com.datastax.oss.driver.api.core.metadata.EndPoint; -import com.datastax.oss.driver.shaded.guava.common.primitives.UnsignedBytes; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.UnknownHostException; -import java.util.Arrays; -import java.util.Comparator; -import java.util.Objects; -import java.util.concurrent.atomic.AtomicInteger; - -public class SniEndPoint implements EndPoint { - private static final AtomicInteger OFFSET = new AtomicInteger(); - - private final InetSocketAddress proxyAddress; - private final String serverName; - - /** - * @param proxyAddress the address of the proxy. If it is {@linkplain - * InetSocketAddress#isUnresolved() unresolved}, each call to {@link #resolve()} will - * re-resolve it, fetch all of its A-records, and if there are more than 1 pick one in a - * round-robin fashion. - * @param serverName the SNI server name. In the context of Cloud, this is the string - * representation of the host id. - */ - public SniEndPoint(InetSocketAddress proxyAddress, String serverName) { - this.proxyAddress = Objects.requireNonNull(proxyAddress, "SNI address cannot be null"); - this.serverName = Objects.requireNonNull(serverName, "SNI Server name cannot be null"); - } - - public String getServerName() { - return serverName; - } - - @NonNull - @Override - public InetSocketAddress resolve() { - try { - InetAddress[] aRecords = InetAddress.getAllByName(proxyAddress.getHostName()); - if (aRecords.length == 0) { - // Probably never happens, but the JDK docs don't explicitly say so - throw new IllegalArgumentException( - "Could not resolve proxy address " + proxyAddress.getHostName()); - } - // The order of the returned address is unspecified. Sort by IP to make sure we get a true - // round-robin - Arrays.sort(aRecords, IP_COMPARATOR); - int index = - (aRecords.length == 1) - ? 0 - : OFFSET.getAndUpdate(x -> x == Integer.MAX_VALUE ? 0 : x + 1) % aRecords.length; - return new InetSocketAddress(aRecords[index], proxyAddress.getPort()); - } catch (UnknownHostException e) { - throw new IllegalArgumentException( - "Could not resolve proxy address " + proxyAddress.getHostName(), e); - } - } - - @Override - public boolean equals(Object other) { - if (other == this) { - return true; - } else if (other instanceof SniEndPoint) { - SniEndPoint that = (SniEndPoint) other; - return this.proxyAddress.equals(that.proxyAddress) && this.serverName.equals(that.serverName); - } else { - return false; - } - } - - @Override - public int hashCode() { - return Objects.hash(proxyAddress, serverName); - } - - @Override - public String toString() { - // Note that this uses the original proxy address, so if there are multiple A-records it won't - // show which one was selected. If that turns out to be a problem for debugging, we might need - // to store the result of resolve() in Connection and log that instead of the endpoint. - return proxyAddress.toString() + ":" + serverName; - } - - @NonNull - @Override - public String asMetricPrefix() { - String hostString = proxyAddress.getHostString(); - if (hostString == null) { - throw new IllegalArgumentException( - "Could not extract a host string from provided proxy address " + proxyAddress); - } - return hostString.replace('.', '_') + ':' + proxyAddress.getPort() + '_' + serverName; - } - - @SuppressWarnings("UnnecessaryLambda") - private static final Comparator IP_COMPARATOR = - (InetAddress address1, InetAddress address2) -> - UnsignedBytes.lexicographicalComparator() - .compare(address1.getAddress(), address2.getAddress()); -} diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/parsing/DefaultSchemaParserFactory.java b/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/parsing/DefaultSchemaParserFactory.java index 5fa64027be5..f5c904efa49 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/parsing/DefaultSchemaParserFactory.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/parsing/DefaultSchemaParserFactory.java @@ -17,8 +17,6 @@ */ package com.datastax.oss.driver.internal.core.metadata.schema.parsing; -import com.datastax.dse.driver.api.core.metadata.DseNodeProperties; -import com.datastax.dse.driver.internal.core.metadata.schema.parsing.DseSchemaParser; import com.datastax.oss.driver.internal.core.context.InternalDriverContext; import com.datastax.oss.driver.internal.core.metadata.schema.queries.SchemaRows; import net.jcip.annotations.ThreadSafe; @@ -34,7 +32,6 @@ public DefaultSchemaParserFactory(InternalDriverContext context) { @Override public SchemaParser newInstance(SchemaRows rows) { - boolean isDse = rows.getNode().getExtras().containsKey(DseNodeProperties.DSE_VERSION); - return isDse ? new DseSchemaParser(rows, context) : new CassandraSchemaParser(rows, context); + return new CassandraSchemaParser(rows, context); } } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/parsing/RelationParser.java b/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/parsing/RelationParser.java index 86c914459d7..ab019c3610e 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/parsing/RelationParser.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/parsing/RelationParser.java @@ -17,7 +17,6 @@ */ package com.datastax.oss.driver.internal.core.metadata.schema.parsing; -import com.datastax.dse.driver.api.core.metadata.DseNodeProperties; import com.datastax.oss.driver.api.core.CqlIdentifier; import com.datastax.oss.driver.api.core.Version; import com.datastax.oss.driver.api.core.metadata.Node; @@ -104,8 +103,7 @@ private boolean isDeprecatedInCassandra4(String name) { private boolean isCassandra4OrAbove() { Node node = rows.getNode(); - return !node.getExtras().containsKey(DseNodeProperties.DSE_VERSION) - && node.getCassandraVersion() != null + return node.getCassandraVersion() != null && node.getCassandraVersion().nextStable().compareTo(Version.V4_0_0) >= 0; } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/Cassandra21SchemaQueries.java b/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/Cassandra21SchemaQueries.java index 1bd8faf3c4c..b3870fc4cf9 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/Cassandra21SchemaQueries.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/Cassandra21SchemaQueries.java @@ -85,16 +85,6 @@ protected Optional selectVirtualColumnsQuery() { return Optional.empty(); } - @Override - protected Optional selectEdgesQuery() { - return Optional.empty(); - } - - @Override - protected Optional selectVerticiesQuery() { - return Optional.empty(); - } - @Override protected Optional selectScyllaKeyspacesQuery() { return Optional.empty(); diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/Cassandra22SchemaQueries.java b/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/Cassandra22SchemaQueries.java index 06b58cc1008..fcb19f12d0e 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/Cassandra22SchemaQueries.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/Cassandra22SchemaQueries.java @@ -85,16 +85,6 @@ protected Optional selectVirtualColumnsQuery() { return Optional.empty(); } - @Override - protected Optional selectEdgesQuery() { - return Optional.empty(); - } - - @Override - protected Optional selectVerticiesQuery() { - return Optional.empty(); - } - @Override protected Optional selectScyllaKeyspacesQuery() { return Optional.empty(); diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/Cassandra3SchemaQueries.java b/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/Cassandra3SchemaQueries.java index 4719a96bdda..542c3aa23b2 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/Cassandra3SchemaQueries.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/Cassandra3SchemaQueries.java @@ -85,16 +85,6 @@ protected Optional selectVirtualColumnsQuery() { return Optional.empty(); } - @Override - protected Optional selectEdgesQuery() { - return Optional.empty(); - } - - @Override - protected Optional selectVerticiesQuery() { - return Optional.empty(); - } - @Override protected Optional selectScyllaKeyspacesQuery() { return Optional.of("SELECT * FROM system_schema.scylla_keyspaces"); diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/CassandraSchemaQueries.java b/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/CassandraSchemaQueries.java index 4c7e51318ed..03aa93521ea 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/CassandraSchemaQueries.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/CassandraSchemaQueries.java @@ -109,10 +109,6 @@ protected CassandraSchemaQueries( protected abstract Optional selectAggregatesQuery(); - protected abstract Optional selectEdgesQuery(); - - protected abstract Optional selectVerticiesQuery(); - protected abstract Optional selectScyllaKeyspacesQuery(); @Override @@ -162,12 +158,6 @@ private void executeOnAdminExecutor() { .ifPresent( select -> query(select + whereClause + usingClause, schemaRowsBuilder::withVirtualColumns)); - selectEdgesQuery() - .ifPresent( - select -> query(select + whereClause + usingClause, schemaRowsBuilder::withEdges)); - selectVerticiesQuery() - .ifPresent( - select -> query(select + whereClause + usingClause, schemaRowsBuilder::withVertices)); } protected boolean shouldApplyUsingTimeout() { diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/CassandraSchemaRows.java b/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/CassandraSchemaRows.java index eeb893a6498..17a2eea28e4 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/CassandraSchemaRows.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/CassandraSchemaRows.java @@ -17,7 +17,6 @@ */ package com.datastax.oss.driver.internal.core.metadata.schema.queries; -import com.datastax.dse.driver.api.core.metadata.DseNodeProperties; import com.datastax.oss.driver.api.core.CqlIdentifier; import com.datastax.oss.driver.api.core.Version; import com.datastax.oss.driver.api.core.metadata.Node; @@ -54,8 +53,6 @@ public class CassandraSchemaRows implements SchemaRows { private final Map> columns; private final Map> virtualColumns; private final Map> indexes; - private final Map> vertices; - private final Map> edges; private final Map scyllaKeyspaces; private CassandraSchemaRows( @@ -72,8 +69,6 @@ private CassandraSchemaRows( Multimap types, Multimap functions, Multimap aggregates, - Map> vertices, - Map> edges, Map scyllaKeyspaces) { this.node = node; this.dataTypeParser = dataTypeParser; @@ -88,8 +83,6 @@ private CassandraSchemaRows( this.types = types; this.functions = functions; this.aggregates = aggregates; - this.vertices = vertices; - this.edges = edges; this.scyllaKeyspaces = scyllaKeyspaces; } @@ -159,16 +152,6 @@ public Map> indexes() { return indexes; } - @Override - public Map> vertices() { - return vertices; - } - - @Override - public Map> edges() { - return edges; - } - @Override public Map scyllaKeyspaces() { return scyllaKeyspaces; @@ -202,10 +185,6 @@ public static class Builder { virtualColumnsBuilders = new LinkedHashMap<>(); private final Map> indexesBuilders = new LinkedHashMap<>(); - private final Map> - verticesBuilders = new LinkedHashMap<>(); - private final Map> - edgesBuilders = new LinkedHashMap<>(); private final ImmutableMap.Builder scyllaKeyspacesBuilder = ImmutableMap.builder(); @@ -223,23 +202,13 @@ public Builder(Node node, KeyspaceFilter keyspaceFilter, String logPrefix) { } private static boolean isCassandraV3OrAbove(Node node) { - // We already did those checks in DefaultSchemaQueriesFactory. - // We could pass along booleans (isCassandraV3, isDse...), but passing the whole Node is - // better for maintainability, in case we need to do more checks in downstream components in - // the future. - Version dseVersion = (Version) node.getExtras().get(DseNodeProperties.DSE_VERSION); - if (dseVersion != null) { - dseVersion = dseVersion.nextStable(); - return dseVersion.compareTo(Version.V5_0_0) >= 0; + Version cassandraVersion = node.getCassandraVersion(); + if (cassandraVersion == null) { + cassandraVersion = Version.V3_0_0; } else { - Version cassandraVersion = node.getCassandraVersion(); - if (cassandraVersion == null) { - cassandraVersion = Version.V3_0_0; - } else { - cassandraVersion = cassandraVersion.nextStable(); - } - return cassandraVersion.compareTo(Version.V3_0_0) >= 0; + cassandraVersion = cassandraVersion.nextStable(); } + return cassandraVersion.compareTo(Version.V3_0_0) >= 0; } public Builder withKeyspaces(Iterable rows) { @@ -319,20 +288,6 @@ public Builder withIndexes(Iterable rows) { return this; } - public Builder withVertices(Iterable rows) { - for (AdminRow row : rows) { - putByKeyspaceAndTable(row, verticesBuilders); - } - return this; - } - - public Builder withEdges(Iterable rows) { - for (AdminRow row : rows) { - putByKeyspaceAndTable(row, edgesBuilders); - } - return this; - } - public Builder withScyllaKeyspaces(Iterable rows) { for (AdminRow row : rows) { putByKeyspacePk(row, scyllaKeyspacesBuilder); @@ -401,8 +356,6 @@ public CassandraSchemaRows build() { typesBuilder.build(), functionsBuilder.build(), aggregatesBuilder.build(), - build(verticesBuilders), - build(edgesBuilders), scyllaKeyspacesBuilder.build()); } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/DefaultSchemaQueriesFactory.java b/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/DefaultSchemaQueriesFactory.java index 1f6911c6f46..c2a3a86d61d 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/DefaultSchemaQueriesFactory.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/DefaultSchemaQueriesFactory.java @@ -17,7 +17,6 @@ */ package com.datastax.oss.driver.internal.core.metadata.schema.queries; -import com.datastax.dse.driver.api.core.metadata.DseNodeProperties; import com.datastax.oss.driver.api.core.Version; import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; import com.datastax.oss.driver.api.core.metadata.Node; @@ -68,48 +67,27 @@ protected SchemaQueries newInstance(Node node, DriverChannel channel) { DriverExecutionProfile config = context.getConfig().getDefaultProfile(); - Version dseVersion = (Version) node.getExtras().get(DseNodeProperties.DSE_VERSION); - if (dseVersion != null) { - dseVersion = dseVersion.nextStable(); - - LOG.debug( - "[{}] Sending schema queries to {} with DSE version {}", logPrefix, node, dseVersion); - // 4.8 is the oldest version supported, which uses C* 2.1 schema - if (dseVersion.compareTo(Version.V5_0_0) < 0) { - return new Cassandra21SchemaQueries(channel, node, config, logPrefix); - } else if (dseVersion.compareTo(Version.V6_7_0) < 0) { - // 5.0 - 6.7 uses C* 3.0 schema - return new Cassandra3SchemaQueries(channel, node, config, logPrefix); - } else if (dseVersion.compareTo(Version.V6_8_0) < 0) { - // 6.7 uses C* 4.0 schema - return new Cassandra4SchemaQueries(channel, node, config, logPrefix); - } else { - // 6.8+ uses DSE 6.8 schema (C* 4.0 schema with graph metadata) (JAVA-1898) - return new Dse68SchemaQueries(channel, node, config, logPrefix); - } + Version cassandraVersion = node.getCassandraVersion(); + if (cassandraVersion == null) { + LOG.warn( + "[{}] Cassandra version missing for {}, defaulting to {}", + logPrefix, + node, + Version.V3_0_0); + cassandraVersion = Version.V3_0_0; + } else { + cassandraVersion = cassandraVersion.nextStable(); + } + LOG.debug( + "[{}] Sending schema queries to {} with version {}", logPrefix, node, cassandraVersion); + if (cassandraVersion.compareTo(Version.V2_2_0) < 0) { + return new Cassandra21SchemaQueries(channel, node, config, logPrefix); + } else if (cassandraVersion.compareTo(Version.V3_0_0) < 0) { + return new Cassandra22SchemaQueries(channel, node, config, logPrefix); + } else if (cassandraVersion.compareTo(Version.V4_0_0) < 0) { + return new Cassandra3SchemaQueries(channel, node, config, logPrefix); } else { - Version cassandraVersion = node.getCassandraVersion(); - if (cassandraVersion == null) { - LOG.warn( - "[{}] Cassandra version missing for {}, defaulting to {}", - logPrefix, - node, - Version.V3_0_0); - cassandraVersion = Version.V3_0_0; - } else { - cassandraVersion = cassandraVersion.nextStable(); - } - LOG.debug( - "[{}] Sending schema queries to {} with version {}", logPrefix, node, cassandraVersion); - if (cassandraVersion.compareTo(Version.V2_2_0) < 0) { - return new Cassandra21SchemaQueries(channel, node, config, logPrefix); - } else if (cassandraVersion.compareTo(Version.V3_0_0) < 0) { - return new Cassandra22SchemaQueries(channel, node, config, logPrefix); - } else if (cassandraVersion.compareTo(Version.V4_0_0) < 0) { - return new Cassandra3SchemaQueries(channel, node, config, logPrefix); - } else { - return new Cassandra4SchemaQueries(channel, node, config, logPrefix); - } + return new Cassandra4SchemaQueries(channel, node, config, logPrefix); } } } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/Dse68SchemaQueries.java b/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/Dse68SchemaQueries.java deleted file mode 100644 index 460df8b59e5..00000000000 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/Dse68SchemaQueries.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.oss.driver.internal.core.metadata.schema.queries; - -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.datastax.oss.driver.internal.core.channel.DriverChannel; -import java.util.Optional; - -/** - * The system table queries to refresh the schema in DSE 6.8. - * - *

There are two additional tables for per-table graph metadata. - */ -public class Dse68SchemaQueries extends Cassandra4SchemaQueries { - - public Dse68SchemaQueries( - DriverChannel channel, Node node, DriverExecutionProfile config, String logPrefix) { - super(channel, node, config, logPrefix); - } - - @Override - protected Optional selectEdgesQuery() { - return Optional.of("SELECT * FROM system_schema.edges"); - } - - @Override - protected Optional selectVerticiesQuery() { - return Optional.of("SELECT * FROM system_schema.vertices"); - } -} diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/SchemaRows.java b/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/SchemaRows.java index 05583eb484e..c457c3f34a1 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/SchemaRows.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/SchemaRows.java @@ -24,7 +24,6 @@ import com.datastax.oss.driver.shaded.guava.common.collect.Multimap; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -64,14 +63,6 @@ public interface SchemaRows { DataTypeParser dataTypeParser(); - default Map> vertices() { - return new LinkedHashMap<>(); - } - - default Map> edges() { - return new LinkedHashMap<>(); - } - default Map scyllaKeyspaces() { return new HashMap<>(); } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/metrics/DropwizardNodeMetricUpdater.java b/core/src/main/java/com/datastax/oss/driver/internal/core/metrics/DropwizardNodeMetricUpdater.java index 2e5e6c8db3d..b0ecfa147fc 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/metrics/DropwizardNodeMetricUpdater.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/metrics/DropwizardNodeMetricUpdater.java @@ -18,8 +18,6 @@ package com.datastax.oss.driver.internal.core.metrics; import com.codahale.metrics.MetricRegistry; -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.dse.driver.api.core.metrics.DseNodeMetric; import com.datastax.oss.driver.api.core.config.DefaultDriverOption; import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; import com.datastax.oss.driver.api.core.metadata.Node; @@ -78,12 +76,6 @@ public DropwizardNodeMetricUpdater( DefaultDriverOption.METRICS_NODE_CQL_MESSAGES_HIGHEST, DefaultDriverOption.METRICS_NODE_CQL_MESSAGES_DIGITS, DefaultDriverOption.METRICS_NODE_CQL_MESSAGES_INTERVAL); - initializeHdrTimer( - DseNodeMetric.GRAPH_MESSAGES, - profile, - DseDriverOption.METRICS_NODE_GRAPH_MESSAGES_HIGHEST, - DseDriverOption.METRICS_NODE_GRAPH_MESSAGES_DIGITS, - DseDriverOption.METRICS_NODE_GRAPH_MESSAGES_INTERVAL); } @Override diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/metrics/DropwizardSessionMetricUpdater.java b/core/src/main/java/com/datastax/oss/driver/internal/core/metrics/DropwizardSessionMetricUpdater.java index 94e10ad6936..f43b34d42fb 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/metrics/DropwizardSessionMetricUpdater.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/metrics/DropwizardSessionMetricUpdater.java @@ -18,8 +18,6 @@ package com.datastax.oss.driver.internal.core.metrics; import com.codahale.metrics.MetricRegistry; -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.dse.driver.api.core.metrics.DseSessionMetric; import com.datastax.oss.driver.api.core.config.DefaultDriverOption; import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; import com.datastax.oss.driver.api.core.metrics.DefaultSessionMetric; @@ -45,7 +43,6 @@ public DropwizardSessionMetricUpdater( initializeCounter(DefaultSessionMetric.CQL_CLIENT_TIMEOUTS, profile); initializeCounter(DefaultSessionMetric.THROTTLING_ERRORS, profile); - initializeCounter(DseSessionMetric.GRAPH_CLIENT_TIMEOUTS, profile); initializeHdrTimer( DefaultSessionMetric.CQL_REQUESTS, @@ -59,18 +56,6 @@ public DropwizardSessionMetricUpdater( DefaultDriverOption.METRICS_SESSION_THROTTLING_HIGHEST, DefaultDriverOption.METRICS_SESSION_THROTTLING_DIGITS, DefaultDriverOption.METRICS_SESSION_THROTTLING_INTERVAL); - initializeHdrTimer( - DseSessionMetric.CONTINUOUS_CQL_REQUESTS, - profile, - DseDriverOption.CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_HIGHEST, - DseDriverOption.CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_DIGITS, - DseDriverOption.CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_INTERVAL); - initializeHdrTimer( - DseSessionMetric.GRAPH_REQUESTS, - profile, - DseDriverOption.METRICS_SESSION_GRAPH_REQUESTS_HIGHEST, - DseDriverOption.METRICS_SESSION_GRAPH_REQUESTS_DIGITS, - DseDriverOption.METRICS_SESSION_GRAPH_REQUESTS_INTERVAL); } @Override diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/metrics/MetricPaths.java b/core/src/main/java/com/datastax/oss/driver/internal/core/metrics/MetricPaths.java index 92b3fc569f7..fb086f4a3ac 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/metrics/MetricPaths.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/metrics/MetricPaths.java @@ -17,8 +17,6 @@ */ package com.datastax.oss.driver.internal.core.metrics; -import com.datastax.dse.driver.api.core.metrics.DseNodeMetric; -import com.datastax.dse.driver.api.core.metrics.DseSessionMetric; import com.datastax.oss.driver.api.core.metrics.DefaultNodeMetric; import com.datastax.oss.driver.api.core.metrics.DefaultSessionMetric; import com.datastax.oss.driver.api.core.metrics.NodeMetric; @@ -40,11 +38,7 @@ public static Set parseSessionMetricPaths(List paths, Str try { result.add(DefaultSessionMetric.fromPath(path)); } catch (IllegalArgumentException e) { - try { - result.add(DseSessionMetric.fromPath(path)); - } catch (IllegalArgumentException e1) { - LOG.warn("[{}] Unknown session metric {}, skipping", logPrefix, path); - } + LOG.warn("[{}] Unknown session metric {}, skipping", logPrefix, path); } } return Collections.unmodifiableSet(result); @@ -56,11 +50,7 @@ public static Set parseNodeMetricPaths(List paths, String lo try { result.add(DefaultNodeMetric.fromPath(path)); } catch (IllegalArgumentException e) { - try { - result.add(DseNodeMetric.fromPath(path)); - } catch (IllegalArgumentException e1) { - LOG.warn("[{}] Unknown node metric {}, skipping", logPrefix, path); - } + LOG.warn("[{}] Unknown node metric {}, skipping", logPrefix, path); } } return Collections.unmodifiableSet(result); diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/session/BuiltInRequestProcessors.java b/core/src/main/java/com/datastax/oss/driver/internal/core/session/BuiltInRequestProcessors.java index dc6e6a295a1..dbf13e391da 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/session/BuiltInRequestProcessors.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/session/BuiltInRequestProcessors.java @@ -18,16 +18,8 @@ package com.datastax.oss.driver.internal.core.session; import static com.datastax.oss.driver.internal.core.util.Dependency.REACTIVE_STREAMS; -import static com.datastax.oss.driver.internal.core.util.Dependency.TINKERPOP; -import com.datastax.dse.driver.internal.core.cql.continuous.ContinuousCqlRequestAsyncProcessor; -import com.datastax.dse.driver.internal.core.cql.continuous.ContinuousCqlRequestSyncProcessor; -import com.datastax.dse.driver.internal.core.cql.continuous.reactive.ContinuousCqlRequestReactiveProcessor; import com.datastax.dse.driver.internal.core.cql.reactive.CqlRequestReactiveProcessor; -import com.datastax.dse.driver.internal.core.graph.GraphRequestAsyncProcessor; -import com.datastax.dse.driver.internal.core.graph.GraphRequestSyncProcessor; -import com.datastax.dse.driver.internal.core.graph.GraphSupportChecker; -import com.datastax.dse.driver.internal.core.graph.reactive.ReactiveGraphRequestProcessor; import com.datastax.oss.driver.internal.core.context.DefaultDriverContext; import com.datastax.oss.driver.internal.core.cql.CqlPrepareAsyncProcessor; import com.datastax.oss.driver.internal.core.cql.CqlPrepareSyncProcessor; @@ -47,21 +39,12 @@ public class BuiltInRequestProcessors { public static List> createDefaultProcessors(DefaultDriverContext context) { List> processors = new ArrayList<>(); addBasicProcessors(processors, context); - if (DefaultDependencyChecker.isPresent(TINKERPOP)) { - addGraphProcessors(context, processors); - } else { - LOG.debug("Tinkerpop was not found on the classpath: graph extensions will not be available"); - } if (DefaultDependencyChecker.isPresent(REACTIVE_STREAMS)) { addReactiveProcessors(processors); } else { LOG.debug( "Reactive Streams was not found on the classpath: reactive extensions will not be available"); } - if (DefaultDependencyChecker.isPresent(REACTIVE_STREAMS) - && DefaultDependencyChecker.isPresent(TINKERPOP)) { - addGraphReactiveProcessors(context, processors); - } return processors; } @@ -81,40 +64,11 @@ public static void addBasicProcessors( new CqlPrepareSyncProcessor(cqlPrepareAsyncProcessor); processors.add(cqlPrepareAsyncProcessor); processors.add(cqlPrepareSyncProcessor); - - // continuous requests (sync and async) - ContinuousCqlRequestAsyncProcessor continuousCqlRequestAsyncProcessor = - new ContinuousCqlRequestAsyncProcessor(); - ContinuousCqlRequestSyncProcessor continuousCqlRequestSyncProcessor = - new ContinuousCqlRequestSyncProcessor(continuousCqlRequestAsyncProcessor); - processors.add(continuousCqlRequestAsyncProcessor); - processors.add(continuousCqlRequestSyncProcessor); - } - - public static void addGraphProcessors( - DefaultDriverContext context, List> processors) { - GraphRequestAsyncProcessor graphRequestAsyncProcessor = - new GraphRequestAsyncProcessor(context, new GraphSupportChecker()); - GraphRequestSyncProcessor graphRequestSyncProcessor = - new GraphRequestSyncProcessor(graphRequestAsyncProcessor); - processors.add(graphRequestAsyncProcessor); - processors.add(graphRequestSyncProcessor); } public static void addReactiveProcessors(List> processors) { CqlRequestReactiveProcessor cqlRequestReactiveProcessor = new CqlRequestReactiveProcessor(new CqlRequestAsyncProcessor()); - ContinuousCqlRequestReactiveProcessor continuousCqlRequestReactiveProcessor = - new ContinuousCqlRequestReactiveProcessor(new ContinuousCqlRequestAsyncProcessor()); processors.add(cqlRequestReactiveProcessor); - processors.add(continuousCqlRequestReactiveProcessor); - } - - public static void addGraphReactiveProcessors( - DefaultDriverContext context, List> processors) { - ReactiveGraphRequestProcessor reactiveGraphRequestProcessor = - new ReactiveGraphRequestProcessor( - new GraphRequestAsyncProcessor(context, new GraphSupportChecker())); - processors.add(reactiveGraphRequestProcessor); } } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/session/BuiltInRequestProcessorsSubstitutions.java b/core/src/main/java/com/datastax/oss/driver/internal/core/session/BuiltInRequestProcessorsSubstitutions.java index b8bca431228..4318de5395b 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/session/BuiltInRequestProcessorsSubstitutions.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/session/BuiltInRequestProcessorsSubstitutions.java @@ -18,7 +18,6 @@ package com.datastax.oss.driver.internal.core.session; import static com.datastax.oss.driver.internal.core.util.Dependency.REACTIVE_STREAMS; -import static com.datastax.oss.driver.internal.core.util.Dependency.TINKERPOP; import com.datastax.oss.driver.internal.core.context.DefaultDriverContext; import com.datastax.oss.driver.internal.core.util.GraalDependencyChecker; @@ -31,8 +30,8 @@ @SuppressWarnings("unused") public class BuiltInRequestProcessorsSubstitutions { - @TargetClass(value = BuiltInRequestProcessors.class, onlyWith = GraphMissingReactiveMissing.class) - public static final class BuiltInRequestProcessorsGraphMissingReactiveMissing { + @TargetClass(value = BuiltInRequestProcessors.class, onlyWith = ReactiveMissing.class) + public static final class BuiltInRequestProcessorsReactiveMissing { @Substitute public static List> createDefaultProcessors( @@ -43,8 +42,8 @@ public static final class BuiltInRequestProcessorsGraphMissingReactiveMissing { } } - @TargetClass(value = BuiltInRequestProcessors.class, onlyWith = GraphMissingReactivePresent.class) - public static final class BuiltInRequestProcessorsGraphMissingReactivePresent { + @TargetClass(value = BuiltInRequestProcessors.class, onlyWith = ReactivePresent.class) + public static final class BuiltInRequestProcessorsReactivePresent { @Substitute public static List> createDefaultProcessors( @@ -56,40 +55,17 @@ public static final class BuiltInRequestProcessorsGraphMissingReactivePresent { } } - @TargetClass(value = BuiltInRequestProcessors.class, onlyWith = GraphPresentReactiveMissing.class) - public static final class BuiltInRequestProcessorsGraphPresentReactiveMissing { - - @Substitute - public static List> createDefaultProcessors( - DefaultDriverContext context) { - List> processors = new ArrayList<>(); - BuiltInRequestProcessors.addBasicProcessors(processors, context); - BuiltInRequestProcessors.addGraphProcessors(context, processors); - return processors; - } - } - - public static class GraphMissingReactiveMissing implements BooleanSupplier { - @Override - public boolean getAsBoolean() { - return !GraalDependencyChecker.isPresent(TINKERPOP) - && !GraalDependencyChecker.isPresent(REACTIVE_STREAMS); - } - } - - public static class GraphMissingReactivePresent implements BooleanSupplier { + public static class ReactiveMissing implements BooleanSupplier { @Override public boolean getAsBoolean() { - return !GraalDependencyChecker.isPresent(TINKERPOP) - && GraalDependencyChecker.isPresent(REACTIVE_STREAMS); + return !GraalDependencyChecker.isPresent(REACTIVE_STREAMS); } } - public static class GraphPresentReactiveMissing implements BooleanSupplier { + public static class ReactivePresent implements BooleanSupplier { @Override public boolean getAsBoolean() { - return GraalDependencyChecker.isPresent(TINKERPOP) - && !GraalDependencyChecker.isPresent(REACTIVE_STREAMS); + return GraalDependencyChecker.isPresent(REACTIVE_STREAMS); } } } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/ssl/SniSslEngineFactory.java b/core/src/main/java/com/datastax/oss/driver/internal/core/ssl/SniSslEngineFactory.java deleted file mode 100644 index 4d2cb69fbfc..00000000000 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/ssl/SniSslEngineFactory.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.datastax.oss.driver.internal.core.ssl; - -import com.datastax.oss.driver.api.core.metadata.EndPoint; -import com.datastax.oss.driver.api.core.ssl.SslEngineFactory; -import com.datastax.oss.driver.internal.core.metadata.SniEndPoint; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.net.InetSocketAddress; -import java.util.concurrent.CopyOnWriteArrayList; -import javax.net.ssl.SNIHostName; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLEngine; -import javax.net.ssl.SSLParameters; - -public class SniSslEngineFactory implements SslEngineFactory { - - // An offset that gets added to our "fake" ports (see below). We pick this value because it is the - // start of the ephemeral port range. - private static final int FAKE_PORT_OFFSET = 49152; - - private final SSLContext sslContext; - private final CopyOnWriteArrayList fakePorts = new CopyOnWriteArrayList<>(); - private final boolean allowDnsReverseLookupSan; - - public SniSslEngineFactory(SSLContext sslContext) { - this(sslContext, true); - } - - public SniSslEngineFactory(SSLContext sslContext, boolean allowDnsReverseLookupSan) { - this.sslContext = sslContext; - this.allowDnsReverseLookupSan = allowDnsReverseLookupSan; - } - - @NonNull - @Override - public SSLEngine newSslEngine(@NonNull EndPoint remoteEndpoint) { - if (!(remoteEndpoint instanceof SniEndPoint)) { - throw new IllegalArgumentException( - String.format( - "Configuration error: can only use %s with SNI end points", - this.getClass().getSimpleName())); - } - SniEndPoint sniEndPoint = (SniEndPoint) remoteEndpoint; - InetSocketAddress address = sniEndPoint.resolve(); - String sniServerName = sniEndPoint.getServerName(); - - // When hostname verification is enabled (with setEndpointIdentificationAlgorithm), the SSL - // engine will try to match the server's certificate against the SNI host name; if that doesn't - // work, it will fall back to the "advisory peer host" passed to createSSLEngine. - // - // In our case, the first check will never succeed because our SNI host name is not the DNS name - // (we use the Cassandra host_id instead). So we *must* set the advisory peer information. - // - // However if we use the address as-is, this leads to another issue: the advisory peer - // information is also used to cache SSL sessions internally. All of our nodes share the same - // proxy address, so the JDK tries to reuse SSL sessions across nodes. But it doesn't update the - // SNI host name every time, so it ends up opening connections to the wrong node. - // - // To avoid that, we create a unique "fake" port for every node. We still get session reuse for - // a given node, but not across nodes. This is safe because the advisory port is only used for - // session caching. - String peerHost = allowDnsReverseLookupSan ? address.getHostName() : address.getHostString(); - SSLEngine engine = sslContext.createSSLEngine(peerHost, getFakePort(sniServerName)); - engine.setUseClientMode(true); - SSLParameters parameters = engine.getSSLParameters(); - parameters.setServerNames(ImmutableList.of(new SNIHostName(sniServerName))); - parameters.setEndpointIdentificationAlgorithm("HTTPS"); - engine.setSSLParameters(parameters); - return engine; - } - - private int getFakePort(String sniServerName) { - fakePorts.addIfAbsent(sniServerName); - return FAKE_PORT_OFFSET + fakePorts.indexOf(sniServerName); - } - - @Override - public void close() { - // nothing to do - } -} diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/util/Dependency.java b/core/src/main/java/com/datastax/oss/driver/internal/core/util/Dependency.java index 97cfa25d9af..4a7f481d4a4 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/util/Dependency.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/util/Dependency.java @@ -36,12 +36,6 @@ public enum Dependency { SNAPPY("org.xerial.snappy.Snappy"), LZ4("net.jpountz.lz4.LZ4Compressor"), - ESRI("com.esri.core.geometry.ogc.OGCGeometry"), - TINKERPOP( - // gremlin-core - "org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal", - // tinkergraph-gremlin - "org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV3d0"), REACTIVE_STREAMS("org.reactivestreams.Publisher"), JACKSON( // jackson-core diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/util/concurrent/DriverBlockHoundIntegration.java b/core/src/main/java/com/datastax/oss/driver/internal/core/util/concurrent/DriverBlockHoundIntegration.java index 68e59e89c3b..698f3ab500d 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/util/concurrent/DriverBlockHoundIntegration.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/util/concurrent/DriverBlockHoundIntegration.java @@ -70,33 +70,6 @@ public void applyTo(BlockHound.Builder builder) { // protect the whole Uuids.timeBased method. "com.datastax.oss.driver.api.core.uuid.Uuids", "timeBased"); - // continuous paging - - builder.allowBlockingCallsInside( - "com.datastax.dse.driver.internal.core.cql.continuous.ContinuousRequestHandlerBase$NodeResponseCallback", - "cancel"); - builder.allowBlockingCallsInside( - "com.datastax.dse.driver.internal.core.cql.continuous.ContinuousRequestHandlerBase$NodeResponseCallback", - "dequeueOrCreatePending"); - builder.allowBlockingCallsInside( - "com.datastax.dse.driver.internal.core.cql.continuous.ContinuousRequestHandlerBase$NodeResponseCallback", - "isLastResponse"); - builder.allowBlockingCallsInside( - "com.datastax.dse.driver.internal.core.cql.continuous.ContinuousRequestHandlerBase$NodeResponseCallback", - "onFailure"); - builder.allowBlockingCallsInside( - "com.datastax.dse.driver.internal.core.cql.continuous.ContinuousRequestHandlerBase$NodeResponseCallback", - "onPageTimeout"); - builder.allowBlockingCallsInside( - "com.datastax.dse.driver.internal.core.cql.continuous.ContinuousRequestHandlerBase$NodeResponseCallback", - "onResponse"); - builder.allowBlockingCallsInside( - "com.datastax.dse.driver.internal.core.cql.continuous.ContinuousRequestHandlerBase$NodeResponseCallback", - "onStreamIdAssigned"); - builder.allowBlockingCallsInside( - "com.datastax.dse.driver.internal.core.cql.continuous.ContinuousRequestHandlerBase$NodeResponseCallback", - "operationComplete"); - // Netty extra exceptions // see https://github.com/netty/netty/pull/10810 diff --git a/core/src/main/resources/META-INF/native-image/com.datastax.oss/java-driver-core/reflection.json b/core/src/main/resources/META-INF/native-image/com.datastax.oss/java-driver-core/reflection.json index 6082b853611..ba13d84a782 100644 --- a/core/src/main/resources/META-INF/native-image/com.datastax.oss/java-driver-core/reflection.json +++ b/core/src/main/resources/META-INF/native-image/com.datastax.oss/java-driver-core/reflection.json @@ -87,10 +87,6 @@ "name": "com.datastax.oss.driver.internal.core.auth.PlainTextAuthProvider", "methods": [ { "name": "", "parameterTypes": [ "com.datastax.oss.driver.api.core.context.DriverContext" ] } ] }, - { - "name": "com.datastax.dse.driver.internal.core.auth.DseGssApiAuthProvider", - "methods": [ { "name": "", "parameterTypes": [ "com.datastax.oss.driver.api.core.context.DriverContext" ] } ] - }, { "name": "com.datastax.oss.driver.internal.core.ssl.DefaultSslEngineFactory", "methods": [ { "name": "", "parameterTypes": [ "com.datastax.oss.driver.api.core.context.DriverContext" ] } ] diff --git a/core/src/main/resources/reference.conf b/core/src/main/resources/reference.conf index 590784b70c5..d05ede8cbf4 100644 --- a/core/src/main/resources/reference.conf +++ b/core/src/main/resources/reference.conf @@ -167,10 +167,9 @@ datastax-java-driver { # - when the policies assign distances to nodes, the driver uses the closest assigned distance # for any given node. basic.load-balancing-policy { - # The class of the policy. If it is not qualified, the driver assumes that it resides in one of - # the following packages: + # The class of the policy. If it is not qualified, the driver assumes that it resides in the + # following package: # - com.datastax.oss.driver.internal.core.loadbalancing. - # - com.datastax.dse.driver.internal.core.loadbalancing. # # The driver provides three implementations out of the box: # @@ -257,29 +256,14 @@ datastax-java-driver { # If this option is not defined, the driver defaults to true. slow-replica-avoidance = true } - basic.cloud { - # The location of the cloud secure bundle used to connect to DataStax Apache Cassandra as a - # service. - # This setting must be a valid URL. - # If the protocol is not specified, it is implicitly assumed to be the `file://` protocol, - # in which case the value is expected to be a valid path on the local filesystem. - # For example, `/a/path/to/bundle` will be interpreted as `file:/a/path/to/bunde`. - # If the protocol is provided explicitly, then the value will be used as is. - # - # Required: no - # Modifiable at runtime: no - # Overridable in a profile: no - // secure-connect-bundle = /location/of/secure/connect/bundle - } - - # DataStax Insights monitoring. + # Application metadata sent in the STARTUP message. basic.application { # The name of the application using the session. # # It will be sent in the STARTUP protocol message for each new connection established by the # driver. # - # This can also be defined programmatically with DseSessionBuilder.withApplicationName(). If you + # This can also be defined programmatically with SessionBuilder.withApplicationName(). If you # specify both, the programmatic value takes precedence and this option is ignored. # # Required: no @@ -292,7 +276,7 @@ datastax-java-driver { # It will be sent in the STARTUP protocol message for each new connection established by the # driver. # - # This can also be defined programmatically with DseSessionBuilder.withApplicationVersion(). If + # This can also be defined programmatically with SessionBuilder.withApplicationVersion(). If # you specify both, the programmatic value takes precedence and this option is ignored. # # Required: no @@ -301,100 +285,6 @@ datastax-java-driver { // version = } - # Graph (DataStax Enterprise only) - basic.graph { - # The name of the graph targeted by graph statements. - # - # This can also be overridden programmatically with GraphStatement.setGraphName(). If both are - # specified, the programmatic value takes precedence, and this option is ignored. - # - # Required: no. In particular, system queries -- such as creating or dropping a graph -- must be - # executed without a graph name (see also basic.graph.is-system-query). - # Modifiable at runtime: yes, the new value will be used for requests issued after the change. - # Overridable in a profile: yes - // name = your-graph-name - - # The traversal source to use for graph statements. - # - # This setting doesn't usually need to change, unless executing OLAP queries, which require the - # traversal source "a". - # - # This can also be overridden programmatically with GraphStatement.setTraversalSource(). If both - # are specified, the programmatic value takes precedence, and this option is ignored. - # - # Required: no - # Modifiable at runtime: yes, the new value will be used for requests issued after the change. - # Overridable in a profile: yes - traversal-source = "g" - - # Whether a script statement represents a system query. - # - # Script statements that access the `system` variable *must not* specify a graph name (otherwise - # `system` is not available). However, if your application executes a lot of non-system - # statements, it is convenient to configure basic.graph.name to avoid repeating it every time. - # This option allows you to ignore that global graph name, for example in a specific profile. - # - # This can also be overridden programmatically with ScriptGraphStatement.setSystemQuery(). If - # both are specified, the programmatic value takes precedence, and this option is ignored. - # - # Required: no (defaults to false) - # Modifiable at runtime: yes, the new value will be used for requests issued after the change. - # Overridable in a profile: yes - // is-system-query = false - - # The read consistency level to use for graph statements. - # - # DSE Graph is able to distinguish between read and write timeouts for the internal storage - # queries that will be produced by a traversal. Hence the consistency level for reads and writes - # can be set separately. - # - # This can also be overridden programmatically with GraphStatement.setReadConsistencyLevel(). If - # both are specified, the programmatic value takes precedence, and this option is ignored. - # - # Required: no (defaults to request.basic.consistency) - # Modifiable at runtime: yes, the new value will be used for requests issued after the change. - # Overridable in a profile: yes - // read-consistency-level = LOCAL_QUORUM - - # The write consistency level to use for graph statements. - # - # DSE Graph is able to distinguish between read and write timeouts for the internal storage - # queries that will be produced by a traversal. Hence the consistency level for reads and writes - # can be set separately. - # - # This can also be overridden programmatically with GraphStatement.setReadConsistencyLevel(). If - # both are specified, the programmatic value takes precedence, and this option is ignored. - # - # Required: no (defaults to request.basic.consistency) - # Modifiable at runtime: yes, the new value will be used for requests issued after the change. - # Overridable in a profile: yes - // write-consistency-level = LOCAL_ONE - - # How long the driver waits for a graph request to complete. This is a global limit on the - # duration of a session.execute() call, including any internal retries the driver might do. - # - # Graph statements behave a bit differently than regular CQL requests (hence this dedicated - # option instead of reusing basic.request.timeout): by default, the client timeout is not set, - # and the driver will just wait as long as needed until the server replies (which is itself - # governed by server-side timeout configuration). - # If you specify a client timeout with this option, then the driver will fail the request after - # the given time; note that the value is also sent along with the request, so that the server - # can also time out early and avoid wasting resources on a response that the client has already - # given up on. - # - # This can also be overridden programmatically with GraphStatement.setTimeout(). If both are - # specified, the programmatic value takes precedence, and this option is ignored. - # - # If this value is left unset (default) or is explicitly set to zero, no timeout will be - # applied. - # - # Required: no (defaults to zero - no timeout) - # Modifiable at runtime: yes, the new value will be used for requests issued after the change. - # Overridable in a profile: yes - // timeout = 10 seconds - } - - # ADVANCED OPTIONS ------------------------------------------------------------------------------- # The maximum number of live sessions that are allowed to coexist in a given VM. @@ -777,63 +667,25 @@ datastax-java-driver { # Note that the contents of this section can be overridden programmatically with # SessionBuilder.withAuthProvider or SessionBuilder.withAuthCredentials. advanced.auth-provider { - # The class of the provider. If it is not qualified, the driver assumes that it resides in one - # of the following packages: + # The class of the provider. If it is not qualified, the driver assumes that it resides in the + # following package: # - com.datastax.oss.driver.internal.core.auth - # - com.datastax.dse.driver.internal.core.auth # - # The driver provides two implementations: + # The driver provides one implementation: # - PlainTextAuthProvider: uses plain-text credentials. It requires the `username` and - # `password` options below. When connecting to DataStax Enterprise, an optional - # `authorization-id` can also be specified. - # For backward compatibility with previous driver versions, you can also use the class name - # "DsePlainTextAuthProvider" for this provider. - # - DseGssApiAuthProvider: provides GSSAPI authentication for DSE clusters secured with - # DseAuthenticator. See the example below and refer to the manual for detailed instructions. + # `password` options below. # # You can also specify a custom class that implements AuthProvider and has a public constructor - # with a DriverContext argument (to simplify this, the driver provides two abstract classes that - # can be extended: PlainTextAuthProviderBase and DseGssApiAuthProviderBase). + # with a DriverContext argument. PlainTextAuthProviderBase can be extended to simplify custom + # providers that use plain-text credentials. # # Finally, you can configure a provider instance programmatically with - # DseSessionBuilder#withAuthProvider. In that case, it will take precedence over the - # configuration. + # SessionBuilder#withAuthProvider. In that case, it will take precedence over the configuration. // class = PlainTextAuthProvider # # Sample configuration for plain-text authentication providers: // username = cassandra // password = cassandra - # - # Proxy authentication: allows to login as another user or role (valid for both - # PlainTextAuthProvider and DseGssApiAuthProvider): - // authorization-id = userOrRole - # - # The settings below are only applicable to DseGssApiAuthProvider: - # - # Service name. For example, if in your dse.yaml configuration file the - # "kerberos_options/service_principal" setting is "cassandra/my.host.com@MY.REALM.COM", then set - # this option to "cassandra". If this value is not explicitly set via configuration (in an - # application.conf or programmatically), the driver will attempt to set it via a System - # property. The property should be "dse.sasl.service". For backwards compatibility with 1.x - # versions of the driver, if "dse.sasl.service" is not set as a System property, the driver will - # attempt to use "dse.sasl.protocol" as a fallback (which is the property for the 1.x driver). - //service = "cassandra" - # - # Login configuration. It is also possible to provide login configuration through a standard - # JAAS configuration file. The below configuration is just an example, see all possible options - # here: - # https://docs.oracle.com/javase/6/docs/jre/api/security/jaas/spec/com/sun/security/auth/module/Krb5LoginModule.html - // login-configuration { - // principal = "cassandra@DATASTAX.COM" - // useKeyTab = "true" - // refreshKrb5Config = "true" - // keyTab = "/path/to/keytab/file" - // } - # - # Internal SASL properties, if any, such as QOP. - // sasl-properties { - // javax.security.sasl.qop = "auth-conf" - // } } # The SSL engine factory that will initialize an SSL engine for each new connection to a server. @@ -1369,204 +1221,6 @@ datastax-java-driver { log-warnings = true } - # Graph (DataStax Enterprise only) - advanced.graph { - # The sub-protocol the driver will use to communicate with DSE Graph, on top of the Cassandra - # native protocol. - # - # You should almost never have to change this: the driver sets it automatically, based on the - # information it has about the server. One exception is if you use the script API against a - # legacy DSE version (5.0.3 or older). In that case, you need to force the sub-protocol to - # "graphson-1.0". - # - # This can also be overridden programmatically with GraphStatement.setSubProtocol(). If both are - # specified, the programmatic value takes precedence, and this option is ignored. - # - # Possible values with built-in support in the driver are: - # [ "graphson-1.0", "graphson-2.0", "graph-binary-1.0"] - # - # IMPORTANT: The default value for the Graph sub-protocol is based only on the DSE - # version. If the version is DSE 6.7 and lower, "graphson-2.0" will be the default. For DSE 6.8 - # and higher, the default value is "graphson-binary-1.0". - # - # Required: no - # Modifiable at runtime: yes, the new value will be used for requests issued after the change. - # Overridable in a profile: yes - // sub-protocol = "graphson-2.0" - - # - # Whether or not Graph paging should be enabled or disabled for all queries. - # - #

If AUTO is set, the driver will decide whether or not to enable Graph paging - # based on the protocol version in use and the DSE version of all hosts. For this reason it is - # usually not necessary to change this setting. - # - #

IMPORTANT: Paging for DSE Graph is only available in DSE 6.8 and higher, and - # requires protocol version DSE_V1 or higher and graphs created with the Native engine; enabling - # paging for clusters and graphs that do not meet this requirement may result in query failures. - # - # Supported values are: ENABLED, DISABLED, AUTO - paging-enabled = "AUTO" - - - paging-options { - - # The page size. - # - # The value specified here can be interpreted in number of rows. - # Interpetation in number of bytes is not supported for graph continuous paging queries. - # - # It controls how many rows will be retrieved simultaneously in a single - # network roundtrip (the goal being to avoid loading too many results in memory at the same - # time). If there are more results, additional requests will be used to retrieve them (either - # automatically if you iterate with the sync API, or explicitly with the async API's - # fetchNextPage method). - # - # The default is the same as the driver's normal request page size, - # i.e., 5000 (rows). - # - # Required: yes - # Modifiable at runtime: yes, the new value will be used for continuous requests issued after - # the change - # Overridable in a profile: yes - page-size = ${datastax-java-driver.advanced.continuous-paging.page-size} - - # The maximum number of pages to return. - # - # The default is zero, which means retrieve all pages. - # - # Required: yes - # Modifiable at runtime: yes, the new value will be used for continuous requests issued after - # the change - # Overridable in a profile: yes - max-pages = ${datastax-java-driver.advanced.continuous-paging.max-pages} - - # Returns the maximum number of pages per second. - # - # The default is zero, which means no limit. - # - # Required: yes - # Modifiable at runtime: yes, the new value will be used for continuous requests issued after - # the change - # Overridable in a profile: yes - max-pages-per-second = ${datastax-java-driver.advanced.continuous-paging.max-pages-per-second} - - # Returns the maximum number of pages per second. - # - # The default is zero, which means no limit. - # - # Required: yes - # Modifiable at runtime: yes, the new value will be used for continuous requests issued after - # the change - # Overridable in a profile: yes - max-enqueued-pages = ${datastax-java-driver.advanced.continuous-paging.max-enqueued-pages} - } - } - - # Continuous paging (DataStax Enterprise only) - advanced.continuous-paging { - - # The page size. - # - # The value specified here can be interpreted in number of rows - # or in number of bytes, depending on the unit defined with page-unit (see below). - # - # It controls how many rows (or how much data) will be retrieved simultaneously in a single - # network roundtrip (the goal being to avoid loading too many results in memory at the same - # time). If there are more results, additional requests will be used to retrieve them (either - # automatically if you iterate with the sync API, or explicitly with the async API's - # fetchNextPage method). - # - # The default is the same as the driver's normal request page size, - # i.e., 5000 (rows). - # - # Required: yes - # Modifiable at runtime: yes, the new value will be used for continuous requests issued after - # the change - # Overridable in a profile: yes - page-size = ${datastax-java-driver.basic.request.page-size} - - # Whether the page-size option should be interpreted in number of rows or bytes. - # - # The default is false, i.e., the page size will be interpreted in number of rows. - # - # Required: yes - # Modifiable at runtime: yes, the new value will be used for continuous requests issued after - # the change - # Overridable in a profile: yes - page-size-in-bytes = false - - # The maximum number of pages to return. - # - # The default is zero, which means retrieve all pages. - # - # Required: yes - # Modifiable at runtime: yes, the new value will be used for continuous requests issued after - # the change - # Overridable in a profile: yes - max-pages = 0 - - # Returns the maximum number of pages per second. - # - # The default is zero, which means no limit. - # - # Required: yes - # Modifiable at runtime: yes, the new value will be used for continuous requests issued after - # the change - # Overridable in a profile: yes - max-pages-per-second = 0 - - # The maximum number of pages that can be stored in the local queue. - # - # This value must be positive. The default is 4. - # - # Required: yes - # Modifiable at runtime: yes, the new value will be used for continuous requests issued after - # the change - # Overridable in a profile: yes - max-enqueued-pages = 4 - - # Timeouts for continuous paging. - # - # Note that there is no global timeout for continuous paging as there is - # for regular queries, because continuous paging queries can take an arbitrarily - # long time to complete. - # - # Instead, timeouts are applied to each exchange between the driver and the coordinator. In - # other words, if the driver decides to retry, all timeouts are reset. - timeout { - - # How long to wait for the coordinator to send the first page. - # - # Required: yes - # Modifiable at runtime: yes, the new value will be used for continuous requests issued after - # the change - # Overridable in a profile: yes - first-page = 2 seconds - - # How long to wait for the coordinator to send subsequent pages. - # - # Required: yes - # Modifiable at runtime: yes, the new value will be used for continuous requests issued after - # the change - # Overridable in a profile: yes - other-pages = 1 second - - } - } - - # DataStax Insights - advanced.monitor-reporting { - # Whether to send monitoring events. - # - # The default is true. - # - # Required: no (defaults to true) - # Modifiable at runtime: no - # Overridable in a profile: no - enabled = true - } - advanced.metrics { # Metrics Factory configuration. factory { @@ -1728,37 +1382,6 @@ datastax-java-driver { # a Counter) // throttling.errors, - # The throughput and latency percentiles of DSE continuous CQL requests (exposed as a - # Timer). - # - # This metric is a session-level metric and corresponds to the overall duration of the - # session.executeContinuously() call, including any retry. - # - # Note that this metric is analogous to the OSS driver's 'cql-requests' metrics, but for - # continuous paging requests only. Continuous paging requests do not update the - # 'cql-requests' metric, because they are usually much longer. Only the following metrics - # are updated during a continuous paging request: - # - # - At node level: all the usual metrics available for normal CQL requests, such as - # 'cql-messages' and error-related metrics (but these are only updated for the first - # page of results); - # - At session level: only 'continuous-cql-requests' is updated (this metric). - // continuous-cql-requests, - - # The throughput and latency percentiles of Graph requests (exposed as a Timer). - # - # This metric is a session-level metric and corresponds to the overall duration of the - # session.execute(GraphStatement) call, including any retry. - // graph-requests, - - # The number of graph requests that timed out -- that is, the - # session.execute(GraphStatement) call failed with a DriverTimeoutException (exposed as a - # Counter). - # - # Note that this metric is analogous to the OSS driver's 'cql-client-timeouts' metrics, but - # for Graph requests only. - // graph-client-timeouts - ] # Extra configuration (for the metrics that need it) @@ -1837,30 +1460,6 @@ datastax-java-driver { // publish-percentiles = [ 0.75, 0.95, 0.99 ] } - # Required: if the 'continuous-cql-requests' metric is enabled, and Dropwizard or Micrometer - # is used. - # Modifiable at runtime: no - # Overridable in a profile: no - continuous-cql-requests { - highest-latency = 120 seconds - lowest-latency = 10 milliseconds - significant-digits = 3 - refresh-interval = 5 minutes - // slo = [ 100 milliseconds, 500 milliseconds, 1 second ] - // publish-percentiles = [ 0.75, 0.95, 0.99 ] - } - - # Required: if the 'graph-requests' metric is enabled, and Dropwizard or Micrometer is used. - # Modifiable at runtime: no - # Overridable in a profile: no - graph-requests { - highest-latency = 12 seconds - lowest-latency = 1 millisecond - significant-digits = 3 - refresh-interval = 5 minutes - // slo = [ 100 milliseconds, 500 milliseconds, 1 second ] - // publish-percentiles = [ 0.75, 0.95, 0.99 ] - } } # The node-level metrics (all disabled by default). # @@ -2000,17 +1599,6 @@ datastax-java-driver { # Authentication errors are also logged at WARN level. // errors.connection.auth, - # The throughput and latency percentiles of individual graph messages sent to this node as - # part of an overall request (exposed as a Timer). - # - # Note that this does not necessarily correspond to the overall duration of the - # session.execute() call, since the driver might query multiple nodes because of retries - # and speculative executions. Therefore a single "request" (as seen from a client of the - # driver) can be composed of more than one of the "messages" measured by this metric. - # - # Therefore this metric is intended as an insight into the performance of this particular - # node. For statistics on overall request completion, use the session-level graph-requests. - // graph-messages, ] # See cql-requests in the `session` section @@ -2027,20 +1615,6 @@ datastax-java-driver { // publish-percentiles = [ 0.75, 0.95, 0.99 ] } - # See graph-requests in the `session` section - # - # Required: if the 'graph-messages' metric is enabled, and Dropwizard or Micrometer is used. - # Modifiable at runtime: no - # Overridable in a profile: no - graph-messages { - highest-latency = 3 seconds - lowest-latency = 1 millisecond - significant-digits = 3 - refresh-interval = 5 minutes - // slo = [ 100 milliseconds, 500 milliseconds, 1 second ] - // publish-percentiles = [ 0.75, 0.95, 0.99 ] - } - # The time after which the node level metrics will be evicted. # # This is used to unregister stale metrics if a node leaves the cluster or gets a new address. @@ -2230,12 +1804,12 @@ datastax-java-driver { # server side with a WHERE IN clause. If you use any other rule, it has to fetch all system # rows and filter on the client side. # - # Required: no. The default value excludes all Cassandra and DSE system keyspaces. If the + # Required: no. The default value excludes all Cassandra system keyspaces. If the # option is unset, this is interpreted as "include all keyspaces". # Modifiable at runtime: yes, the new value will be used for refreshes issued after the # change. # Overridable in a profile: no - refreshed-keyspaces = [ "!system", "!/^system_.*/", "!/^dse_.*/", "!solr_admin", "!OpsCenter" ] + refreshed-keyspaces = [ "!system", "!/^system_.*/" ] # The timeout for the requests to the schema tables. # @@ -2580,20 +2154,5 @@ datastax-java-driver { # olap { # basic.request.timeout = 5 seconds # } - - # An example configuration profile for graph requests. - // my-graph-profile-example { - // graph { - // read-consistency-level = LOCAL_QUORUM - // write-consistency-level = LOCAL_ONE - // } - // } - - # An example pre-defined configuration profile for OLAP graph queries. - // graph-olap { - // graph { - // traversal-source = "a" // traversal source needs to be set to "a" for OLAP queries. - // } - // } } } diff --git a/core/src/test/java/com/datastax/dse/driver/Assertions.java b/core/src/test/java/com/datastax/dse/driver/Assertions.java deleted file mode 100644 index 09f7b281f84..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/Assertions.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver; - -import org.apache.tinkerpop.gremlin.structure.io.Buffer; - -public class Assertions extends org.assertj.core.api.Assertions { - public static TinkerpopBufferAssert assertThat(Buffer actual) { - return new TinkerpopBufferAssert(actual); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/DriverRunListener.java b/core/src/test/java/com/datastax/dse/driver/DriverRunListener.java deleted file mode 100644 index 65e58878dbc..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/DriverRunListener.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver; - -import static org.assertj.core.api.Assertions.fail; - -import org.junit.runner.Description; -import org.junit.runner.notification.RunListener; - -/** - * Common parent of all driver tests, to store common configuration and perform sanity checks. - * - * @see "maven-surefire-plugin configuration in pom.xml" - */ -public class DriverRunListener extends RunListener { - - @Override - public void testFinished(Description description) throws Exception { - // If a test interrupted the main thread silently, this can make later tests fail. Instead, we - // fail the test and clear the interrupt status. - // Note: Thread.interrupted() also clears the flag, which is what we want. - if (Thread.interrupted()) { - fail(description.getMethodName() + " interrupted the main thread"); - } - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/DseTestDataProviders.java b/core/src/test/java/com/datastax/dse/driver/DseTestDataProviders.java deleted file mode 100644 index 7d9aecc28ed..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/DseTestDataProviders.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver; - -import static com.datastax.dse.driver.internal.core.graph.GraphProtocol.GRAPHSON_1_0; -import static com.datastax.dse.driver.internal.core.graph.GraphProtocol.GRAPHSON_2_0; -import static com.datastax.dse.driver.internal.core.graph.GraphProtocol.GRAPH_BINARY_1_0; - -import com.datastax.dse.driver.api.core.DseProtocolVersion; -import com.datastax.dse.driver.api.core.graph.ScriptGraphStatement; -import com.datastax.oss.driver.TestDataProviders; -import com.datastax.oss.driver.api.core.DefaultProtocolVersion; -import com.tngtech.java.junit.dataprovider.DataProvider; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Arrays; -import java.util.stream.Stream; - -public class DseTestDataProviders { - - private static final ScriptGraphStatement UNDEFINED_IDEMPOTENCE_STATEMENT = - ScriptGraphStatement.newInstance("undefined idempotence"); - private static final ScriptGraphStatement IDEMPOTENT_STATEMENT = - ScriptGraphStatement.builder("idempotent").setIdempotence(true).build(); - private static final ScriptGraphStatement NON_IDEMPOTENT_STATEMENT = - ScriptGraphStatement.builder("non idempotent").setIdempotence(false).build(); - - @DataProvider - public static Object[][] allDseProtocolVersions() { - return concat(DseProtocolVersion.values()); - } - - @DataProvider - public static Object[][] allOssProtocolVersions() { - return concat(DefaultProtocolVersion.values()); - } - - @DataProvider - public static Object[][] allDseAndOssProtocolVersions() { - return concat(DefaultProtocolVersion.values(), DseProtocolVersion.values()); - } - - @DataProvider - public static Object[][] supportedGraphProtocols() { - return new Object[][] {{GRAPHSON_1_0}, {GRAPHSON_2_0}, {GRAPH_BINARY_1_0}}; - } - - /** - * The combination of the default idempotence option and statement setting that produce an - * idempotent statement. - */ - @DataProvider - public static Object[][] idempotentGraphConfig() { - return new Object[][] { - new Object[] {true, UNDEFINED_IDEMPOTENCE_STATEMENT}, - new Object[] {false, IDEMPOTENT_STATEMENT}, - new Object[] {true, IDEMPOTENT_STATEMENT}, - }; - } - - /** - * The combination of the default idempotence option and statement setting that produce a non - * idempotent statement. - */ - @DataProvider - public static Object[][] nonIdempotentGraphConfig() { - return new Object[][] { - new Object[] {false, UNDEFINED_IDEMPOTENCE_STATEMENT}, - new Object[] {true, NON_IDEMPOTENT_STATEMENT}, - new Object[] {false, NON_IDEMPOTENT_STATEMENT}, - }; - } - - @DataProvider - public static Object[][] allDseProtocolVersionsAndSupportedGraphProtocols() { - return TestDataProviders.combine(allDseProtocolVersions(), supportedGraphProtocols()); - } - - @NonNull - private static Object[][] concat(Object[]... values) { - return Stream.of(values) - .flatMap(Arrays::stream) - .map(o -> new Object[] {o}) - .toArray(Object[][]::new); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/TinkerpopBufferAssert.java b/core/src/test/java/com/datastax/dse/driver/TinkerpopBufferAssert.java deleted file mode 100644 index 278e5a65070..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/TinkerpopBufferAssert.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.oss.protocol.internal.util.Bytes; -import org.apache.tinkerpop.gremlin.structure.io.Buffer; -import org.assertj.core.api.AbstractAssert; - -public class TinkerpopBufferAssert extends AbstractAssert { - public TinkerpopBufferAssert(Buffer actual) { - super(actual, TinkerpopBufferAssert.class); - } - - public TinkerpopBufferAssert containsExactly(String hexString) { - - byte[] expectedBytes = Bytes.fromHexString(hexString).array(); - byte[] actualBytes = new byte[expectedBytes.length]; - actual.readBytes(actualBytes); - assertThat(actualBytes).containsExactly(expectedBytes); - assertThat(actual.readableBytes()).isEqualTo(0); - return this; - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/api/core/data/time/DateRangePrecisionTest.java b/core/src/test/java/com/datastax/dse/driver/api/core/data/time/DateRangePrecisionTest.java deleted file mode 100644 index 4cf8d43b748..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/api/core/data/time/DateRangePrecisionTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.data.time; - -import static org.assertj.core.api.Assertions.assertThat; - -import java.time.ZonedDateTime; -import org.junit.Test; - -public class DateRangePrecisionTest { - - @Test - public void should_round_up() { - ZonedDateTime timestamp = ZonedDateTime.parse("2011-02-03T04:05:16.789Z"); - assertThat(DateRangePrecision.MILLISECOND.roundUp(timestamp)) - .isEqualTo("2011-02-03T04:05:16.789Z"); - assertThat(DateRangePrecision.SECOND.roundUp(timestamp)).isEqualTo("2011-02-03T04:05:16.999Z"); - assertThat(DateRangePrecision.MINUTE.roundUp(timestamp)).isEqualTo("2011-02-03T04:05:59.999Z"); - assertThat(DateRangePrecision.HOUR.roundUp(timestamp)).isEqualTo("2011-02-03T04:59:59.999Z"); - assertThat(DateRangePrecision.DAY.roundUp(timestamp)).isEqualTo("2011-02-03T23:59:59.999Z"); - assertThat(DateRangePrecision.MONTH.roundUp(timestamp)).isEqualTo("2011-02-28T23:59:59.999Z"); - assertThat(DateRangePrecision.YEAR.roundUp(timestamp)).isEqualTo("2011-12-31T23:59:59.999Z"); - } - - @Test - public void should_round_down() { - ZonedDateTime timestamp = ZonedDateTime.parse("2011-02-03T04:05:16.789Z"); - assertThat(DateRangePrecision.MILLISECOND.roundDown(timestamp)) - .isEqualTo("2011-02-03T04:05:16.789Z"); - assertThat(DateRangePrecision.SECOND.roundDown(timestamp)) - .isEqualTo("2011-02-03T04:05:16.000Z"); - assertThat(DateRangePrecision.MINUTE.roundDown(timestamp)) - .isEqualTo("2011-02-03T04:05:00.000Z"); - assertThat(DateRangePrecision.HOUR.roundDown(timestamp)).isEqualTo("2011-02-03T04:00:00.000Z"); - assertThat(DateRangePrecision.DAY.roundDown(timestamp)).isEqualTo("2011-02-03T00:00:00.000Z"); - assertThat(DateRangePrecision.MONTH.roundDown(timestamp)).isEqualTo("2011-02-01T00:00:00.000Z"); - assertThat(DateRangePrecision.YEAR.roundDown(timestamp)).isEqualTo("2011-01-01T00:00:00.000Z"); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/api/core/data/time/DateRangeTest.java b/core/src/test/java/com/datastax/dse/driver/api/core/data/time/DateRangeTest.java deleted file mode 100644 index b067c12cad0..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/api/core/data/time/DateRangeTest.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.data.time; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import com.datastax.oss.driver.internal.SerializationHelper; -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import java.text.ParseException; -import java.time.temporal.ChronoField; -import java.util.function.Predicate; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(DataProviderRunner.class) -public class DateRangeTest { - - @Test - @UseDataProvider("rangeStrings") - public void should_parse_and_format(String source) throws Exception { - DateRange parsed = DateRange.parse(source); - assertThat(parsed.toString()).isEqualTo(source); - } - - @DataProvider - public static Object[][] rangeStrings() { - return new Object[][] { - {"[2011-01 TO 2015]"}, - {"[2010-01-02 TO 2015-05-05T13]"}, - {"[1973-06-30T13:57:28.123Z TO 1999-05-05T14:14:59]"}, - // leap year - {"[2010-01-01T15 TO 2016-02]"}, - // pre-epoch - {"[1500 TO 1501]"}, - {"[0001 TO 0001-01-02]"}, - {"[0000 TO 0000-01-02]"}, - {"[-0001 TO -0001-01-02]"}, - // unbounded - {"[* TO 2014-12-01]"}, - {"[1999 TO *]"}, - {"[* TO *]"}, - // single bound ranges - // AD/BC era boundary - {"0001-01-01"}, - {"-0001-01-01"}, - {"-0009"}, - {"2000-11"}, - {"*"} - }; - } - - @Test - public void should_use_proleptic_parser() throws Exception { - DateRange parsed = DateRange.parse("[0000 TO 0000-01-02]"); - assertThat(parsed.getLowerBound().getTimestamp().get(ChronoField.YEAR)).isEqualTo(0); - } - - @Test - public void should_fail_to_parse_invalid_strings() { - assertThatThrownBy(() -> DateRange.parse("foo")).matches(hasOffset(0)); - assertThatThrownBy(() -> DateRange.parse("[foo TO *]")).matches(hasOffset(1)); - assertThatThrownBy(() -> DateRange.parse("[* TO foo]")).matches(hasOffset(6)); - } - - private static Predicate hasOffset(int offset) { - return e -> ((ParseException) e).getErrorOffset() == offset; - } - - @Test - public void should_fail_to_parse_inverted_range() { - assertThatThrownBy(() -> DateRange.parse("[2001-01 TO 2000]")) - .hasMessage( - "Lower bound of a date range should be before upper bound, got: [2001-01 TO 2000]"); - } - - @Test - public void should_not_equate_single_date_open_to_both_open_range() throws Exception { - assertThat(DateRange.parse("*")).isNotEqualTo(DateRange.parse("[* TO *]")); - } - - @Test - public void should_not_equate_same_ranges_with_different_precisions() throws ParseException { - assertThat(DateRange.parse("[2001 TO 2002]")) - .isNotEqualTo(DateRange.parse("[2001-01 TO 2002-12]")); - } - - @Test - public void should_give_same_hashcode_to_equal_objects() throws ParseException { - assertThat(DateRange.parse("[2001 TO 2002]").hashCode()) - .isEqualTo(DateRange.parse("[2001 TO 2002]").hashCode()); - } - - @Test - public void should_serialize_and_deserialize() throws Exception { - DateRange initial = DateRange.parse("[1973-06-30T13:57:28.123Z TO 1999-05-05T14:14:59]"); - DateRange deserialized = SerializationHelper.serializeAndDeserialize(initial); - assertThat(deserialized).isEqualTo(initial); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/api/core/graph/predicates/CqlCollectionTest.java b/core/src/test/java/com/datastax/dse/driver/api/core/graph/predicates/CqlCollectionTest.java deleted file mode 100644 index a890720a3ef..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/api/core/graph/predicates/CqlCollectionTest.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph.predicates; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import com.datastax.oss.driver.shaded.guava.common.collect.Lists; -import com.datastax.oss.driver.shaded.guava.common.collect.Sets; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.Map; -import org.apache.tinkerpop.gremlin.process.traversal.P; -import org.junit.Test; - -public class CqlCollectionTest { - - @Test - public void should_evaluate_contains() { - P> contains = CqlCollection.contains("foo"); - assertThat(contains.test(new HashSet<>())).isFalse(); - assertThat(contains.test(new ArrayList<>())).isFalse(); - assertThat(contains.test(Sets.newHashSet("foo"))).isTrue(); - assertThat(contains.test(Lists.newArrayList("foo"))).isTrue(); - assertThat(contains.test(Sets.newHashSet("bar"))).isFalse(); - assertThat(contains.test(Lists.newArrayList("bar"))).isFalse(); - assertThatThrownBy(() -> contains.test(null)).isInstanceOf(IllegalArgumentException.class); - assertThatThrownBy(() -> CqlCollection.contains(null).test(Sets.newHashSet("foo"))) - .isInstanceOf(IllegalArgumentException.class); - } - - @Test - public void should_evaluate_containsKey() { - P> containsKey = CqlCollection.containsKey("foo"); - assertThat(containsKey.test(new HashMap<>())).isFalse(); - assertThat(containsKey.test(new LinkedHashMap<>())).isFalse(); - assertThat(containsKey.test(ImmutableMap.of("foo", "bar"))).isTrue(); - assertThat(containsKey.test(ImmutableMap.of("bar", "foo"))).isFalse(); - assertThatThrownBy(() -> containsKey.test(null)).isInstanceOf(IllegalArgumentException.class); - assertThatThrownBy(() -> CqlCollection.containsKey(null).test(ImmutableMap.of("foo", "bar"))) - .isInstanceOf(IllegalArgumentException.class); - } - - @Test - public void should_evaluate_containsValue() { - P> containsValue = CqlCollection.containsValue("foo"); - assertThat(containsValue.test(new HashMap<>())).isFalse(); - assertThat(containsValue.test(new LinkedHashMap<>())).isFalse(); - assertThat(containsValue.test(ImmutableMap.of("bar", "foo"))).isTrue(); - assertThat(containsValue.test(ImmutableMap.of("foo", "bar"))).isFalse(); - assertThatThrownBy(() -> containsValue.test(null)).isInstanceOf(IllegalArgumentException.class); - assertThatThrownBy(() -> CqlCollection.containsValue(null).test(ImmutableMap.of("foo", "bar"))) - .isInstanceOf(IllegalArgumentException.class); - } - - @Test - public void should_evaluate_entryEq() { - P> entryEq = CqlCollection.entryEq("foo", "bar"); - assertThat(entryEq.test(new HashMap<>())).isFalse(); - assertThat(entryEq.test(new LinkedHashMap<>())).isFalse(); - assertThat(entryEq.test(ImmutableMap.of("foo", "bar"))).isTrue(); - assertThat(entryEq.test(ImmutableMap.of("bar", "foo"))).isFalse(); - assertThatThrownBy(() -> entryEq.test(null)).isInstanceOf(IllegalArgumentException.class); - assertThatThrownBy(() -> CqlCollection.entryEq(null, "foo").test(ImmutableMap.of("foo", "bar"))) - .isInstanceOf(IllegalArgumentException.class); - assertThatThrownBy(() -> CqlCollection.entryEq("foo", null).test(ImmutableMap.of("foo", "bar"))) - .isInstanceOf(IllegalArgumentException.class); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/api/core/graph/predicates/GeoTest.java b/core/src/test/java/com/datastax/dse/driver/api/core/graph/predicates/GeoTest.java deleted file mode 100644 index 143aec97b78..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/api/core/graph/predicates/GeoTest.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph.predicates; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.dse.driver.api.core.data.geometry.LineString; -import com.datastax.dse.driver.api.core.data.geometry.Point; -import com.datastax.dse.driver.api.core.data.geometry.Polygon; -import org.apache.tinkerpop.gremlin.process.traversal.P; -import org.junit.Test; - -public class GeoTest { - - @Test - public void should_convert_units_to_degrees() { - assertThat(Geo.Unit.DEGREES.toDegrees(100.0)).isEqualTo(100.0); - assertThat(Geo.Unit.MILES.toDegrees(68.9722)).isEqualTo(0.9982455747535043); - assertThat(Geo.Unit.KILOMETERS.toDegrees(111.0)).isEqualTo(0.9982456082154465); - assertThat(Geo.Unit.METERS.toDegrees(111000.0)).isEqualTo(0.9982456082154464); - } - - @Test - public void should_test_if_point_is_inside_circle_with_cartesian_coordinates() { - P inside = Geo.inside(Point.fromCoordinates(30, 30), 14.142135623730951); - assertThat(inside.test(Point.fromCoordinates(40, 40))).isTrue(); - assertThat(inside.test(Point.fromCoordinates(40.1, 40))).isFalse(); - } - - @Test - public void should_test_if_point_is_inside_circle_with_geo_coordinates() { - P inside = - Geo.inside(Point.fromCoordinates(30, 30), 12.908258700131379, Geo.Unit.DEGREES); - assertThat(inside.test(Point.fromCoordinates(40, 40))).isTrue(); - assertThat(inside.test(Point.fromCoordinates(40.1, 40))).isFalse(); - } - - @Test - public void should_test_if_point_is_inside_polygon() { - P inside = - Geo.inside( - Polygon.builder() - .addRing( - Point.fromCoordinates(30, 30), - Point.fromCoordinates(40, 40), - Point.fromCoordinates(40, 30)) - .build()); - assertThat(inside.test(Point.fromCoordinates(35, 32))).isTrue(); - assertThat(inside.test(Point.fromCoordinates(33, 37))).isFalse(); - } - - @Test - public void should_build_line_string_from_coordinates() { - LineString lineString = Geo.lineString(1, 2, 3, 4, 5, 6); - assertThat(lineString.getPoints()) - .hasSize(3) - .contains(Point.fromCoordinates(1, 2)) - .contains(Point.fromCoordinates(3, 4)) - .contains(Point.fromCoordinates(5, 6)); - } - - @Test(expected = IllegalArgumentException.class) - public void should_fail_to_build_line_string_if_not_enough_coordinates() { - Geo.lineString(1, 2); - } - - @Test(expected = IllegalArgumentException.class) - public void should_fail_to_build_line_string_if_uneven_number_of_coordinates() { - Geo.lineString(1, 2, 3, 4, 5); - } - - @Test - public void should_build_polygon_from_coordinates() { - Polygon polygon = Geo.polygon(1, 2, 3, 4, 5, 6, 7, 8); - assertThat(polygon.getExteriorRing()) - .hasSize(4) - .contains(Point.fromCoordinates(1, 2)) - .contains(Point.fromCoordinates(3, 4)) - .contains(Point.fromCoordinates(5, 6)) - .contains(Point.fromCoordinates(7, 8)); - assertThat(polygon.getInteriorRings()).isEmpty(); - } - - @Test(expected = IllegalArgumentException.class) - public void should_fail_to_build_polygon_if_not_enough_coordinates() { - Geo.polygon(1, 2, 3, 4); - } - - @Test(expected = IllegalArgumentException.class) - public void should_fail_to_build_polygon_if_uneven_number_of_coordinates() { - Geo.polygon(1, 2, 3, 4, 5, 6, 7); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/api/core/graph/predicates/SearchTest.java b/core/src/test/java/com/datastax/dse/driver/api/core/graph/predicates/SearchTest.java deleted file mode 100644 index 591269e31ad..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/api/core/graph/predicates/SearchTest.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph.predicates; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.apache.tinkerpop.gremlin.process.traversal.P; -import org.junit.Test; - -public class SearchTest { - - @Test - public void testToken() { - P p = Search.token("needle"); - assertThat(p.test("needle")).isTrue(); - assertThat(p.test("This is a needle in a haystack")).isTrue(); - assertThat(p.test("This is just the haystack")).isFalse(); - } - - @Test - public void testPrefix() { - P p = Search.prefix("abcd"); - assertThat(p.test("abcd")).isTrue(); - assertThat(p.test("abcdefg hijkl")).isTrue(); - assertThat(p.test("zabcd")).isFalse(); - } - - @Test - public void testTokenPrefix() { - P p = Search.tokenPrefix("abcd"); - assertThat(p.test("abcd")).isTrue(); - assertThat(p.test("abcdefg hijkl")).isTrue(); - assertThat(p.test("z abcd")).isTrue(); - assertThat(p.test("ab cd")).isFalse(); - } - - @Test - public void testRegex() { - P p = Search.regex("(foo|bar)"); - assertThat(p.test("foo")).isTrue(); - assertThat(p.test("bar")).isTrue(); - assertThat(p.test("foo bar")).isFalse(); - } - - @Test - public void testTokenRegex() { - P p = Search.tokenRegex("(foo|bar)"); - assertThat(p.test("foo")).isTrue(); - assertThat(p.test("bar")).isTrue(); - assertThat(p.test("foo bar")).isTrue(); - assertThat(p.test("foo bar qix")).isTrue(); - assertThat(p.test("qix")).isFalse(); - } - - @Test - public void testPhrase() { - P p = Search.phrase("Hello world", 2); - assertThat(p.test("Hello World")).isTrue(); - assertThat(p.test("Hello Big World")).isTrue(); - assertThat(p.test("Hello Big Wild World")).isTrue(); - assertThat(p.test("Hello The Big Wild World")).isFalse(); - assertThat(p.test("Goodbye world")).isFalse(); - } - - @Test - public void testPhraseFragment() { - // Tests JAVA-1744 - P p = Search.phrase("a b", 0); - assertThat(p.test("a b")).isTrue(); - assertThat(p.test("a")).isFalse(); - assertThat(p.test("b")).isFalse(); - } - - @Test - public void testFuzzy() { - P p = Search.fuzzy("abc", 1); - assertThat(p.test("abcd")).isTrue(); - assertThat(p.test("ab")).isTrue(); - assertThat(p.test("abce")).isTrue(); - assertThat(p.test("abdc")).isTrue(); - assertThat(p.test("badc")).isFalse(); - - // Make sure we do NOT calculate the Damerau–Levenshtein distance (2), but the optimal string - // alignment distance (3): - assertThat(Search.tokenFuzzy("ca", 2).test("abc")).isFalse(); - } - - @Test - public void testTokenFuzzy() { - P p = Search.tokenFuzzy("abc", 1); - assertThat(p.test("foo abcd")).isTrue(); - assertThat(p.test("foo ab")).isTrue(); - assertThat(p.test("foo abce")).isTrue(); - assertThat(p.test("foo abdc")).isTrue(); - assertThat(p.test("foo badc")).isFalse(); - - // Make sure we do NOT calculate the Damerau–Levenshtein distance (2), but the optimal string - // alignment distance (3): - assertThat(Search.tokenFuzzy("ca", 2).test("abc 123")).isFalse(); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/DependencyCheckTest.java b/core/src/test/java/com/datastax/dse/driver/internal/DependencyCheckTest.java deleted file mode 100644 index d001f791e82..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/DependencyCheckTest.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal; - -import java.nio.file.Path; -import java.nio.file.Paths; - -public class DependencyCheckTest extends DependencyCheckTestBase { - - @Override - protected Path getDepsTxtPath() { - return Paths.get( - getBaseResourcePathString(), - "target", - "classes", - "com", - "datastax", - "dse", - "driver", - "internal", - "deps.txt"); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/DependencyCheckTestBase.java b/core/src/test/java/com/datastax/dse/driver/internal/DependencyCheckTestBase.java deleted file mode 100644 index f2ce5513d65..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/DependencyCheckTestBase.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal; - -import static org.assertj.core.api.Assertions.assertThat; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Path; -import java.util.Properties; -import org.junit.Test; - -public abstract class DependencyCheckTestBase { - - private String baseResourcePath; - - protected DependencyCheckTestBase() { - Properties projectProperties = new Properties(); - try (InputStream is = this.getClass().getResourceAsStream("/project.properties")) { - projectProperties.load(is); - baseResourcePath = projectProperties.getProperty("project.basedir"); - } catch (IOException ioe) { - throw new AssertionError( - "Error retrieving \"project.basedir\" value from \"/project.properties\". Please check test resources in this project.", - ioe); - } - assert baseResourcePath != null; - } - - @Test - public void should_generate_deps_txt() { - assertThat(getDepsTxtPath()).exists(); - } - - protected final String getBaseResourcePathString() { - return baseResourcePath; - } - - protected abstract Path getDepsTxtPath(); -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/cql/continuous/ContinuousCqlRequestHandlerNodeTargetingTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/cql/continuous/ContinuousCqlRequestHandlerNodeTargetingTest.java deleted file mode 100644 index 1edb7c183bf..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/cql/continuous/ContinuousCqlRequestHandlerNodeTargetingTest.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.cql.continuous; - -import static com.datastax.oss.driver.Assertions.assertThatStage; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.never; - -import com.datastax.dse.driver.DseTestDataProviders; -import com.datastax.dse.driver.DseTestFixtures; -import com.datastax.dse.driver.api.core.DseProtocolVersion; -import com.datastax.dse.driver.api.core.cql.continuous.ContinuousAsyncResultSet; -import com.datastax.oss.driver.api.core.AllNodesFailedException; -import com.datastax.oss.driver.api.core.NodeUnavailableException; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.datastax.oss.driver.api.core.session.Request; -import com.datastax.oss.driver.api.core.session.Session; -import com.datastax.oss.driver.internal.core.cql.RequestHandlerTestHarness; -import com.datastax.oss.driver.internal.core.metadata.LoadBalancingPolicyWrapper; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CompletionStage; -import org.junit.Test; -import org.mockito.InOrder; -import org.mockito.Mockito; - -public class ContinuousCqlRequestHandlerNodeTargetingTest - extends ContinuousCqlRequestHandlerTestBase { - - @Test - @UseDataProvider(value = "allDseProtocolVersions", location = DseTestDataProviders.class) - public void should_fail_if_targeted_node_not_available(DseProtocolVersion version) { - try (RequestHandlerTestHarness harness = - continuousHarnessBuilder() - .withResponse(node1, defaultFrameOf(DseTestFixtures.singleDseRow())) - .withResponse(node2, defaultFrameOf(DseTestFixtures.singleDseRow())) - .withEmptyPool(node3) - .withProtocolVersion(version) - .build()) { - - LoadBalancingPolicyWrapper loadBalancingPolicy = - harness.getContext().getLoadBalancingPolicyWrapper(); - InOrder invocations = Mockito.inOrder(loadBalancingPolicy); - - // target node3, which should be unavailable - CompletionStage resultSetFuture = - new ContinuousCqlRequestHandler( - UNDEFINED_IDEMPOTENCE_STATEMENT.setNode(node3), - harness.getSession(), - harness.getContext(), - "target node 3, unavailable") - .handle(); - - assertThatStage(resultSetFuture) - .isFailed( - error -> { - assertThat(error).isInstanceOf(AllNodesFailedException.class); - Map> errors = - ((AllNodesFailedException) error).getAllErrors(); - assertThat(errors).hasSize(1); - List nodeErrors = errors.values().iterator().next(); - assertThat(nodeErrors).singleElement().isInstanceOf(NodeUnavailableException.class); - invocations - .verify(loadBalancingPolicy, never()) - .newQueryPlan(any(Request.class), anyString(), any(Session.class)); - }); - - resultSetFuture = - new ContinuousCqlRequestHandler( - UNDEFINED_IDEMPOTENCE_STATEMENT, - harness.getSession(), - harness.getContext(), - "no node targeting, should use node 1") - .handle(); - - assertThatStage(resultSetFuture) - .isSuccess( - resultSet -> { - assertThat(resultSet.getExecutionInfo().getCoordinator()).isEqualTo(node1); - invocations - .verify(loadBalancingPolicy) - .newQueryPlan( - UNDEFINED_IDEMPOTENCE_STATEMENT, - DriverExecutionProfile.DEFAULT_NAME, - harness.getSession()); - }); - - resultSetFuture = - new ContinuousCqlRequestHandler( - UNDEFINED_IDEMPOTENCE_STATEMENT, - harness.getSession(), - harness.getContext(), - "no node targeting, should use node 2") - .handle(); - - assertThatStage(resultSetFuture) - .isSuccess( - resultSet -> { - assertThat(resultSet.getExecutionInfo().getCoordinator()).isEqualTo(node2); - invocations - .verify(loadBalancingPolicy) - .newQueryPlan( - UNDEFINED_IDEMPOTENCE_STATEMENT, - DriverExecutionProfile.DEFAULT_NAME, - harness.getSession()); - }); - } - } - - @Test - @UseDataProvider(value = "allDseProtocolVersions", location = DseTestDataProviders.class) - public void should_target_node(DseProtocolVersion version) { - try (RequestHandlerTestHarness harness = - continuousHarnessBuilder() - .withResponse(node1, defaultFrameOf(DseTestFixtures.singleDseRow())) - .withResponse(node2, defaultFrameOf(DseTestFixtures.singleDseRow())) - .withResponse(node3, defaultFrameOf(DseTestFixtures.singleDseRow())) - .withProtocolVersion(version) - .build()) { - - LoadBalancingPolicyWrapper loadBalancingPolicy = - harness.getContext().getLoadBalancingPolicyWrapper(); - InOrder invocations = Mockito.inOrder(loadBalancingPolicy); - - CompletionStage resultSetFuture = - new ContinuousCqlRequestHandler( - UNDEFINED_IDEMPOTENCE_STATEMENT.setNode(node3), - harness.getSession(), - harness.getContext(), - "target node 3") - .handle(); - - assertThatStage(resultSetFuture) - .isSuccess( - resultSet -> { - assertThat(resultSet.getExecutionInfo().getCoordinator()).isEqualTo(node3); - invocations - .verify(loadBalancingPolicy, never()) - .newQueryPlan(any(Request.class), anyString(), any(Session.class)); - }); - - resultSetFuture = - new ContinuousCqlRequestHandler( - UNDEFINED_IDEMPOTENCE_STATEMENT, - harness.getSession(), - harness.getContext(), - "no node targeting") - .handle(); - - assertThatStage(resultSetFuture) - .isSuccess( - resultSet -> { - assertThat(resultSet.getExecutionInfo().getCoordinator()).isEqualTo(node1); - invocations - .verify(loadBalancingPolicy) - .newQueryPlan( - UNDEFINED_IDEMPOTENCE_STATEMENT, - DriverExecutionProfile.DEFAULT_NAME, - harness.getSession()); - }); - } - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/cql/continuous/ContinuousCqlRequestHandlerReprepareTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/cql/continuous/ContinuousCqlRequestHandlerReprepareTest.java deleted file mode 100644 index fd8d0ea1f98..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/cql/continuous/ContinuousCqlRequestHandlerReprepareTest.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.cql.continuous; - -import static com.datastax.oss.driver.Assertions.assertThat; -import static com.datastax.oss.driver.Assertions.assertThatStage; -import static com.datastax.oss.protocol.internal.Frame.NO_PAYLOAD; -import static org.assertj.core.api.Assertions.catchThrowable; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anyMap; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import com.datastax.dse.driver.DseTestDataProviders; -import com.datastax.dse.driver.DseTestFixtures; -import com.datastax.dse.driver.api.core.DseProtocolVersion; -import com.datastax.dse.driver.api.core.cql.continuous.ContinuousAsyncResultSet; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.servererrors.SyntaxError; -import com.datastax.oss.driver.internal.core.adminrequest.AdminRequestHandler; -import com.datastax.oss.driver.internal.core.adminrequest.UnexpectedResponseException; -import com.datastax.oss.driver.internal.core.cql.RequestHandlerTestHarness; -import com.datastax.oss.driver.internal.core.session.RepreparePayload; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import com.datastax.oss.protocol.internal.ProtocolConstants; -import com.datastax.oss.protocol.internal.ProtocolConstants.ErrorCode; -import com.datastax.oss.protocol.internal.request.Prepare; -import com.datastax.oss.protocol.internal.request.Query; -import com.datastax.oss.protocol.internal.response.Error; -import com.datastax.oss.protocol.internal.response.error.Unprepared; -import com.datastax.oss.protocol.internal.response.result.Prepared; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import io.netty.util.concurrent.Future; -import java.nio.ByteBuffer; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import org.junit.Test; -import org.mockito.Mock; - -public class ContinuousCqlRequestHandlerReprepareTest extends ContinuousCqlRequestHandlerTestBase { - - private final byte[] preparedId = {1, 2, 3}; - private final ByteBuffer preparedIdBuf = ByteBuffer.wrap(preparedId); - - private final RepreparePayload repreparePayload = - new RepreparePayload(preparedIdBuf, "irrelevant", CqlIdentifier.fromCql("ks"), NO_PAYLOAD); - - private final ConcurrentMap repreparePayloads = - new ConcurrentHashMap<>(ImmutableMap.of(preparedIdBuf, repreparePayload)); - - private final Unprepared unprepared = new Unprepared("test", preparedId); - private final Prepared prepared = new Prepared(preparedId, null, null, null); - private final Error unrecoverable = - new Error(ProtocolConstants.ErrorCode.SYNTAX_ERROR, "bad query"); - private final Error recoverable = new Error(ErrorCode.SERVER_ERROR, "sorry"); - - @Mock private Future future; - - @Override - public void setup() { - super.setup(); - when(future.isSuccess()).thenReturn(true); - } - - @Test - @UseDataProvider(value = "allDseProtocolVersions", location = DseTestDataProviders.class) - public void should_prepare_and_retry_on_same_node(DseProtocolVersion version) { - - try (RequestHandlerTestHarness harness = - continuousHarnessBuilder() - .withResponse(node1, defaultFrameOf(unprepared)) - .withProtocolVersion(version) - .build()) { - - when(harness.getSession().getRepreparePayloads()).thenReturn(repreparePayloads); - when(harness.getChannel(node1).write(any(Prepare.class), anyBoolean(), anyMap(), any())) - .then( - invocation -> { - AdminRequestHandler admin = invocation.getArgument(3); - admin.onResponse(defaultFrameOf(prepared)); - return future; - }); - - new ContinuousCqlRequestHandler( - UNDEFINED_IDEMPOTENCE_STATEMENT, harness.getSession(), harness.getContext(), "test") - .handle(); - - verify(harness.getChannel(node1)).write(any(Prepare.class), anyBoolean(), anyMap(), any()); - // should have attempted to execute the query twice on the same node - verify(harness.getChannel(node1), times(2)) - .write(any(Query.class), anyBoolean(), anyMap(), any()); - } - } - - @Test - @UseDataProvider(value = "allDseProtocolVersions", location = DseTestDataProviders.class) - public void should_abort_when_prepare_fails_with_unrecoverable_error(DseProtocolVersion version) { - - try (RequestHandlerTestHarness harness = - continuousHarnessBuilder() - .withResponse(node1, defaultFrameOf(unprepared)) - .withProtocolVersion(version) - .build()) { - - when(harness.getSession().getRepreparePayloads()).thenReturn(repreparePayloads); - when(harness.getChannel(node1).write(any(Prepare.class), anyBoolean(), anyMap(), any())) - .then( - invocation -> { - AdminRequestHandler admin = invocation.getArgument(3); - admin.onResponse(defaultFrameOf(unrecoverable)); - return future; - }); - - ContinuousCqlRequestHandler handler = - new ContinuousCqlRequestHandler( - UNDEFINED_IDEMPOTENCE_STATEMENT, harness.getSession(), harness.getContext(), "test"); - CompletionStage page1Future = handler.handle(); - - verify(harness.getChannel(node1)).write(any(Query.class), anyBoolean(), anyMap(), any()); - verify(harness.getChannel(node1)).write(any(Prepare.class), anyBoolean(), anyMap(), any()); - - assertThat(handler.getState()).isEqualTo(-2); - assertThat(page1Future).isCompletedExceptionally(); - Throwable t = catchThrowable(() -> page1Future.toCompletableFuture().get()); - assertThat(t).hasRootCauseInstanceOf(SyntaxError.class).hasMessageContaining("bad query"); - } - } - - @Test - @UseDataProvider(value = "allDseProtocolVersions", location = DseTestDataProviders.class) - public void should_try_next_node_when_prepare_fails_with_recoverable_error( - DseProtocolVersion version) { - - try (RequestHandlerTestHarness harness = - continuousHarnessBuilder() - .withResponse(node1, defaultFrameOf(unprepared)) - .withResponse(node2, defaultFrameOf(DseTestFixtures.singleDseRow())) - .withProtocolVersion(version) - .build()) { - - when(harness.getSession().getRepreparePayloads()).thenReturn(repreparePayloads); - when(harness.getChannel(node1).write(any(Prepare.class), anyBoolean(), anyMap(), any())) - .then( - invocation -> { - AdminRequestHandler admin = invocation.getArgument(3); - admin.onResponse(defaultFrameOf(recoverable)); - return future; - }); - - ContinuousCqlRequestHandler handler = - new ContinuousCqlRequestHandler( - UNDEFINED_IDEMPOTENCE_STATEMENT, harness.getSession(), harness.getContext(), "test"); - CompletionStage page1Future = handler.handle(); - - verify(harness.getChannel(node1)).write(any(Query.class), anyBoolean(), anyMap(), any()); - verify(harness.getChannel(node1)).write(any(Prepare.class), anyBoolean(), anyMap(), any()); - // should have tried the next host - verify(harness.getChannel(node2)).write(any(Query.class), anyBoolean(), anyMap(), any()); - - assertThat(handler.getState()).isEqualTo(-1); - assertThatStage(page1Future) - .isSuccess( - rs -> { - assertThat(rs.currentPage()).hasSize(1); - assertThat(rs.hasMorePages()).isFalse(); - assertThat(rs.getExecutionInfo().getCoordinator()).isEqualTo(node2); - assertThat(rs.getExecutionInfo().getErrors()) - .hasSize(1) - .allSatisfy( - entry -> { - assertThat(entry.getKey()).isEqualTo(node1); - assertThat(entry.getValue()) - .isInstanceOf(UnexpectedResponseException.class) - .hasMessageContaining(recoverable.toString()); - }); - }); - } - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/cql/continuous/ContinuousCqlRequestHandlerRetryTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/cql/continuous/ContinuousCqlRequestHandlerRetryTest.java deleted file mode 100644 index 97fe82985de..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/cql/continuous/ContinuousCqlRequestHandlerRetryTest.java +++ /dev/null @@ -1,600 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.cql.continuous; - -import static com.datastax.dse.driver.DseTestDataProviders.allDseProtocolVersions; -import static com.datastax.oss.driver.Assertions.assertThat; -import static com.datastax.oss.driver.Assertions.assertThatStage; -import static com.datastax.oss.driver.TestDataProviders.combine; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.atMost; -import static org.mockito.Mockito.when; - -import com.datastax.dse.driver.DseTestFixtures; -import com.datastax.dse.driver.api.core.DseProtocolVersion; -import com.datastax.dse.driver.api.core.cql.continuous.ContinuousAsyncResultSet; -import com.datastax.oss.driver.TestDataProviders; -import com.datastax.oss.driver.api.core.DefaultConsistencyLevel; -import com.datastax.oss.driver.api.core.connection.HeartbeatException; -import com.datastax.oss.driver.api.core.cql.BatchStatement; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import com.datastax.oss.driver.api.core.cql.Row; -import com.datastax.oss.driver.api.core.cql.SimpleStatement; -import com.datastax.oss.driver.api.core.cql.Statement; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.datastax.oss.driver.api.core.metrics.DefaultNodeMetric; -import com.datastax.oss.driver.api.core.retry.RetryPolicy; -import com.datastax.oss.driver.api.core.retry.RetryVerdict; -import com.datastax.oss.driver.api.core.servererrors.BootstrappingException; -import com.datastax.oss.driver.api.core.servererrors.DefaultWriteType; -import com.datastax.oss.driver.api.core.servererrors.InvalidQueryException; -import com.datastax.oss.driver.api.core.servererrors.ReadTimeoutException; -import com.datastax.oss.driver.api.core.servererrors.ServerError; -import com.datastax.oss.driver.api.core.servererrors.UnavailableException; -import com.datastax.oss.driver.api.core.servererrors.WriteTimeoutException; -import com.datastax.oss.driver.internal.core.cql.RequestHandlerTestHarness; -import com.datastax.oss.protocol.internal.ProtocolConstants; -import com.datastax.oss.protocol.internal.response.Error; -import com.datastax.oss.protocol.internal.response.error.ReadTimeout; -import com.datastax.oss.protocol.internal.response.error.Unavailable; -import com.datastax.oss.protocol.internal.response.error.WriteTimeout; -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.TimeUnit; -import org.junit.Test; -import org.mockito.Mockito; - -public class ContinuousCqlRequestHandlerRetryTest extends ContinuousCqlRequestHandlerTestBase { - - @Test - @UseDataProvider("allIdempotenceConfigs") - public void should_always_try_next_node_if_bootstrapping( - boolean defaultIdempotence, Statement statement, DseProtocolVersion version) { - - try (RequestHandlerTestHarness harness = - continuousHarnessBuilder() - .withProtocolVersion(version) - .withDefaultIdempotence(defaultIdempotence) - .withResponse( - node1, - defaultFrameOf( - new Error(ProtocolConstants.ErrorCode.IS_BOOTSTRAPPING, "mock message"))) - .withResponse(node2, defaultFrameOf(DseTestFixtures.singleDseRow())) - .build()) { - - ContinuousCqlRequestHandler handler = - new ContinuousCqlRequestHandler( - statement, harness.getSession(), harness.getContext(), "test"); - CompletionStage resultSetFuture = handler.handle(); - - assertThat(handler.getState()).isEqualTo(-1); - - assertThatStage(resultSetFuture) - .isSuccess( - resultSet -> { - Iterator rows = resultSet.currentPage().iterator(); - assertThat(rows.hasNext()).isTrue(); - assertThat(rows.next().getString("message")).isEqualTo("hello, world"); - - ExecutionInfo executionInfo = resultSet.getExecutionInfo(); - assertThat(executionInfo.getCoordinator()).isEqualTo(node2); - assertThat(executionInfo.getErrors()).hasSize(1); - assertThat(executionInfo.getErrors().get(0).getKey()).isEqualTo(node1); - assertThat(executionInfo.getErrors().get(0).getValue()) - .isInstanceOf(BootstrappingException.class); - assertThat(executionInfo.getIncomingPayload()).isEmpty(); - assertThat(executionInfo.getPagingState()).isNull(); - assertThat(executionInfo.getSpeculativeExecutionCount()).isEqualTo(0); - assertThat(executionInfo.getSuccessfulExecutionIndex()).isEqualTo(0); - assertThat(executionInfo.getWarnings()).isEmpty(); - - Mockito.verifyNoMoreInteractions(harness.getContext().getRetryPolicy(anyString())); - }); - } - } - - @Test - @UseDataProvider("allIdempotenceConfigs") - public void should_always_rethrow_query_validation_error( - boolean defaultIdempotence, Statement statement, DseProtocolVersion version) { - - try (RequestHandlerTestHarness harness = - continuousHarnessBuilder() - .withProtocolVersion(version) - .withDefaultIdempotence(defaultIdempotence) - .withResponse( - node1, - defaultFrameOf(new Error(ProtocolConstants.ErrorCode.INVALID, "mock message"))) - .build()) { - - ContinuousCqlRequestHandler handler = - new ContinuousCqlRequestHandler( - statement, harness.getSession(), harness.getContext(), "test"); - CompletionStage resultSetFuture = handler.handle(); - - assertThat(handler.getState()).isEqualTo(-2); - - assertThatStage(resultSetFuture) - .isFailed( - error -> { - assertThat(error) - .isInstanceOf(InvalidQueryException.class) - .hasMessage("mock message"); - Mockito.verifyNoMoreInteractions(harness.getContext().getRetryPolicy(anyString())); - - Mockito.verify(nodeMetricUpdater1) - .incrementCounter(eq(DefaultNodeMetric.OTHER_ERRORS), anyString()); - Mockito.verify(nodeMetricUpdater1) - .updateTimer( - eq(DefaultNodeMetric.CQL_MESSAGES), - anyString(), - anyLong(), - eq(TimeUnit.NANOSECONDS)); - Mockito.verifyNoMoreInteractions(nodeMetricUpdater1); - }); - } - } - - @Test - @UseDataProvider("failureAndIdempotent") - public void should_try_next_node_if_idempotent_and_retry_policy_decides_so( - FailureScenario failureScenario, - boolean defaultIdempotence, - Statement statement, - DseProtocolVersion version) { - - RequestHandlerTestHarness.Builder harnessBuilder = - continuousHarnessBuilder() - .withProtocolVersion(version) - .withDefaultIdempotence(defaultIdempotence); - failureScenario.mockRequestError(harnessBuilder, node1); - harnessBuilder.withResponse(node2, defaultFrameOf(DseTestFixtures.singleDseRow())); - - try (RequestHandlerTestHarness harness = harnessBuilder.build()) { - failureScenario.mockRetryPolicyVerdict( - harness.getContext().getRetryPolicy(anyString()), RetryVerdict.RETRY_NEXT); - - ContinuousCqlRequestHandler handler = - new ContinuousCqlRequestHandler( - statement, harness.getSession(), harness.getContext(), "test"); - CompletionStage resultSetFuture = handler.handle(); - - assertThat(handler.getState()).isEqualTo(-1); - - assertThatStage(resultSetFuture) - .isSuccess( - resultSet -> { - Iterator rows = resultSet.currentPage().iterator(); - assertThat(rows.hasNext()).isTrue(); - assertThat(rows.next().getString("message")).isEqualTo("hello, world"); - - ExecutionInfo executionInfo = resultSet.getExecutionInfo(); - assertThat(executionInfo.getCoordinator()).isEqualTo(node2); - assertThat(executionInfo.getErrors()).hasSize(1); - assertThat(executionInfo.getErrors().get(0).getKey()).isEqualTo(node1); - - Mockito.verify(nodeMetricUpdater1) - .incrementCounter(eq(failureScenario.errorMetric), anyString()); - Mockito.verify(nodeMetricUpdater1) - .incrementCounter(eq(DefaultNodeMetric.RETRIES), anyString()); - Mockito.verify(nodeMetricUpdater1) - .incrementCounter(eq(failureScenario.retryMetric), anyString()); - Mockito.verify(nodeMetricUpdater1, atMost(1)) - .updateTimer( - eq(DefaultNodeMetric.CQL_MESSAGES), - anyString(), - anyLong(), - eq(TimeUnit.NANOSECONDS)); - Mockito.verifyNoMoreInteractions(nodeMetricUpdater1); - }); - } - } - - @Test - @UseDataProvider("failureAndIdempotent") - public void should_try_same_node_if_idempotent_and_retry_policy_decides_so( - FailureScenario failureScenario, - boolean defaultIdempotence, - Statement statement, - DseProtocolVersion version) { - - RequestHandlerTestHarness.Builder harnessBuilder = - continuousHarnessBuilder() - .withProtocolVersion(version) - .withDefaultIdempotence(defaultIdempotence); - failureScenario.mockRequestError(harnessBuilder, node1); - harnessBuilder.withResponse(node1, defaultFrameOf(DseTestFixtures.singleDseRow())); - - try (RequestHandlerTestHarness harness = harnessBuilder.build()) { - failureScenario.mockRetryPolicyVerdict( - harness.getContext().getRetryPolicy(anyString()), RetryVerdict.RETRY_SAME); - - ContinuousCqlRequestHandler handler = - new ContinuousCqlRequestHandler( - statement, harness.getSession(), harness.getContext(), "test"); - CompletionStage resultSetFuture = handler.handle(); - - assertThat(handler.getState()).isEqualTo(-1); - - assertThatStage(resultSetFuture) - .isSuccess( - resultSet -> { - Iterator rows = resultSet.currentPage().iterator(); - assertThat(rows.hasNext()).isTrue(); - assertThat(rows.next().getString("message")).isEqualTo("hello, world"); - - ExecutionInfo executionInfo = resultSet.getExecutionInfo(); - assertThat(executionInfo.getCoordinator()).isEqualTo(node1); - assertThat(executionInfo.getErrors()).hasSize(1); - assertThat(executionInfo.getErrors().get(0).getKey()).isEqualTo(node1); - - Mockito.verify(nodeMetricUpdater1) - .incrementCounter(eq(failureScenario.errorMetric), anyString()); - Mockito.verify(nodeMetricUpdater1) - .incrementCounter(eq(DefaultNodeMetric.RETRIES), anyString()); - Mockito.verify(nodeMetricUpdater1) - .incrementCounter(eq(failureScenario.retryMetric), anyString()); - Mockito.verify(nodeMetricUpdater1, atMost(2)) - .updateTimer( - eq(DefaultNodeMetric.CQL_MESSAGES), - anyString(), - anyLong(), - eq(TimeUnit.NANOSECONDS)); - Mockito.verifyNoMoreInteractions(nodeMetricUpdater1); - }); - } - } - - @Test - @UseDataProvider("failureAndIdempotent") - public void should_ignore_error_if_idempotent_and_retry_policy_decides_so( - FailureScenario failureScenario, - boolean defaultIdempotence, - Statement statement, - DseProtocolVersion version) { - - RequestHandlerTestHarness.Builder harnessBuilder = - continuousHarnessBuilder() - .withProtocolVersion(version) - .withDefaultIdempotence(defaultIdempotence); - failureScenario.mockRequestError(harnessBuilder, node1); - - try (RequestHandlerTestHarness harness = harnessBuilder.build()) { - failureScenario.mockRetryPolicyVerdict( - harness.getContext().getRetryPolicy(anyString()), RetryVerdict.IGNORE); - - ContinuousCqlRequestHandler handler = - new ContinuousCqlRequestHandler( - statement, harness.getSession(), harness.getContext(), "test"); - CompletionStage resultSetFuture = handler.handle(); - - assertThat(handler.getState()).isEqualTo(-1); - - assertThatStage(resultSetFuture) - .isSuccess( - resultSet -> { - Iterator rows = resultSet.currentPage().iterator(); - assertThat(rows.hasNext()).isFalse(); - - ExecutionInfo executionInfo = resultSet.getExecutionInfo(); - assertThat(executionInfo.getCoordinator()).isEqualTo(node1); - assertThat(executionInfo.getErrors()).hasSize(0); - - Mockito.verify(nodeMetricUpdater1) - .incrementCounter(eq(failureScenario.errorMetric), anyString()); - Mockito.verify(nodeMetricUpdater1) - .incrementCounter(eq(DefaultNodeMetric.IGNORES), anyString()); - Mockito.verify(nodeMetricUpdater1) - .incrementCounter(eq(failureScenario.ignoreMetric), anyString()); - Mockito.verify(nodeMetricUpdater1, atMost(1)) - .updateTimer( - eq(DefaultNodeMetric.CQL_MESSAGES), - anyString(), - anyLong(), - eq(TimeUnit.NANOSECONDS)); - Mockito.verifyNoMoreInteractions(nodeMetricUpdater1); - }); - } - } - - @Test - @UseDataProvider("failureAndIdempotent") - public void should_rethrow_error_if_idempotent_and_retry_policy_decides_so( - FailureScenario failureScenario, - boolean defaultIdempotence, - Statement statement, - DseProtocolVersion version) { - - RequestHandlerTestHarness.Builder harnessBuilder = - continuousHarnessBuilder() - .withProtocolVersion(version) - .withDefaultIdempotence(defaultIdempotence); - failureScenario.mockRequestError(harnessBuilder, node1); - - try (RequestHandlerTestHarness harness = harnessBuilder.build()) { - - failureScenario.mockRetryPolicyVerdict( - harness.getContext().getRetryPolicy(anyString()), RetryVerdict.RETHROW); - - ContinuousCqlRequestHandler handler = - new ContinuousCqlRequestHandler( - statement, harness.getSession(), harness.getContext(), "test"); - CompletionStage resultSetFuture = handler.handle(); - - assertThat(handler.getState()).isEqualTo(-2); - - assertThatStage(resultSetFuture) - .isFailed( - error -> { - assertThat(error).isInstanceOf(failureScenario.expectedExceptionClass); - - Mockito.verify(nodeMetricUpdater1) - .incrementCounter(eq(failureScenario.errorMetric), anyString()); - Mockito.verify(nodeMetricUpdater1, atMost(1)) - .updateTimer( - eq(DefaultNodeMetric.CQL_MESSAGES), - anyString(), - anyLong(), - eq(TimeUnit.NANOSECONDS)); - Mockito.verifyNoMoreInteractions(nodeMetricUpdater1); - }); - } - } - - @Test - @UseDataProvider("failureAndNotIdempotent") - public void should_rethrow_error_if_not_idempotent_and_error_unsafe_or_policy_rethrows( - FailureScenario failureScenario, - boolean defaultIdempotence, - Statement statement, - DseProtocolVersion version) { - - // For two of the possible exceptions, the retry policy is called even if the statement is not - // idempotent - boolean shouldCallRetryPolicy = - (failureScenario.expectedExceptionClass.equals(UnavailableException.class) - || failureScenario.expectedExceptionClass.equals(ReadTimeoutException.class)); - - RequestHandlerTestHarness.Builder harnessBuilder = - continuousHarnessBuilder() - .withProtocolVersion(version) - .withDefaultIdempotence(defaultIdempotence); - failureScenario.mockRequestError(harnessBuilder, node1); - harnessBuilder.withResponse(node2, defaultFrameOf(DseTestFixtures.singleDseRow())); - - try (RequestHandlerTestHarness harness = harnessBuilder.build()) { - - if (shouldCallRetryPolicy) { - failureScenario.mockRetryPolicyVerdict( - harness.getContext().getRetryPolicy(anyString()), RetryVerdict.RETHROW); - } - - ContinuousCqlRequestHandler handler = - new ContinuousCqlRequestHandler( - statement, harness.getSession(), harness.getContext(), "test"); - CompletionStage resultSetFuture = handler.handle(); - - assertThat(handler.getState()).isEqualTo(-2); - - assertThatStage(resultSetFuture) - .isFailed( - error -> { - assertThat(error).isInstanceOf(failureScenario.expectedExceptionClass); - // When non idempotent, the policy is bypassed completely: - if (!shouldCallRetryPolicy) { - Mockito.verifyNoMoreInteractions( - harness.getContext().getRetryPolicy(anyString())); - } - - Mockito.verify(nodeMetricUpdater1) - .incrementCounter(eq(failureScenario.errorMetric), anyString()); - Mockito.verify(nodeMetricUpdater1, atMost(1)) - .updateTimer( - eq(DefaultNodeMetric.CQL_MESSAGES), - anyString(), - anyLong(), - eq(TimeUnit.NANOSECONDS)); - Mockito.verifyNoMoreInteractions(nodeMetricUpdater1); - }); - } - } - - /** - * Sets up the mocks to simulate an error from a node, and make the retry policy return a given - * decision for that error. - */ - private abstract static class FailureScenario { - private final Class expectedExceptionClass; - final DefaultNodeMetric errorMetric; - final DefaultNodeMetric retryMetric; - final DefaultNodeMetric ignoreMetric; - - FailureScenario( - Class expectedExceptionClass, - DefaultNodeMetric errorMetric, - DefaultNodeMetric retryMetric, - DefaultNodeMetric ignoreMetric) { - this.expectedExceptionClass = expectedExceptionClass; - this.errorMetric = errorMetric; - this.retryMetric = retryMetric; - this.ignoreMetric = ignoreMetric; - } - - abstract void mockRequestError(RequestHandlerTestHarness.Builder builder, Node node); - - abstract void mockRetryPolicyVerdict(RetryPolicy policy, RetryVerdict verdict); - } - - @DataProvider - public static Object[][] failure() { - return TestDataProviders.fromList( - new FailureScenario( - ReadTimeoutException.class, - DefaultNodeMetric.READ_TIMEOUTS, - DefaultNodeMetric.RETRIES_ON_READ_TIMEOUT, - DefaultNodeMetric.IGNORES_ON_READ_TIMEOUT) { - @Override - public void mockRequestError(RequestHandlerTestHarness.Builder builder, Node node) { - builder.withResponse( - node, - defaultFrameOf( - new ReadTimeout( - "mock message", ProtocolConstants.ConsistencyLevel.LOCAL_ONE, 1, 2, true))); - } - - @Override - public void mockRetryPolicyVerdict(RetryPolicy policy, RetryVerdict verdict) { - when(policy.onReadTimeoutVerdict( - any(SimpleStatement.class), - eq(DefaultConsistencyLevel.LOCAL_ONE), - eq(2), - eq(1), - eq(true), - eq(0))) - .thenReturn(verdict); - } - }, - new FailureScenario( - WriteTimeoutException.class, - DefaultNodeMetric.WRITE_TIMEOUTS, - DefaultNodeMetric.RETRIES_ON_WRITE_TIMEOUT, - DefaultNodeMetric.IGNORES_ON_WRITE_TIMEOUT) { - @Override - public void mockRequestError(RequestHandlerTestHarness.Builder builder, Node node) { - builder.withResponse( - node, - defaultFrameOf( - new WriteTimeout( - "mock message", - ProtocolConstants.ConsistencyLevel.LOCAL_ONE, - 1, - 2, - ProtocolConstants.WriteType.SIMPLE))); - } - - @Override - public void mockRetryPolicyVerdict(RetryPolicy policy, RetryVerdict verdict) { - when(policy.onWriteTimeoutVerdict( - any(SimpleStatement.class), - eq(DefaultConsistencyLevel.LOCAL_ONE), - eq(DefaultWriteType.SIMPLE), - eq(2), - eq(1), - eq(0))) - .thenReturn(verdict); - } - }, - new FailureScenario( - UnavailableException.class, - DefaultNodeMetric.UNAVAILABLES, - DefaultNodeMetric.RETRIES_ON_UNAVAILABLE, - DefaultNodeMetric.IGNORES_ON_UNAVAILABLE) { - @Override - public void mockRequestError(RequestHandlerTestHarness.Builder builder, Node node) { - builder.withResponse( - node, - defaultFrameOf( - new Unavailable( - "mock message", ProtocolConstants.ConsistencyLevel.LOCAL_ONE, 2, 1))); - } - - @Override - public void mockRetryPolicyVerdict(RetryPolicy policy, RetryVerdict verdict) { - when(policy.onUnavailableVerdict( - any(SimpleStatement.class), - eq(DefaultConsistencyLevel.LOCAL_ONE), - eq(2), - eq(1), - eq(0))) - .thenReturn(verdict); - } - }, - new FailureScenario( - ServerError.class, - DefaultNodeMetric.OTHER_ERRORS, - DefaultNodeMetric.RETRIES_ON_OTHER_ERROR, - DefaultNodeMetric.IGNORES_ON_OTHER_ERROR) { - @Override - public void mockRequestError(RequestHandlerTestHarness.Builder builder, Node node) { - builder.withResponse( - node, - defaultFrameOf( - new Error(ProtocolConstants.ErrorCode.SERVER_ERROR, "mock server error"))); - } - - @Override - public void mockRetryPolicyVerdict(RetryPolicy policy, RetryVerdict verdict) { - when(policy.onErrorResponseVerdict( - any(SimpleStatement.class), any(ServerError.class), eq(0))) - .thenReturn(verdict); - } - }, - new FailureScenario( - HeartbeatException.class, - DefaultNodeMetric.ABORTED_REQUESTS, - DefaultNodeMetric.RETRIES_ON_ABORTED, - DefaultNodeMetric.IGNORES_ON_ABORTED) { - @Override - public void mockRequestError(RequestHandlerTestHarness.Builder builder, Node node) { - builder.withResponseFailure(node, Mockito.mock(HeartbeatException.class)); - } - - @Override - public void mockRetryPolicyVerdict(RetryPolicy policy, RetryVerdict verdict) { - when(policy.onRequestAbortedVerdict( - any(SimpleStatement.class), any(HeartbeatException.class), eq(0))) - .thenReturn(verdict); - } - }); - } - - @DataProvider - public static Object[][] failureAndIdempotent() { - return combine(failure(), excludeBatchStatements(idempotentConfig()), allDseProtocolVersions()); - } - - @DataProvider - public static Object[][] failureAndNotIdempotent() { - return combine( - failure(), excludeBatchStatements(nonIdempotentConfig()), allDseProtocolVersions()); - } - - @DataProvider - public static Object[][] allIdempotenceConfigs() { - return combine( - excludeBatchStatements(ContinuousCqlRequestHandlerTestBase.allIdempotenceConfigs()), - allDseProtocolVersions()); - } - - private static Object[][] excludeBatchStatements(Object[][] configs) { - List result = new ArrayList<>(); - for (Object[] config : configs) { - if (!(config[1] instanceof BatchStatement)) { - result.add(config); - } - } - return result.toArray(new Object[][] {}); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/cql/continuous/ContinuousCqlRequestHandlerTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/cql/continuous/ContinuousCqlRequestHandlerTest.java deleted file mode 100644 index e24579e7fe6..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/cql/continuous/ContinuousCqlRequestHandlerTest.java +++ /dev/null @@ -1,560 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.cql.continuous; - -import static com.datastax.dse.driver.api.core.DseProtocolVersion.DSE_V1; -import static com.datastax.dse.driver.api.core.DseProtocolVersion.DSE_V2; -import static com.datastax.dse.protocol.internal.DseProtocolConstants.RevisionType.CANCEL_CONTINUOUS_PAGING; -import static com.datastax.dse.protocol.internal.DseProtocolConstants.RevisionType.MORE_CONTINUOUS_PAGES; -import static com.datastax.oss.driver.Assertions.assertThat; -import static com.datastax.oss.driver.Assertions.assertThatStage; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.anyMap; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.matches; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import com.datastax.dse.driver.DseTestDataProviders; -import com.datastax.dse.driver.DseTestFixtures; -import com.datastax.dse.driver.api.core.DseProtocolVersion; -import com.datastax.dse.driver.api.core.cql.continuous.ContinuousAsyncResultSet; -import com.datastax.dse.protocol.internal.request.Revise; -import com.datastax.oss.driver.api.core.DefaultProtocolVersion; -import com.datastax.oss.driver.api.core.DriverTimeoutException; -import com.datastax.oss.driver.api.core.NoNodeAvailableException; -import com.datastax.oss.driver.api.core.ProtocolVersion; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import com.datastax.oss.driver.api.core.cql.Row; -import com.datastax.oss.driver.api.core.cql.SimpleStatement; -import com.datastax.oss.driver.api.core.servererrors.BootstrappingException; -import com.datastax.oss.driver.api.core.session.throttling.RequestThrottler; -import com.datastax.oss.driver.api.core.tracker.RequestTracker; -import com.datastax.oss.driver.internal.core.ProtocolFeature; -import com.datastax.oss.driver.internal.core.cql.PoolBehavior; -import com.datastax.oss.driver.internal.core.cql.RequestHandlerTestHarness; -import com.datastax.oss.driver.internal.core.util.concurrent.CapturingTimer.CapturedTimeout; -import com.datastax.oss.driver.internal.core.util.concurrent.CompletableFutures; -import com.datastax.oss.protocol.internal.Message; -import com.datastax.oss.protocol.internal.ProtocolConstants; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import java.util.Iterator; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.TimeUnit; -import java.util.regex.Pattern; -import org.junit.Test; -import org.mockito.Mockito; - -public class ContinuousCqlRequestHandlerTest extends ContinuousCqlRequestHandlerTestBase { - - private static final Pattern LOG_PREFIX_PER_REQUEST = Pattern.compile("test\\|\\d*\\|\\d"); - - @Test - @UseDataProvider(value = "allDseProtocolVersions", location = DseTestDataProviders.class) - public void should_complete_single_page_result(DseProtocolVersion version) { - try (RequestHandlerTestHarness harness = - continuousHarnessBuilder() - .withProtocolVersion(version) - .withResponse(node1, defaultFrameOf(DseTestFixtures.singleDseRow())) - .build()) { - - CompletionStage resultSetFuture = - new ContinuousCqlRequestHandler( - UNDEFINED_IDEMPOTENCE_STATEMENT, - harness.getSession(), - harness.getContext(), - "test") - .handle(); - - assertThatStage(resultSetFuture) - .isSuccess( - resultSet -> { - Iterator rows = resultSet.currentPage().iterator(); - assertThat(rows.hasNext()).isTrue(); - assertThat(rows.next().getString("message")).isEqualTo("hello, world"); - ExecutionInfo executionInfo = resultSet.getExecutionInfo(); - assertThat(executionInfo.getCoordinator()).isEqualTo(node1); - assertThat(executionInfo.getErrors()).isEmpty(); - assertThat(executionInfo.getIncomingPayload()).isEmpty(); - assertThat(executionInfo.getPagingState()).isNull(); - assertThat(executionInfo.getSpeculativeExecutionCount()).isEqualTo(0); - assertThat(executionInfo.getSuccessfulExecutionIndex()).isEqualTo(0); - assertThat(executionInfo.getWarnings()).isEmpty(); - }); - } - } - - @Test - @UseDataProvider(value = "allDseProtocolVersions", location = DseTestDataProviders.class) - public void should_complete_multi_page_result(DseProtocolVersion version) { - RequestHandlerTestHarness.Builder builder = - continuousHarnessBuilder().withProtocolVersion(version); - PoolBehavior node1Behavior = builder.customBehavior(node1); - try (RequestHandlerTestHarness harness = builder.build()) { - - ContinuousCqlRequestHandler handler = - new ContinuousCqlRequestHandler( - UNDEFINED_IDEMPOTENCE_STATEMENT, harness.getSession(), harness.getContext(), "test"); - CompletionStage page1Future = handler.handle(); - - node1Behavior.setResponseSuccess(defaultFrameOf(DseTestFixtures.tenDseRows(1, false))); - - assertThatStage(page1Future) - .isSuccess( - page1 -> { - assertThat(page1.hasMorePages()).isTrue(); - assertThat(page1.pageNumber()).isEqualTo(1); - Iterator rows = page1.currentPage().iterator(); - assertThat(rows.hasNext()).isTrue(); - assertThat(rows).toIterable().hasSize(10); - ExecutionInfo executionInfo = page1.getExecutionInfo(); - assertThat(executionInfo.getCoordinator()).isEqualTo(node1); - assertThat(executionInfo.getErrors()).isEmpty(); - assertThat(executionInfo.getIncomingPayload()).isEmpty(); - assertThat(executionInfo.getPagingState()).isNotNull(); - assertThat(executionInfo.getSpeculativeExecutionCount()).isEqualTo(0); - assertThat(executionInfo.getSuccessfulExecutionIndex()).isEqualTo(0); - assertThat(executionInfo.getWarnings()).isEmpty(); - }); - - ContinuousAsyncResultSet page1 = CompletableFutures.getCompleted(page1Future); - assertThat(handler.getPendingResult()).isNull(); - CompletionStage page2Future = page1.fetchNextPage(); - assertThat(handler.getPendingResult()).isNotNull(); - node1Behavior.setResponseSuccess(defaultFrameOf(DseTestFixtures.tenDseRows(2, true))); - - assertThatStage(page2Future) - .isSuccess( - page2 -> { - assertThat(page2.hasMorePages()).isFalse(); - assertThat(page2.pageNumber()).isEqualTo(2); - Iterator rows = page2.currentPage().iterator(); - assertThat(rows.hasNext()).isTrue(); - assertThat(rows).toIterable().hasSize(10); - ExecutionInfo executionInfo = page2.getExecutionInfo(); - assertThat(executionInfo.getCoordinator()).isEqualTo(node1); - assertThat(executionInfo.getErrors()).isEmpty(); - assertThat(executionInfo.getIncomingPayload()).isEmpty(); - assertThat(executionInfo.getPagingState()).isNull(); - assertThat(executionInfo.getSpeculativeExecutionCount()).isEqualTo(0); - assertThat(executionInfo.getSuccessfulExecutionIndex()).isEqualTo(0); - assertThat(executionInfo.getWarnings()).isEmpty(); - }); - } - } - - @Test - @UseDataProvider(value = "allDseProtocolVersions", location = DseTestDataProviders.class) - public void should_fail_if_no_node_available(DseProtocolVersion version) { - try (RequestHandlerTestHarness harness = - continuousHarnessBuilder() - .withProtocolVersion(version) - // Mock no responses => this will produce an empty query plan - .build()) { - - CompletionStage resultSetFuture = - new ContinuousCqlRequestHandler( - UNDEFINED_IDEMPOTENCE_STATEMENT, - harness.getSession(), - harness.getContext(), - "test") - .handle(); - - assertThatStage(resultSetFuture) - .isFailed(error -> assertThat(error).isInstanceOf(NoNodeAvailableException.class)); - } - } - - @Test - @UseDataProvider(value = "allOssProtocolVersions", location = DseTestDataProviders.class) - public void should_throw_if_protocol_version_does_not_support_continuous_paging( - ProtocolVersion version) { - try (RequestHandlerTestHarness harness = - continuousHarnessBuilder().withProtocolVersion(version).build()) { - Mockito.when( - harness - .getContext() - .getProtocolVersionRegistry() - .supports(any(DefaultProtocolVersion.class), any(ProtocolFeature.class))) - .thenReturn(false); - assertThatThrownBy( - () -> - new ContinuousCqlRequestHandler( - UNDEFINED_IDEMPOTENCE_STATEMENT, - harness.getSession(), - harness.getContext(), - "test") - .handle()) - .isInstanceOf(IllegalStateException.class) - .hasMessage("Cannot execute continuous paging requests with protocol version " + version); - } - } - - @Test - public void should_unwind_execution_if_request_setup_fails_before_write() { - RuntimeException failure = new RuntimeException("mock failure"); - SimpleStatement statement = Mockito.spy(SimpleStatement.newInstance("mock query")); - doThrow(failure).when(statement).getCustomPayload(); - RequestThrottler throttler = mock(RequestThrottler.class); - RequestHandlerTestHarness.Builder builder = - continuousHarnessBuilder().withProtocolVersion(DSE_V2); - PoolBehavior node1Behavior = builder.customBehavior(node1); - - try (RequestHandlerTestHarness harness = builder.build()) { - when(harness.getContext().getRequestThrottler()).thenReturn(throttler); - ContinuousCqlRequestHandler handler = - new ContinuousCqlRequestHandler( - statement, harness.getSession(), harness.getContext(), "test"); - CompletionStage resultSetFuture = handler.handle(); - - assertThatThrownBy(() -> handler.onThrottleReady(false)).isSameAs(failure); - - assertThatStage(resultSetFuture).isFailed(error -> assertThat(error).isSameAs(failure)); - assertThat(handler.getActiveExecutionsCount()).isZero(); - assertThat(handler.getInFlightCallbackCount()).isZero(); - node1Behavior.verifyNoWrite(); - node1Behavior.verifyPreAcquireCancelled(); - verify(throttler).signalError(handler, failure); - } - } - - @Test - @UseDataProvider(value = "allDseProtocolVersions", location = DseTestDataProviders.class) - public void should_time_out_if_first_page_takes_too_long(DseProtocolVersion version) - throws Exception { - RequestHandlerTestHarness.Builder builder = - continuousHarnessBuilder().withProtocolVersion(version); - PoolBehavior node1Behavior = builder.customBehavior(node1); - try (RequestHandlerTestHarness harness = builder.build()) { - - CompletionStage resultSetFuture = - new ContinuousCqlRequestHandler( - UNDEFINED_IDEMPOTENCE_STATEMENT, - harness.getSession(), - harness.getContext(), - "test") - .handle(); - - // mark the initial request as successful, which should schedule a timeout for the first page - node1Behavior.setWriteSuccess(); - CapturedTimeout page1Timeout = harness.nextScheduledTimeout(); - assertThat(page1Timeout.getDelay(TimeUnit.NANOSECONDS)) - .isEqualTo(TIMEOUT_FIRST_PAGE.toNanos()); - - page1Timeout.task().run(page1Timeout); - - assertThatStage(resultSetFuture) - .isFailed( - t -> - assertThat(t) - .isInstanceOf(DriverTimeoutException.class) - .hasMessageContaining("Timed out waiting for page 1")); - } - } - - @Test - @UseDataProvider(value = "allDseProtocolVersions", location = DseTestDataProviders.class) - public void should_time_out_if_other_page_takes_too_long(DseProtocolVersion version) - throws Exception { - RequestHandlerTestHarness.Builder builder = - continuousHarnessBuilder().withProtocolVersion(version); - PoolBehavior node1Behavior = builder.customBehavior(node1); - - try (RequestHandlerTestHarness harness = builder.build()) { - - CompletionStage page1Future = - new ContinuousCqlRequestHandler( - UNDEFINED_IDEMPOTENCE_STATEMENT, - harness.getSession(), - harness.getContext(), - "test") - .handle(); - - // mark the initial request as successful, which should schedule a timeout for the first page - node1Behavior.setWriteSuccess(); - CapturedTimeout page1Timeout = harness.nextScheduledTimeout(); - assertThat(page1Timeout.getDelay(TimeUnit.NANOSECONDS)) - .isEqualTo(TIMEOUT_FIRST_PAGE.toNanos()); - - // the server replies with page 1, the corresponding timeout should be cancelled - node1Behavior.setResponseSuccess(defaultFrameOf(DseTestFixtures.tenDseRows(1, false))); - assertThat(page1Timeout.isCancelled()).isTrue(); - - // request page 2, the queue is empty so this should request more pages and schedule another - // timeout - ContinuousAsyncResultSet page1 = CompletableFutures.getUninterruptibly(page1Future); - CompletionStage page2Future = page1.fetchNextPage(); - CapturedTimeout page2Timeout = harness.nextScheduledTimeout(); - assertThat(page2Timeout.getDelay(TimeUnit.NANOSECONDS)) - .isEqualTo(TIMEOUT_OTHER_PAGES.toNanos()); - - page2Timeout.task().run(page2Timeout); - - assertThatStage(page2Future) - .isFailed( - t -> - assertThat(t) - .isInstanceOf(DriverTimeoutException.class) - .hasMessageContaining("Timed out waiting for page 2")); - } - } - - @Test - @UseDataProvider(value = "allDseProtocolVersions", location = DseTestDataProviders.class) - public void should_cancel_future_if_session_cancelled(DseProtocolVersion version) { - RequestHandlerTestHarness.Builder builder = - continuousHarnessBuilder().withProtocolVersion(version); - PoolBehavior node1Behavior = builder.customBehavior(node1); - try (RequestHandlerTestHarness harness = builder.build()) { - - ContinuousCqlRequestHandler handler = - new ContinuousCqlRequestHandler( - UNDEFINED_IDEMPOTENCE_STATEMENT, harness.getSession(), harness.getContext(), "test"); - CompletionStage page1Future = handler.handle(); - - node1Behavior.setResponseSuccess(defaultFrameOf(DseTestFixtures.tenDseRows(1, false))); - // will be discarded - node1Behavior.setResponseSuccess(defaultFrameOf(DseTestFixtures.tenDseRows(2, false))); - - ContinuousAsyncResultSet page1 = CompletableFutures.getUninterruptibly(page1Future); - page1.cancel(); - - assertThat(handler.getState()).isEqualTo(-2); - assertThat(page1.fetchNextPage()).isCancelled(); - } - } - - @Test - @UseDataProvider(value = "allDseProtocolVersions", location = DseTestDataProviders.class) - public void should_cancel_session_if_future_cancelled(DseProtocolVersion version) { - RequestHandlerTestHarness.Builder builder = - continuousHarnessBuilder().withProtocolVersion(version); - PoolBehavior node1Behavior = builder.customBehavior(node1); - try (RequestHandlerTestHarness harness = builder.build()) { - - ContinuousCqlRequestHandler handler = - new ContinuousCqlRequestHandler( - UNDEFINED_IDEMPOTENCE_STATEMENT, harness.getSession(), harness.getContext(), "test"); - CompletionStage page1Future = handler.handle(); - - page1Future.toCompletableFuture().cancel(true); - // this should be ignored - node1Behavior.setResponseSuccess(defaultFrameOf(DseTestFixtures.tenDseRows(1, false))); - assertThat(handler.getState()).isEqualTo(-2); - } - } - - @Test - @UseDataProvider(value = "allDseProtocolVersions", location = DseTestDataProviders.class) - public void should_not_cancel_session_if_future_cancelled_but_already_done( - DseProtocolVersion version) { - RequestHandlerTestHarness.Builder builder = - continuousHarnessBuilder().withProtocolVersion(version); - PoolBehavior node1Behavior = builder.customBehavior(node1); - try (RequestHandlerTestHarness harness = builder.build()) { - - ContinuousCqlRequestHandler handler = - new ContinuousCqlRequestHandler( - UNDEFINED_IDEMPOTENCE_STATEMENT, harness.getSession(), harness.getContext(), "test"); - CompletionStage page1Future = handler.handle(); - - // this will complete page 1 future - node1Behavior.setResponseSuccess(defaultFrameOf(DseTestFixtures.tenDseRows(1, true))); - - // to late - page1Future.toCompletableFuture().cancel(true); - assertThat(handler.getState()).isEqualTo(-1); - } - } - - @Test - public void should_send_cancel_request_if_dse_v2() { - RequestHandlerTestHarness.Builder builder = - continuousHarnessBuilder().withProtocolVersion(DSE_V2); - PoolBehavior node1Behavior = builder.customBehavior(node1); - try (RequestHandlerTestHarness harness = builder.build()) { - - ContinuousCqlRequestHandler handler = - new ContinuousCqlRequestHandler( - UNDEFINED_IDEMPOTENCE_STATEMENT, harness.getSession(), harness.getContext(), "test"); - CompletionStage page1Future = handler.handle(); - - page1Future.toCompletableFuture().cancel(true); - assertThat(handler.getState()).isEqualTo(-2); - verify(node1Behavior.getChannel()) - .write(argThat(this::isCancelRequest), anyBoolean(), anyMap(), any()); - } - } - - @Test - public void should_toggle_channel_autoread_if_dse_v1() { - RequestHandlerTestHarness.Builder builder = - continuousHarnessBuilder().withProtocolVersion(DSE_V1); - PoolBehavior node1Behavior = builder.customBehavior(node1); - try (RequestHandlerTestHarness harness = builder.build()) { - - CompletionStage page1Future = - new ContinuousCqlRequestHandler( - UNDEFINED_IDEMPOTENCE_STATEMENT, - harness.getSession(), - harness.getContext(), - "test") - .handle(); - - // simulate the arrival of 5 pages, the first one will complete page1 future above, - // the following 4 will be enqueued and should trigger autoread off - node1Behavior.setResponseSuccess(defaultFrameOf(DseTestFixtures.tenDseRows(1, false))); - node1Behavior.setResponseSuccess(defaultFrameOf(DseTestFixtures.tenDseRows(2, false))); - node1Behavior.setResponseSuccess(defaultFrameOf(DseTestFixtures.tenDseRows(3, false))); - node1Behavior.setResponseSuccess(defaultFrameOf(DseTestFixtures.tenDseRows(4, false))); - node1Behavior.setResponseSuccess(defaultFrameOf(DseTestFixtures.tenDseRows(5, false))); - - verify(node1Behavior.getChannel().config()).setAutoRead(false); - - // simulate the retrieval of 2 pages, this should dequeue page 2 - // and trigger autoread on - ContinuousAsyncResultSet page1 = CompletableFutures.getCompleted(page1Future); - CompletableFutures.getCompleted(page1.fetchNextPage()); - - verify(node1Behavior.getChannel().config()).setAutoRead(true); - - // in DSE_V1, the backpressure request should not have been sent - verify(node1Behavior.getChannel(), never()) - .write(any(Revise.class), anyBoolean(), anyMap(), any()); - } - } - - @Test - public void should_send_backpressure_request_if_dse_v2() { - RequestHandlerTestHarness.Builder builder = - continuousHarnessBuilder().withProtocolVersion(DSE_V2); - PoolBehavior node1Behavior = builder.customBehavior(node1); - try (RequestHandlerTestHarness harness = builder.build()) { - - CompletionStage page1Future = - new ContinuousCqlRequestHandler( - UNDEFINED_IDEMPOTENCE_STATEMENT, - harness.getSession(), - harness.getContext(), - "test") - .handle(); - - // simulate the arrival of 4 pages, the first one will complete page1 future above, - // the following 3 will be enqueued - node1Behavior.setResponseSuccess(defaultFrameOf(DseTestFixtures.tenDseRows(1, false))); - node1Behavior.setResponseSuccess(defaultFrameOf(DseTestFixtures.tenDseRows(2, false))); - node1Behavior.setResponseSuccess(defaultFrameOf(DseTestFixtures.tenDseRows(3, false))); - node1Behavior.setResponseSuccess(defaultFrameOf(DseTestFixtures.tenDseRows(4, false))); - - // simulate the retrieval of 2 pages, this should dequeue page 2 - // and trigger a backpressure request as the queue is now half empty (2/4) - ContinuousAsyncResultSet page1 = CompletableFutures.getCompleted(page1Future); - CompletableFutures.getCompleted(page1.fetchNextPage()); - - verify(node1Behavior.getChannel()) - .write(argThat(this::isBackpressureRequest), anyBoolean(), anyMap(), any()); - // should not mess with autoread in dse v2 - verify(node1Behavior.getChannel().config(), never()).setAutoRead(anyBoolean()); - } - } - - @Test - @UseDataProvider(value = "allDseProtocolVersions", location = DseTestDataProviders.class) - public void should_invoke_request_tracker(DseProtocolVersion version) { - try (RequestHandlerTestHarness harness = - continuousHarnessBuilder() - .withProtocolVersion(version) - .withResponse( - node1, - defaultFrameOf( - new com.datastax.oss.protocol.internal.response.Error( - ProtocolConstants.ErrorCode.IS_BOOTSTRAPPING, "mock message"))) - .withResponse(node2, defaultFrameOf(DseTestFixtures.singleDseRow())) - .build()) { - - RequestTracker requestTracker = mock(RequestTracker.class); - when(harness.getContext().getRequestTracker()).thenReturn(requestTracker); - - CompletionStage resultSetFuture = - new ContinuousCqlRequestHandler( - UNDEFINED_IDEMPOTENCE_STATEMENT, - harness.getSession(), - harness.getContext(), - "test") - .handle(); - - assertThatStage(resultSetFuture) - .isSuccess( - resultSet -> { - Iterator rows = resultSet.currentPage().iterator(); - assertThat(rows.hasNext()).isTrue(); - assertThat(rows.next().getString("message")).isEqualTo("hello, world"); - ExecutionInfo executionInfo = resultSet.getExecutionInfo(); - assertThat(executionInfo.getCoordinator()).isEqualTo(node2); - assertThat(executionInfo.getErrors()).isNotEmpty(); - assertThat(executionInfo.getIncomingPayload()).isEmpty(); - assertThat(executionInfo.getPagingState()).isNull(); - assertThat(executionInfo.getSpeculativeExecutionCount()).isEqualTo(0); - assertThat(executionInfo.getSuccessfulExecutionIndex()).isEqualTo(0); - assertThat(executionInfo.getWarnings()).isEmpty(); - - verify(requestTracker) - .onNodeError( - eq(UNDEFINED_IDEMPOTENCE_STATEMENT), - any(BootstrappingException.class), - anyLong(), - any(DriverExecutionProfile.class), - eq(node1), - matches(LOG_PREFIX_PER_REQUEST)); - verify(requestTracker) - .onNodeSuccess( - eq(UNDEFINED_IDEMPOTENCE_STATEMENT), - anyLong(), - any(DriverExecutionProfile.class), - eq(node2), - matches(LOG_PREFIX_PER_REQUEST)); - verify(requestTracker) - .onSuccess( - eq(UNDEFINED_IDEMPOTENCE_STATEMENT), - anyLong(), - any(DriverExecutionProfile.class), - eq(node2), - matches(LOG_PREFIX_PER_REQUEST)); - verifyNoMoreInteractions(requestTracker); - }); - } - } - - private boolean isBackpressureRequest(Message argument) { - return argument instanceof Revise && ((Revise) argument).revisionType == MORE_CONTINUOUS_PAGES; - } - - private boolean isCancelRequest(Message argument) { - return argument instanceof Revise - && ((Revise) argument).revisionType == CANCEL_CONTINUOUS_PAGING; - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/cql/continuous/ContinuousCqlRequestHandlerTestBase.java b/core/src/test/java/com/datastax/dse/driver/internal/core/cql/continuous/ContinuousCqlRequestHandlerTestBase.java deleted file mode 100644 index 04195f5faf0..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/cql/continuous/ContinuousCqlRequestHandlerTestBase.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.cql.continuous; - -import static com.datastax.dse.driver.api.core.config.DseDriverOption.CONTINUOUS_PAGING_MAX_ENQUEUED_PAGES; -import static com.datastax.dse.driver.api.core.config.DseDriverOption.CONTINUOUS_PAGING_TIMEOUT_FIRST_PAGE; -import static com.datastax.dse.driver.api.core.config.DseDriverOption.CONTINUOUS_PAGING_TIMEOUT_OTHER_PAGES; -import static org.mockito.Mockito.when; - -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.internal.core.cql.CqlRequestHandlerTestBase; -import com.datastax.oss.driver.internal.core.cql.RequestHandlerTestHarness; -import java.time.Duration; - -public abstract class ContinuousCqlRequestHandlerTestBase extends CqlRequestHandlerTestBase { - - static final Duration TIMEOUT_FIRST_PAGE = Duration.ofSeconds(2); - static final Duration TIMEOUT_OTHER_PAGES = Duration.ofSeconds(1); - - protected RequestHandlerTestHarness.Builder continuousHarnessBuilder() { - return new RequestHandlerTestHarness.Builder() { - @Override - public RequestHandlerTestHarness build() { - RequestHandlerTestHarness harness = super.build(); - DriverExecutionProfile config = harness.getContext().getConfig().getDefaultProfile(); - when(config.getDuration(CONTINUOUS_PAGING_TIMEOUT_FIRST_PAGE)) - .thenReturn(TIMEOUT_FIRST_PAGE); - when(config.getDuration(CONTINUOUS_PAGING_TIMEOUT_OTHER_PAGES)) - .thenReturn(TIMEOUT_OTHER_PAGES); - when(config.getInt(CONTINUOUS_PAGING_MAX_ENQUEUED_PAGES)).thenReturn(4); - return harness; - } - }; - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/cql/continuous/DefaultContinuousAsyncResultSetTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/cql/continuous/DefaultContinuousAsyncResultSetTest.java deleted file mode 100644 index 1e59559013f..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/cql/continuous/DefaultContinuousAsyncResultSetTest.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.cql.continuous; - -import static com.datastax.oss.driver.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.verify; - -import com.datastax.dse.driver.api.core.cql.continuous.ContinuousAsyncResultSet; -import com.datastax.oss.driver.api.core.cql.ColumnDefinitions; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import com.datastax.oss.driver.api.core.cql.Row; -import com.datastax.oss.driver.internal.core.util.CountingIterator; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; -import org.assertj.core.api.ThrowableAssert.ThrowingCallable; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -public class DefaultContinuousAsyncResultSetTest { - - @Mock private ColumnDefinitions columnDefinitions; - @Mock private ExecutionInfo executionInfo; - @Mock private ContinuousCqlRequestHandler handler; - @Mock private CountingIterator rows; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - } - - @Test - public void should_fail_to_fetch_next_page_if_last() { - // Given - given(executionInfo.getPagingState()).willReturn(null); - DefaultContinuousAsyncResultSet resultSet = - new DefaultContinuousAsyncResultSet( - rows, columnDefinitions, 1, false, executionInfo, handler); - - // When - boolean hasMorePages = resultSet.hasMorePages(); - ThrowingCallable nextPage = resultSet::fetchNextPage; - - // Then - assertThat(hasMorePages).isFalse(); - assertThatThrownBy(nextPage) - .isInstanceOf(IllegalStateException.class) - .hasMessageContaining("Can't call fetchNextPage() on the last page"); - } - - @Test - public void should_invoke_handler_to_fetch_next_page() { - // Given - CompletableFuture mockResultFuture = new CompletableFuture<>(); - given(handler.fetchNextPage()).willReturn(mockResultFuture); - DefaultContinuousAsyncResultSet resultSet = - new DefaultContinuousAsyncResultSet( - rows, columnDefinitions, 1, true, executionInfo, handler); - - // When - boolean hasMorePages = resultSet.hasMorePages(); - CompletionStage nextPageFuture = resultSet.fetchNextPage(); - - // Then - assertThat(hasMorePages).isTrue(); - verify(handler).fetchNextPage(); - assertThat(nextPageFuture).isEqualTo(mockResultFuture); - } - - @Test - public void should_invoke_handler_to_cancel() { - // Given - DefaultContinuousAsyncResultSet resultSet = - new DefaultContinuousAsyncResultSet( - rows, columnDefinitions, 1, true, executionInfo, handler); - // When - resultSet.cancel(); - - // Then - verify(handler).cancel(); - } - - @Test - public void should_report_remaining_rows() { - // Given - given(rows.remaining()).willReturn(42); - DefaultContinuousAsyncResultSet resultSet = - new DefaultContinuousAsyncResultSet( - rows, columnDefinitions, 1, true, executionInfo, handler); - - // When - int remaining = resultSet.remaining(); - Iterable currentPage = resultSet.currentPage(); - - // Then - assertThat(remaining).isEqualTo(42); - assertThat(currentPage.iterator()).isSameAs(rows); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/cql/continuous/DefaultContinuousResultSetTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/cql/continuous/DefaultContinuousResultSetTest.java deleted file mode 100644 index 2bfb4768e49..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/cql/continuous/DefaultContinuousResultSetTest.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.cql.continuous; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.dse.driver.api.core.cql.continuous.ContinuousAsyncResultSet; -import com.datastax.oss.driver.api.core.cql.ColumnDefinitions; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import com.datastax.oss.driver.api.core.cql.ResultSet; -import com.datastax.oss.driver.api.core.cql.Row; -import com.datastax.oss.driver.internal.core.util.CountingIterator; -import java.util.Arrays; -import java.util.Iterator; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; -import org.junit.Test; -import org.mockito.Mockito; - -public class DefaultContinuousResultSetTest { - - @Test - public void should_create_result_set_from_single_page() { - // Given - ContinuousAsyncResultSet page1 = mockPage(false, 0, 1, 2); - - // When - ResultSet resultSet = new DefaultContinuousResultSet(page1); - - // Then - assertThat(resultSet.getColumnDefinitions()).isSameAs(page1.getColumnDefinitions()); - assertThat(resultSet.getExecutionInfo()).isSameAs(page1.getExecutionInfo()); - assertThat(resultSet.getExecutionInfos()).containsExactly(page1.getExecutionInfo()); - - Iterator iterator = resultSet.iterator(); - - assertNextRow(iterator, 0); - assertNextRow(iterator, 1); - assertNextRow(iterator, 2); - - assertThat(iterator.hasNext()).isFalse(); - } - - @Test - public void should_create_result_set_from_multiple_pages() { - // Given - ContinuousAsyncResultSet page1 = mockPage(true, 0, 1, 2); - ContinuousAsyncResultSet page2 = mockPage(true, 3, 4, 5); - ContinuousAsyncResultSet page3 = mockPage(false, 6, 7, 8); - - complete(page1.fetchNextPage(), page2); - complete(page2.fetchNextPage(), page3); - - // When - ResultSet resultSet = new DefaultContinuousResultSet(page1); - - // Then - assertThat(resultSet.iterator().hasNext()).isTrue(); - - assertThat(resultSet.getColumnDefinitions()).isSameAs(page1.getColumnDefinitions()); - assertThat(resultSet.getExecutionInfo()).isSameAs(page1.getExecutionInfo()); - assertThat(resultSet.getExecutionInfos()).containsExactly(page1.getExecutionInfo()); - - Iterator iterator = resultSet.iterator(); - - assertNextRow(iterator, 0); - assertNextRow(iterator, 1); - assertNextRow(iterator, 2); - - assertThat(iterator.hasNext()).isTrue(); - // This should have triggered the fetch of page2 - assertThat(resultSet.getExecutionInfo()).isEqualTo(page2.getExecutionInfo()); - assertThat(resultSet.getExecutionInfos()) - .containsExactly(page1.getExecutionInfo(), page2.getExecutionInfo()); - - assertNextRow(iterator, 3); - assertNextRow(iterator, 4); - assertNextRow(iterator, 5); - - assertThat(iterator.hasNext()).isTrue(); - // This should have triggered the fetch of page3 - assertThat(resultSet.getExecutionInfo()).isEqualTo(page3.getExecutionInfo()); - assertThat(resultSet.getExecutionInfos()) - .containsExactly( - page1.getExecutionInfo(), page2.getExecutionInfo(), page3.getExecutionInfo()); - - assertNextRow(iterator, 6); - assertNextRow(iterator, 7); - assertNextRow(iterator, 8); - } - - private static ContinuousAsyncResultSet mockPage(boolean nextPage, Integer... data) { - ContinuousAsyncResultSet page = Mockito.mock(ContinuousAsyncResultSet.class); - - ColumnDefinitions columnDefinitions = Mockito.mock(ColumnDefinitions.class); - Mockito.when(page.getColumnDefinitions()).thenReturn(columnDefinitions); - - ExecutionInfo executionInfo = Mockito.mock(ExecutionInfo.class); - Mockito.when(page.getExecutionInfo()).thenReturn(executionInfo); - - if (nextPage) { - Mockito.when(page.hasMorePages()).thenReturn(true); - Mockito.when(page.fetchNextPage()).thenReturn(Mockito.spy(new CompletableFuture<>())); - } else { - Mockito.when(page.hasMorePages()).thenReturn(false); - Mockito.when(page.fetchNextPage()).thenThrow(new IllegalStateException()); - } - - Iterator rows = Arrays.asList(data).iterator(); - CountingIterator iterator = - new CountingIterator(data.length) { - @Override - protected Row computeNext() { - return rows.hasNext() ? mockRow(rows.next()) : endOfData(); - } - }; - Mockito.when(page.currentPage()).thenReturn(() -> iterator); - Mockito.when(page.remaining()).thenAnswer(invocation -> iterator.remaining()); - - return page; - } - - private static Row mockRow(int index) { - Row row = Mockito.mock(Row.class); - Mockito.when(row.getInt(0)).thenReturn(index); - return row; - } - - private static void complete( - CompletionStage stage, ContinuousAsyncResultSet result) { - stage.toCompletableFuture().complete(result); - } - - private static void assertNextRow(Iterator iterator, int expectedValue) { - assertThat(iterator.hasNext()).isTrue(); - Row row0 = iterator.next(); - assertThat(row0.getInt(0)).isEqualTo(expectedValue); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/cql/continuous/reactive/ContinuousCqlRequestReactiveProcessorTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/cql/continuous/reactive/ContinuousCqlRequestReactiveProcessorTest.java deleted file mode 100644 index 0bfb00695d3..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/cql/continuous/reactive/ContinuousCqlRequestReactiveProcessorTest.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.cql.continuous.reactive; - -import static com.datastax.dse.driver.api.core.DseProtocolVersion.DSE_V1; -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.dse.driver.DseTestDataProviders; -import com.datastax.dse.driver.DseTestFixtures; -import com.datastax.dse.driver.api.core.DseProtocolVersion; -import com.datastax.dse.driver.api.core.cql.continuous.reactive.ContinuousReactiveResultSet; -import com.datastax.dse.driver.api.core.cql.reactive.ReactiveRow; -import com.datastax.dse.driver.internal.core.cql.continuous.ContinuousCqlRequestAsyncProcessor; -import com.datastax.dse.driver.internal.core.cql.continuous.ContinuousCqlRequestHandlerTestBase; -import com.datastax.oss.driver.api.core.cql.ColumnDefinitions; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import com.datastax.oss.driver.internal.core.cql.PoolBehavior; -import com.datastax.oss.driver.internal.core.cql.RequestHandlerTestHarness; -import com.datastax.oss.driver.internal.core.session.DefaultSession; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import io.reactivex.Flowable; -import java.util.List; -import org.junit.Test; - -public class ContinuousCqlRequestReactiveProcessorTest extends ContinuousCqlRequestHandlerTestBase { - - @Test - public void should_be_able_to_process_reactive_result_set() { - ContinuousCqlRequestReactiveProcessor processor = - new ContinuousCqlRequestReactiveProcessor(new ContinuousCqlRequestAsyncProcessor()); - assertThat( - processor.canProcess( - UNDEFINED_IDEMPOTENCE_STATEMENT, - ContinuousCqlRequestReactiveProcessor.CONTINUOUS_REACTIVE_RESULT_SET)) - .isTrue(); - } - - @Test - public void should_create_request_handler() { - RequestHandlerTestHarness.Builder builder = - continuousHarnessBuilder().withProtocolVersion(DSE_V1); - try (RequestHandlerTestHarness harness = builder.build()) { - ContinuousCqlRequestReactiveProcessor processor = - new ContinuousCqlRequestReactiveProcessor(new ContinuousCqlRequestAsyncProcessor()); - assertThat( - processor.process( - UNDEFINED_IDEMPOTENCE_STATEMENT, - harness.getSession(), - harness.getContext(), - "test")) - .isInstanceOf(DefaultContinuousReactiveResultSet.class); - } - } - - @Test - @UseDataProvider(value = "allDseProtocolVersions", location = DseTestDataProviders.class) - public void should_complete_single_page_result(DseProtocolVersion version) { - try (RequestHandlerTestHarness harness = - continuousHarnessBuilder() - .withProtocolVersion(version) - .withResponse(node1, defaultFrameOf(DseTestFixtures.singleDseRow())) - .build()) { - - DefaultSession session = harness.getSession(); - InternalDriverContext context = harness.getContext(); - - ContinuousReactiveResultSet publisher = - new ContinuousCqlRequestReactiveProcessor(new ContinuousCqlRequestAsyncProcessor()) - .process(UNDEFINED_IDEMPOTENCE_STATEMENT, session, context, "test"); - - List rows = Flowable.fromPublisher(publisher).toList().blockingGet(); - - assertThat(rows).hasSize(1); - ReactiveRow row = rows.get(0); - assertThat(row.getString("message")).isEqualTo("hello, world"); - ExecutionInfo executionInfo = row.getExecutionInfo(); - assertThat(executionInfo.getCoordinator()).isEqualTo(node1); - assertThat(executionInfo.getErrors()).isEmpty(); - assertThat(executionInfo.getIncomingPayload()).isEmpty(); - assertThat(executionInfo.getPagingState()).isNull(); - assertThat(executionInfo.getSpeculativeExecutionCount()).isEqualTo(0); - assertThat(executionInfo.getSuccessfulExecutionIndex()).isEqualTo(0); - assertThat(executionInfo.getWarnings()).isEmpty(); - - Flowable execInfosFlowable = - Flowable.fromPublisher(publisher.getExecutionInfos()); - assertThat(execInfosFlowable.toList().blockingGet()).containsExactly(executionInfo); - - Flowable colDefsFlowable = - Flowable.fromPublisher(publisher.getColumnDefinitions()); - assertThat(colDefsFlowable.toList().blockingGet()) - .containsExactly(row.getColumnDefinitions()); - - Flowable wasAppliedFlowable = Flowable.fromPublisher(publisher.wasApplied()); - assertThat(wasAppliedFlowable.toList().blockingGet()).containsExactly(row.wasApplied()); - } - } - - @Test - @UseDataProvider(value = "allDseProtocolVersions", location = DseTestDataProviders.class) - public void should_complete_multi_page_result(DseProtocolVersion version) { - RequestHandlerTestHarness.Builder builder = - continuousHarnessBuilder().withProtocolVersion(version); - PoolBehavior node1Behavior = builder.customBehavior(node1); - try (RequestHandlerTestHarness harness = builder.build()) { - - DefaultSession session = harness.getSession(); - InternalDriverContext context = harness.getContext(); - - ContinuousReactiveResultSet publisher = - new ContinuousCqlRequestReactiveProcessor(new ContinuousCqlRequestAsyncProcessor()) - .process(UNDEFINED_IDEMPOTENCE_STATEMENT, session, context, "test"); - - Flowable rowsPublisher = Flowable.fromPublisher(publisher).cache(); - rowsPublisher.subscribe(); - - node1Behavior.setResponseSuccess(defaultFrameOf(DseTestFixtures.tenDseRows(1, false))); - node1Behavior.setResponseSuccess(defaultFrameOf(DseTestFixtures.tenDseRows(2, true))); - - List rows = rowsPublisher.toList().blockingGet(); - assertThat(rows).hasSize(20); - - ReactiveRow first = rows.get(0); - ExecutionInfo firstExecutionInfo = first.getExecutionInfo(); - assertThat(firstExecutionInfo.getCoordinator()).isEqualTo(node1); - assertThat(firstExecutionInfo.getErrors()).isEmpty(); - assertThat(firstExecutionInfo.getIncomingPayload()).isEmpty(); - assertThat(firstExecutionInfo.getPagingState()).isNotNull(); - assertThat(firstExecutionInfo.getSpeculativeExecutionCount()).isEqualTo(0); - assertThat(firstExecutionInfo.getSuccessfulExecutionIndex()).isEqualTo(0); - assertThat(firstExecutionInfo.getWarnings()).isEmpty(); - - ReactiveRow inSecondPage = rows.get(10); - ExecutionInfo secondExecutionInfo = inSecondPage.getExecutionInfo(); - assertThat(secondExecutionInfo.getCoordinator()).isEqualTo(node1); - assertThat(secondExecutionInfo.getErrors()).isEmpty(); - assertThat(secondExecutionInfo.getIncomingPayload()).isEmpty(); - assertThat(secondExecutionInfo.getPagingState()).isNull(); - assertThat(secondExecutionInfo.getSpeculativeExecutionCount()).isEqualTo(0); - assertThat(secondExecutionInfo.getSuccessfulExecutionIndex()).isEqualTo(0); - assertThat(secondExecutionInfo.getWarnings()).isEmpty(); - - Flowable execInfosFlowable = - Flowable.fromPublisher(publisher.getExecutionInfos()); - assertThat(execInfosFlowable.toList().blockingGet()) - .containsExactly(firstExecutionInfo, secondExecutionInfo); - - Flowable colDefsFlowable = - Flowable.fromPublisher(publisher.getColumnDefinitions()); - assertThat(colDefsFlowable.toList().blockingGet()) - .containsExactly(first.getColumnDefinitions()); - - Flowable wasAppliedFlowable = Flowable.fromPublisher(publisher.wasApplied()); - assertThat(wasAppliedFlowable.toList().blockingGet()).containsExactly(first.wasApplied()); - } - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/cql/reactive/CqlRequestReactiveProcessorTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/cql/reactive/CqlRequestReactiveProcessorTest.java index a7a6bced9e8..eb755ad1945 100644 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/cql/reactive/CqlRequestReactiveProcessorTest.java +++ b/core/src/test/java/com/datastax/dse/driver/internal/core/cql/reactive/CqlRequestReactiveProcessorTest.java @@ -17,15 +17,13 @@ */ package com.datastax.dse.driver.internal.core.cql.reactive; -import static com.datastax.dse.driver.DseTestFixtures.singleDseRow; -import static com.datastax.dse.driver.api.core.DseProtocolVersion.DSE_V1; +import static com.datastax.dse.driver.internal.core.cql.reactive.ReactiveTestFixtures.singleRow; +import static com.datastax.oss.driver.api.core.ProtocolVersion.V4; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import com.datastax.dse.driver.DseTestDataProviders; -import com.datastax.dse.driver.DseTestFixtures; import com.datastax.dse.driver.api.core.cql.reactive.ReactiveResultSet; import com.datastax.dse.driver.api.core.cql.reactive.ReactiveRow; import com.datastax.oss.driver.api.core.ProtocolVersion; @@ -61,7 +59,7 @@ public void should_be_able_to_process_reactive_result_set() { @Test public void should_create_request_handler() { RequestHandlerTestHarness.Builder builder = - RequestHandlerTestHarness.builder().withProtocolVersion(DSE_V1); + RequestHandlerTestHarness.builder().withProtocolVersion(V4); try (RequestHandlerTestHarness harness = builder.build()) { CqlRequestReactiveProcessor processor = new CqlRequestReactiveProcessor(new CqlRequestAsyncProcessor()); @@ -76,12 +74,12 @@ public void should_create_request_handler() { } @Test - @UseDataProvider(value = "allDseAndOssProtocolVersions", location = DseTestDataProviders.class) + @UseDataProvider(value = "allOssProtocolVersions", location = ReactiveTestDataProviders.class) public void should_complete_single_page_result(ProtocolVersion version) { try (RequestHandlerTestHarness harness = RequestHandlerTestHarness.builder() .withProtocolVersion(version) - .withResponse(node1, defaultFrameOf(singleDseRow())) + .withResponse(node1, defaultFrameOf(singleRow())) .build()) { DefaultSession session = harness.getSession(); @@ -120,7 +118,7 @@ public void should_complete_single_page_result(ProtocolVersion version) { } @Test - @UseDataProvider(value = "allDseAndOssProtocolVersions", location = DseTestDataProviders.class) + @UseDataProvider(value = "allOssProtocolVersions", location = ReactiveTestDataProviders.class) public void should_complete_multi_page_result(ProtocolVersion version) { RequestHandlerTestHarness.Builder builder = RequestHandlerTestHarness.builder().withProtocolVersion(version); @@ -144,12 +142,12 @@ public void should_complete_multi_page_result(ProtocolVersion version) { rowsPublisher.subscribe(); // emulate arrival of page 1 - node1Behavior.setResponseSuccess(defaultFrameOf(DseTestFixtures.tenDseRows(1, false))); + node1Behavior.setResponseSuccess(defaultFrameOf(ReactiveTestFixtures.tenRows(1, false))); // emulate arrival of page 2 following the call to session.executeAsync() page2Future.complete( Conversions.toResultSet( - DseTestFixtures.tenDseRows(2, true), + ReactiveTestFixtures.tenRows(2, true), mockInfo, harness.getSession(), harness.getContext())); diff --git a/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseVertexMetadata.java b/core/src/test/java/com/datastax/dse/driver/internal/core/cql/reactive/ReactiveTestDataProviders.java similarity index 59% rename from core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseVertexMetadata.java rename to core/src/test/java/com/datastax/dse/driver/internal/core/cql/reactive/ReactiveTestDataProviders.java index c08a7eb1d60..cfafe7a5054 100644 --- a/core/src/main/java/com/datastax/dse/driver/api/core/metadata/schema/DseVertexMetadata.java +++ b/core/src/test/java/com/datastax/dse/driver/internal/core/cql/reactive/ReactiveTestDataProviders.java @@ -15,15 +15,26 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.datastax.dse.driver.api.core.metadata.schema; +package com.datastax.dse.driver.internal.core.cql.reactive; -import com.datastax.oss.driver.api.core.CqlIdentifier; +import com.datastax.oss.driver.api.core.DefaultProtocolVersion; +import com.tngtech.java.junit.dataprovider.DataProvider; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Arrays; +import java.util.stream.Stream; -/** Vertex metadata, for a table that was created with CREATE TABLE ... WITH VERTEX LABEL. */ -public interface DseVertexMetadata { +public class ReactiveTestDataProviders { + + @DataProvider + public static Object[][] allOssProtocolVersions() { + return concat(DefaultProtocolVersion.values()); + } - /** The label of the vertex in graph. */ @NonNull - CqlIdentifier getLabelName(); + private static Object[][] concat(Object[]... values) { + return Stream.of(values) + .flatMap(Arrays::stream) + .map(o -> new Object[] {o}) + .toArray(Object[][]::new); + } } diff --git a/core/src/test/java/com/datastax/dse/driver/DseTestFixtures.java b/core/src/test/java/com/datastax/dse/driver/internal/core/cql/reactive/ReactiveTestFixtures.java similarity index 51% rename from core/src/test/java/com/datastax/dse/driver/DseTestFixtures.java rename to core/src/test/java/com/datastax/dse/driver/internal/core/cql/reactive/ReactiveTestFixtures.java index 7992dde4fea..c44a9e19f24 100644 --- a/core/src/test/java/com/datastax/dse/driver/DseTestFixtures.java +++ b/core/src/test/java/com/datastax/dse/driver/internal/core/cql/reactive/ReactiveTestFixtures.java @@ -15,39 +15,27 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.datastax.dse.driver; +package com.datastax.dse.driver.internal.core.cql.reactive; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import com.datastax.dse.driver.api.core.metadata.DseNodeProperties; -import com.datastax.dse.protocol.internal.response.result.DseRowsMetadata; -import com.datastax.oss.driver.api.core.Version; -import com.datastax.oss.driver.api.core.metadata.Metadata; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.datastax.oss.driver.internal.core.context.DefaultDriverContext; -import com.datastax.oss.driver.internal.core.metadata.MetadataManager; import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; import com.datastax.oss.protocol.internal.ProtocolConstants; import com.datastax.oss.protocol.internal.response.result.ColumnSpec; import com.datastax.oss.protocol.internal.response.result.DefaultRows; import com.datastax.oss.protocol.internal.response.result.RawType; import com.datastax.oss.protocol.internal.response.result.Rows; +import com.datastax.oss.protocol.internal.response.result.RowsMetadata; import com.datastax.oss.protocol.internal.util.Bytes; import java.nio.ByteBuffer; import java.util.ArrayDeque; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Queue; -import java.util.UUID; -public class DseTestFixtures { +public class ReactiveTestFixtures { // Returns a single row, with a single "message" column with the value "hello, world" - public static Rows singleDseRow() { - DseRowsMetadata metadata = - new DseRowsMetadata( + public static Rows singleRow() { + RowsMetadata metadata = + new RowsMetadata( ImmutableList.of( new ColumnSpec( "ks", @@ -57,18 +45,16 @@ public static Rows singleDseRow() { RawType.PRIMITIVES.get(ProtocolConstants.DataType.VARCHAR))), null, new int[] {}, - null, - 1, - true); + null); Queue> data = new ArrayDeque<>(); data.add(ImmutableList.of(Bytes.fromHexString("0x68656C6C6F2C20776F726C64"))); return new DefaultRows(metadata, data); } // Returns 10 rows, each with a single "message" column with the value "hello, world" - public static Rows tenDseRows(int page, boolean last) { - DseRowsMetadata metadata = - new DseRowsMetadata( + public static Rows tenRows(int page, boolean last) { + RowsMetadata metadata = + new RowsMetadata( ImmutableList.of( new ColumnSpec( "ks", @@ -78,48 +64,11 @@ public static Rows tenDseRows(int page, boolean last) { RawType.PRIMITIVES.get(ProtocolConstants.DataType.VARCHAR))), last ? null : ByteBuffer.wrap(new byte[] {(byte) page}), new int[] {}, - null, - page, - last); + null); Queue> data = new ArrayDeque<>(); for (int i = 0; i < 10; i++) { data.add(ImmutableList.of(Bytes.fromHexString("0x68656C6C6F2C20776F726C64"))); } return new DefaultRows(metadata, data); } - - public static DefaultDriverContext mockNodesInMetadataWithVersions( - DefaultDriverContext mockContext, boolean treatNullAsMissing, Version... dseVersions) { - - // mock bits of the context - MetadataManager metadataManager = mock(MetadataManager.class); - Metadata metadata = mock(Metadata.class); - Map nodeMap = new HashMap<>((dseVersions != null) ? dseVersions.length : 1); - if (dseVersions == null) { - Node node = mock(Node.class); - Map nodeExtras = new HashMap<>(1); - if (!treatNullAsMissing) { - // put an explicit null in for DSE_VERSION - nodeExtras.put(DseNodeProperties.DSE_VERSION, null); - } - nodeMap.put(UUID.randomUUID(), node); - when(node.getExtras()).thenReturn(nodeExtras); - } else { - for (Version dseVersion : dseVersions) { - // create a node with DSE version in its extra data - Node node = mock(Node.class); - Map nodeExtras = new HashMap<>(1); - if (dseVersion != null || !treatNullAsMissing) { - nodeExtras.put(DseNodeProperties.DSE_VERSION, dseVersion); - } - nodeMap.put(UUID.randomUUID(), node); - when(node.getExtras()).thenReturn(nodeExtras); - } - } - // return mocked data when requested - when(metadata.getNodes()).thenReturn(nodeMap); - when(metadataManager.getMetadata()).thenReturn(metadata); - when(mockContext.getMetadataManager()).thenReturn(metadataManager); - return mockContext; - } } diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/data/geometry/DefaultLineStringTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/data/geometry/DefaultLineStringTest.java deleted file mode 100644 index 38dc84549c4..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/data/geometry/DefaultLineStringTest.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.data.geometry; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Fail.fail; - -import com.datastax.dse.driver.api.core.data.geometry.LineString; -import com.datastax.dse.driver.api.core.data.geometry.Point; -import com.esri.core.geometry.ogc.OGCLineString; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import org.junit.Test; - -public class DefaultLineStringTest { - private final LineString lineString = - LineString.fromPoints( - Point.fromCoordinates(30, 10), - Point.fromCoordinates(10, 30), - Point.fromCoordinates(40, 40)); - - private final String wkt = "LINESTRING (30 10, 10 30, 40 40)"; - - private final String json = - "{\"type\":\"LineString\",\"coordinates\":[[30.0,10.0],[10.0,30.0],[40.0,40.0]]}"; - - @Test - public void should_parse_valid_well_known_text() { - assertThat(LineString.fromWellKnownText(wkt)).isEqualTo(lineString); - } - - @Test - public void should_fail_to_parse_invalid_well_known_text() { - assertInvalidWkt("linestring()"); - assertInvalidWkt("linestring(30 10 20, 10 30 20)"); // 3d - assertInvalidWkt("linestring(0 0, 1 1, 0 1, 1 0)"); // crossing itself - assertInvalidWkt("superlinestring(30 10, 10 30, 40 40)"); - } - - @Test - public void should_convert_to_well_known_text() { - assertThat(lineString.toString()).isEqualTo(wkt); - } - - @Test - public void should_convert_to_well_known_binary() { - ByteBuffer actual = lineString.asWellKnownBinary(); - - ByteBuffer expected = ByteBuffer.allocate(1024).order(ByteOrder.nativeOrder()); - expected.position(0); - expected.put((byte) (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN ? 1 : 0)); // endianness - expected.putInt(2); // type - expected.putInt(3); // num lineStrings - expected.putDouble(30); // x1 - expected.putDouble(10); // y1 - expected.putDouble(10); // x2 - expected.putDouble(30); // y2 - expected.putDouble(40); // x3 - expected.putDouble(40); // y3 - expected.flip(); - - assertThat(actual).isEqualTo(expected); - } - - @Test - public void should_load_from_well_known_binary() { - ByteBuffer bb = ByteBuffer.allocate(1024).order(ByteOrder.nativeOrder()); - bb.position(0); - bb.put((byte) (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN ? 1 : 0)); // endianness - bb.putInt(2); // type - bb.putInt(3); // num lineStrings - bb.putDouble(30); // x1 - bb.putDouble(10); // y1 - bb.putDouble(10); // x2 - bb.putDouble(30); // y2 - bb.putDouble(40); // x3 - bb.putDouble(40); // y3 - bb.flip(); - - assertThat(LineString.fromWellKnownBinary(bb)).isEqualTo(lineString); - } - - @Test - public void should_parse_valid_geo_json() { - assertThat(LineString.fromGeoJson(json)).isEqualTo(lineString); - } - - @Test - public void should_convert_to_geo_json() { - assertThat(lineString.asGeoJson()).isEqualTo(json); - } - - @Test - public void should_convert_to_ogc_line_string() { - assertThat(((DefaultLineString) lineString).getOgcGeometry()).isInstanceOf(OGCLineString.class); - } - - @Test - public void should_produce_same_hashCode_for_equal_objects() { - LineString line1 = - LineString.fromPoints( - Point.fromCoordinates(30, 10), - Point.fromCoordinates(10, 30), - Point.fromCoordinates(40, 40)); - LineString line2 = LineString.fromWellKnownText(wkt); - assertThat(line1).isEqualTo(line2); - assertThat(line1.hashCode()).isEqualTo(line2.hashCode()); - } - - @Test - public void should_expose_points() { - assertThat(lineString.getPoints()) - .containsOnly( - Point.fromCoordinates(30, 10), - Point.fromCoordinates(10, 30), - Point.fromCoordinates(40, 40)); - assertThat(LineString.fromWellKnownText(wkt).getPoints()) - .containsOnly( - Point.fromCoordinates(30, 10), - Point.fromCoordinates(10, 30), - Point.fromCoordinates(40, 40)); - } - - @Test - public void should_encode_and_decode() throws Exception { - assertThat(SerializationUtils.serializeAndDeserialize(lineString)).isEqualTo(lineString); - } - - @Test - public void should_contain_self() { - assertThat(lineString.contains(lineString)).isTrue(); - } - - @Test - public void should_contain_all_intersected_points_except_start_and_end() { - LineString s = - LineString.fromPoints( - Point.fromCoordinates(0, 0), - Point.fromCoordinates(0, 30), - Point.fromCoordinates(30, 30)); - assertThat(s.contains(Point.fromCoordinates(0, 0))).isFalse(); - assertThat(s.contains(Point.fromCoordinates(0, 15))).isTrue(); - assertThat(s.contains(Point.fromCoordinates(0, 30))).isTrue(); - assertThat(s.contains(Point.fromCoordinates(15, 30))).isTrue(); - assertThat(s.contains(Point.fromCoordinates(30, 30))).isFalse(); - } - - @Test - public void should_contain_substring() { - assertThat( - lineString.contains( - LineString.fromPoints( - Point.fromCoordinates(30, 10), Point.fromCoordinates(10, 30)))) - .isTrue(); - } - - @Test - public void should_not_contain_unrelated_string() { - assertThat( - lineString.contains( - LineString.fromPoints( - Point.fromCoordinates(10, 10), Point.fromCoordinates(30, 30)))) - .isFalse(); - } - - @Test - public void should_not_contain_polygon() { - LineString s = - LineString.fromPoints( - Point.fromCoordinates(0, 0), - Point.fromCoordinates(0, 30), - Point.fromCoordinates(30, 30), - Point.fromCoordinates(30, 0)); - LineString p = - LineString.fromPoints( - Point.fromCoordinates(10, 10), - Point.fromCoordinates(10, 20), - Point.fromCoordinates(20, 20), - Point.fromCoordinates(20, 10)); - assertThat(s.contains(p)).isFalse(); - } - - @Test - public void should_accept_empty_shape() throws Exception { - DefaultLineString s = ((DefaultLineString) LineString.fromWellKnownText("LINESTRING EMPTY")); - assertThat(s.getOgcGeometry().isEmpty()).isTrue(); - } - - private void assertInvalidWkt(String s) { - try { - LineString.fromWellKnownText(s); - fail("Should have thrown InvalidTypeException"); - } catch (IllegalArgumentException e) { - // expected - } - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/data/geometry/DefaultPointTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/data/geometry/DefaultPointTest.java deleted file mode 100644 index 1e3a7366741..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/data/geometry/DefaultPointTest.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.data.geometry; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Fail.fail; - -import com.datastax.dse.driver.api.core.data.geometry.Point; -import com.esri.core.geometry.ogc.OGCPoint; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import org.junit.Test; - -public class DefaultPointTest { - - private DefaultPoint point = new DefaultPoint(1.1, 2.2); - - private final String wkt = "POINT (1.1 2.2)"; - - private final String json = "{\"type\":\"Point\",\"coordinates\":[1.1,2.2]}"; - - @Test - public void should_parse_valid_well_known_text() { - assertThat(Point.fromWellKnownText(wkt)).isEqualTo(point); - } - - @Test - public void should_fail_to_parse_invalid_well_known_text() { - assertInvalidWkt("superpoint(1.1 2.2 3.3)"); - } - - @Test - public void should_convert_to_well_known_text() { - assertThat(point.toString()).isEqualTo(wkt); - } - - @Test - public void should_convert_to_well_knowm_binary() { - ByteBuffer actual = point.asWellKnownBinary(); - - ByteBuffer expected = ByteBuffer.allocate(1024).order(ByteOrder.nativeOrder()); - expected.position(0); - expected.put((byte) (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN ? 1 : 0)); // endianness - expected.putInt(1); // type - expected.putDouble(1.1); // x - expected.putDouble(2.2); // y - expected.flip(); - - assertThat(actual).isEqualTo(expected); - } - - @Test - public void should_load_from_well_known_binary() { - ByteBuffer bb = ByteBuffer.allocate(1024).order(ByteOrder.nativeOrder()); - bb.position(0); - bb.put((byte) (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN ? 1 : 0)); // endianness - bb.putInt(1); // type - bb.putDouble(1.1); // x - bb.putDouble(2.2); // y - bb.flip(); - - assertThat(Point.fromWellKnownBinary(bb)).isEqualTo(point); - } - - @Test - public void should_parse_valid_geo_json() { - assertThat(Point.fromGeoJson(json)).isEqualTo(point); - } - - @Test - public void should_convert_to_geo_json() { - assertThat(point.asGeoJson()).isEqualTo(json); - } - - @Test - public void should_convert_to_ogc_point() { - assertThat(point.getOgcGeometry()).isInstanceOf(OGCPoint.class); - } - - @Test - public void should_produce_same_hashCode_for_equal_objects() { - Point point1 = new DefaultPoint(10, 20); - Point point2 = Point.fromWellKnownText("POINT (10 20)"); - assertThat(point1).isEqualTo(point2); - assertThat(point1.hashCode()).isEqualTo(point2.hashCode()); - } - - @Test - public void should_encode_and_decode() throws Exception { - assertThat(SerializationUtils.serializeAndDeserialize(point)).isEqualTo(point); - } - - @Test - public void should_contain_self() { - assertThat(point.contains(point)).isTrue(); - } - - @Test - public void should_not_contain_any_other_shape_than_self() { - DefaultPoint point2 = new DefaultPoint(1, 2); - DefaultPoint point3 = new DefaultPoint(1, 3); - assertThat(point.contains(point2)).isFalse(); - assertThat(point.contains(new DefaultLineString(point, point2))).isFalse(); - assertThat(point.contains(new DefaultPolygon(point, point2, point3))).isFalse(); - } - - @Test - public void should_accept_empty_shape() throws Exception { - DefaultPoint point = ((DefaultPoint) Point.fromWellKnownText("POINT EMPTY")); - assertThat(point.getOgcGeometry().isEmpty()).isTrue(); - } - - private void assertInvalidWkt(String s) { - try { - Point.fromWellKnownText(s); - fail("Should have thrown InvalidTypeException"); - } catch (IllegalArgumentException e) { - // expected - } - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/data/geometry/DefaultPolygonTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/data/geometry/DefaultPolygonTest.java deleted file mode 100644 index d86e9cdc269..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/data/geometry/DefaultPolygonTest.java +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.data.geometry; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Fail.fail; - -import com.datastax.dse.driver.api.core.data.geometry.LineString; -import com.datastax.dse.driver.api.core.data.geometry.Point; -import com.datastax.dse.driver.api.core.data.geometry.Polygon; -import com.esri.core.geometry.ogc.OGCPolygon; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import org.junit.Test; - -public class DefaultPolygonTest { - - private Polygon polygon = - Polygon.fromPoints( - Point.fromCoordinates(30, 10), - Point.fromCoordinates(10, 20), - Point.fromCoordinates(20, 40), - Point.fromCoordinates(40, 40)); - - private String wkt = "POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))"; - - private String json = - "{\"type\":\"Polygon\",\"coordinates\":[[[30.0,10.0],[10.0,20.0],[20.0,40.0],[40.0,40.0],[30.0,10.0]]]}"; - - @Test - public void should_parse_valid_well_known_text() { - assertThat(Polygon.fromWellKnownText(wkt)).isEqualTo(polygon); - } - - @Test - public void should_fail_to_parse_invalid_well_known_text() { - assertInvalidWkt("polygon(())"); // malformed - assertInvalidWkt("polygon((30 10 1, 40 40 1, 20 40 1, 10 20 1, 30 10 1))"); // 3d - assertInvalidWkt("polygon((0 0, 1 1, 0 1, 1 0, 0 0))"); // crosses itself - assertInvalidWkt("polygon123((30 10, 40 40, 20 40, 10 20, 30 10))"); // malformed - } - - @Test - public void should_convert_to_well_known_binary() { - ByteBuffer actual = polygon.asWellKnownBinary(); - - ByteBuffer expected = ByteBuffer.allocate(1024).order(ByteOrder.nativeOrder()); - expected.position(0); - expected.put((byte) (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN ? 1 : 0)); // endianness - expected.putInt(3); // type - expected.putInt(1); // num rings - expected.putInt(5); // num polygons (ring 1/1) - expected.putDouble(30); // x1 - expected.putDouble(10); // y1 - expected.putDouble(40); // x2 - expected.putDouble(40); // y2 - expected.putDouble(20); // x3 - expected.putDouble(40); // y3 - expected.putDouble(10); // x4 - expected.putDouble(20); // y4 - expected.putDouble(30); // x5 - expected.putDouble(10); // y5 - expected.flip(); - - assertThat(actual).isEqualTo(expected); - } - - @Test - public void should_load_from_well_known_binary() { - ByteBuffer bb = ByteBuffer.allocate(1024).order(ByteOrder.nativeOrder()); - bb.position(0); - bb.put((byte) (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN ? 1 : 0)); // endianness - bb.putInt(3); // type - bb.putInt(1); // num rings - bb.putInt(5); // num polygons (ring 1/1) - bb.putDouble(30); // x1 - bb.putDouble(10); // y1 - bb.putDouble(40); // x2 - bb.putDouble(40); // y2 - bb.putDouble(20); // x3 - bb.putDouble(40); // y3 - bb.putDouble(10); // x4 - bb.putDouble(20); // y4 - bb.putDouble(30); // x5 - bb.putDouble(10); // y5 - bb.flip(); - - assertThat(Polygon.fromWellKnownBinary(bb)).isEqualTo(polygon); - } - - @Test - public void should_parse_valid_geo_json() { - assertThat(Polygon.fromGeoJson(json)).isEqualTo(polygon); - } - - @Test - public void should_convert_to_geo_json() { - assertThat(polygon.asGeoJson()).isEqualTo(json); - } - - @Test - public void should_convert_to_ogc_polygon() { - assertThat(((DefaultPolygon) polygon).getOgcGeometry()).isInstanceOf(OGCPolygon.class); - } - - @Test - public void should_produce_same_hashCode_for_equal_objects() { - Polygon polygon1 = - Polygon.fromPoints( - Point.fromCoordinates(30, 10), - Point.fromCoordinates(10, 20), - Point.fromCoordinates(20, 40), - Point.fromCoordinates(40, 40)); - Polygon polygon2 = Polygon.fromWellKnownText(wkt); - assertThat(polygon1).isEqualTo(polygon2); - assertThat(polygon1.hashCode()).isEqualTo(polygon2.hashCode()); - } - - @Test - public void should_build_with_constructor_without_checking_orientation() { - // By default, OGC requires outer rings to be clockwise and inner rings to be counterclockwise. - // We disable that in our constructors. - // This polygon has a single outer ring that is counterclockwise. - Polygon polygon = - Polygon.fromPoints( - Point.fromCoordinates(5, 0), - Point.fromCoordinates(5, 3), - Point.fromCoordinates(0, 3), - Point.fromCoordinates(0, 0)); - assertThat(polygon.asWellKnownText()).isEqualTo("POLYGON ((0 0, 5 0, 5 3, 0 3, 0 0))"); - } - - @Test - public void should_build_complex_polygon_with_builder() { - Polygon polygon = - Polygon.builder() - .addRing( - Point.fromCoordinates(0, 0), - Point.fromCoordinates(0, 3), - Point.fromCoordinates(5, 3), - Point.fromCoordinates(5, 0)) - .addRing( - Point.fromCoordinates(1, 1), - Point.fromCoordinates(1, 2), - Point.fromCoordinates(2, 2), - Point.fromCoordinates(2, 1)) - .addRing( - Point.fromCoordinates(3, 1), - Point.fromCoordinates(3, 2), - Point.fromCoordinates(4, 2), - Point.fromCoordinates(4, 1)) - .build(); - assertThat(polygon.asWellKnownText()) - .isEqualTo( - "POLYGON ((0 0, 5 0, 5 3, 0 3, 0 0), (1 1, 1 2, 2 2, 2 1, 1 1), (3 1, 3 2, 4 2, 4 1, 3 1))"); - } - - @Test - public void should_expose_rings() { - assertThat(polygon.getExteriorRing()) - .containsOnly( - Point.fromCoordinates(30, 10), - Point.fromCoordinates(10, 20), - Point.fromCoordinates(20, 40), - Point.fromCoordinates(40, 40)); - assertThat(polygon.getInteriorRings().isEmpty()).isTrue(); - - Polygon fromWkt = Polygon.fromWellKnownText(wkt); - assertThat(fromWkt.getExteriorRing()) - .containsOnly( - Point.fromCoordinates(30, 10), - Point.fromCoordinates(10, 20), - Point.fromCoordinates(20, 40), - Point.fromCoordinates(40, 40)); - assertThat(fromWkt.getInteriorRings().isEmpty()).isTrue(); - - Polygon complex = - Polygon.builder() - .addRing( - Point.fromCoordinates(0, 0), - Point.fromCoordinates(0, 3), - Point.fromCoordinates(5, 3), - Point.fromCoordinates(5, 0)) - .addRing( - Point.fromCoordinates(1, 1), - Point.fromCoordinates(1, 2), - Point.fromCoordinates(2, 2), - Point.fromCoordinates(2, 1)) - .addRing( - Point.fromCoordinates(3, 1), - Point.fromCoordinates(3, 2), - Point.fromCoordinates(4, 2), - Point.fromCoordinates(4, 1)) - .build(); - assertThat(complex.getExteriorRing()) - .containsOnly( - Point.fromCoordinates(0, 0), - Point.fromCoordinates(0, 3), - Point.fromCoordinates(5, 3), - Point.fromCoordinates(5, 0)); - assertThat(complex.getInteriorRings()).hasSize(2); - assertThat(complex.getInteriorRings().get(0)) - .containsOnly( - Point.fromCoordinates(1, 1), - Point.fromCoordinates(1, 2), - Point.fromCoordinates(2, 2), - Point.fromCoordinates(2, 1)); - assertThat(complex.getInteriorRings().get(1)) - .containsOnly( - Point.fromCoordinates(3, 1), - Point.fromCoordinates(3, 2), - Point.fromCoordinates(4, 2), - Point.fromCoordinates(4, 1)); - - Polygon complexFromWkt = - Polygon.fromWellKnownText( - "POLYGON ((0 0, 5 0, 5 3, 0 3, 0 0), (1 1, 1 2, 2 2, 2 1, 1 1), (3 1, 3 2, 4 2, 4 1, 3 1))"); - assertThat(complexFromWkt.getExteriorRing()) - .containsOnly( - Point.fromCoordinates(0, 0), - Point.fromCoordinates(0, 3), - Point.fromCoordinates(5, 3), - Point.fromCoordinates(5, 0)); - assertThat(complexFromWkt.getInteriorRings()).hasSize(2); - assertThat(complexFromWkt.getInteriorRings().get(0)) - .containsOnly( - Point.fromCoordinates(1, 1), - Point.fromCoordinates(1, 2), - Point.fromCoordinates(2, 2), - Point.fromCoordinates(2, 1)); - assertThat(complexFromWkt.getInteriorRings().get(1)) - .containsOnly( - Point.fromCoordinates(3, 1), - Point.fromCoordinates(3, 2), - Point.fromCoordinates(4, 2), - Point.fromCoordinates(4, 1)); - } - - @Test - public void should_encode_and_decode() throws Exception { - assertThat(SerializationUtils.serializeAndDeserialize(polygon)).isEqualTo(polygon); - } - - @Test - public void should_contain_self() { - assertThat(polygon.contains(polygon)).isTrue(); - } - - @Test - public void should_not_contain_point_or_linestring_on_exterior_ring() { - assertThat(polygon.contains(Point.fromCoordinates(30, 10))).isFalse(); - assertThat(polygon.contains(Point.fromCoordinates(30, 40))).isFalse(); - assertThat( - polygon.contains( - LineString.fromPoints( - Point.fromCoordinates(35, 40), Point.fromCoordinates(25, 40)))) - .isFalse(); - } - - @Test - public void should_contain_interior_shape() { - assertThat(polygon.contains(Point.fromCoordinates(20, 20))).isTrue(); - assertThat( - polygon.contains( - LineString.fromPoints( - Point.fromCoordinates(20, 20), Point.fromCoordinates(30, 20)))) - .isTrue(); - assertThat( - polygon.contains( - Polygon.fromPoints( - Point.fromCoordinates(20, 20), - Point.fromCoordinates(30, 20), - Point.fromCoordinates(20, 30)))) - .isTrue(); - } - - @Test - public void should_not_contain_exterior_shape() { - assertThat(polygon.contains(Point.fromCoordinates(10, 10))).isFalse(); - assertThat( - polygon.contains( - LineString.fromPoints( - Point.fromCoordinates(10, 10), Point.fromCoordinates(20, 20)))) - .isFalse(); - assertThat( - polygon.contains( - Polygon.fromPoints( - Point.fromCoordinates(0, 0), - Point.fromCoordinates(0, 10), - Point.fromCoordinates(10, 10)))) - .isFalse(); - } - - @Test - public void should_not_contain_shapes_in_interior_hole() { - Polygon complex = - Polygon.builder() - .addRing( - Point.fromCoordinates(0, 0), - Point.fromCoordinates(30, 0), - Point.fromCoordinates(30, 30), - Point.fromCoordinates(0, 30)) - .addRing( - Point.fromCoordinates(10, 10), - Point.fromCoordinates(20, 10), - Point.fromCoordinates(20, 20), - Point.fromCoordinates(10, 20)) - .build(); - assertThat(complex.contains(Point.fromCoordinates(15, 15))).isFalse(); - } - - @Test - public void should_accept_empty_shape() throws Exception { - Polygon polygon = Polygon.fromWellKnownText("POLYGON EMPTY"); - assertThat(polygon.getExteriorRing()).isEmpty(); - assertThat(((DefaultPolygon) polygon).getOgcGeometry().isEmpty()).isTrue(); - } - - private void assertInvalidWkt(String s) { - try { - Polygon.fromWellKnownText(s); - fail("Should have thrown InvalidTypeException"); - } catch (IllegalArgumentException e) { - // expected - } - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/data/geometry/DistanceTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/data/geometry/DistanceTest.java deleted file mode 100644 index ba158288891..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/data/geometry/DistanceTest.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.data.geometry; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.dse.driver.api.core.data.geometry.LineString; -import com.datastax.dse.driver.api.core.data.geometry.Point; -import com.datastax.dse.driver.api.core.data.geometry.Polygon; -import org.junit.Test; - -public class DistanceTest { - - private final Point point = Point.fromCoordinates(1.1, 2.2); - private final Distance distance = new Distance(point, 7.0); - private final String wkt = "DISTANCE((1.1 2.2) 7.0)"; - - @Test - public void should_parse_valid_well_known_text() { - Distance fromWkt = Distance.fromWellKnownText(wkt); - assertThat(fromWkt.getRadius()).isEqualTo(7.0); - assertThat(fromWkt.getCenter()).isEqualTo(point); - assertThat(Distance.fromWellKnownText(wkt)).isEqualTo(distance); - // whitespace doesn't matter between distance and spec. - assertThat(Distance.fromWellKnownText("DISTANCE ((1.1 2.2) 7.0)")).isEqualTo(distance); - // case doesn't matter. - assertThat(Distance.fromWellKnownText("distance((1.1 2.2) 7.0)")).isEqualTo(distance); - } - - @Test(expected = IllegalArgumentException.class) - public void should_fail_to_parse_invalid_well_known_text() { - Distance.fromWellKnownText("dist((1.1 2.2) 3.3)"); - } - - @Test - public void should_convert_to_well_known_text() { - assertThat(distance.asWellKnownText()).isEqualTo(wkt); - } - - @Test - public void should_contain_point() { - assertThat(distance.contains(Point.fromCoordinates(2.0, 3.0))).isTrue(); - } - - @Test - public void should_not_contain_point() { - // y axis falls outside of distance - assertThat(distance.contains(Point.fromCoordinates(2.0, 9.3))).isFalse(); - } - - @Test - public void should_contain_linestring() { - assertThat( - distance.contains( - LineString.fromPoints( - Point.fromCoordinates(2.0, 3.0), - Point.fromCoordinates(3.1, 6.2), - Point.fromCoordinates(-1.0, -2.0)))) - .isTrue(); - } - - @Test - public void should_not_contain_linestring() { - // second point falls outside of distance at y axis. - assertThat( - distance.contains( - LineString.fromPoints( - Point.fromCoordinates(2.0, 3.0), - Point.fromCoordinates(3.1, 9.2), - Point.fromCoordinates(-1.0, -2.0)))) - .isFalse(); - } - - @Test - public void should_contain_polygon() { - Polygon polygon = - Polygon.fromPoints( - Point.fromCoordinates(3, 1), - Point.fromCoordinates(1, 2), - Point.fromCoordinates(2, 4), - Point.fromCoordinates(4, 4)); - assertThat(distance.contains(polygon)).isTrue(); - } - - @Test - public void should_not_contain_polygon() { - Polygon polygon = - Polygon.fromPoints( - Point.fromCoordinates(3, 1), - Point.fromCoordinates(1, 2), - Point.fromCoordinates(2, 4), - Point.fromCoordinates(10, 4)); - // final point falls outside of distance at x axis. - assertThat(distance.contains(polygon)).isFalse(); - } - - @Test(expected = UnsupportedOperationException.class) - public void should_fail_to_convert_to_ogc() { - distance.getOgcGeometry(); - } - - @Test(expected = UnsupportedOperationException.class) - public void should_fail_to_convert_to_wkb() { - distance.asWellKnownBinary(); - } - - @Test(expected = UnsupportedOperationException.class) - public void should_fail_to_convert_to_geo_json() { - distance.asGeoJson(); - } - - @Test - public void should_serialize_and_deserialize() throws Exception { - assertThat(SerializationUtils.serializeAndDeserialize(distance)).isEqualTo(distance); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/data/geometry/SerializationUtils.java b/core/src/test/java/com/datastax/dse/driver/internal/core/data/geometry/SerializationUtils.java deleted file mode 100644 index 84bd1dab343..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/data/geometry/SerializationUtils.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.data.geometry; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.dse.driver.api.core.data.geometry.Geometry; -import com.datastax.oss.protocol.internal.util.Bytes; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; - -public class SerializationUtils { - - public static Object serializeAndDeserialize(Geometry geometry) - throws IOException, ClassNotFoundException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(baos); - - out.writeObject(geometry); - - byte[] bytes = baos.toByteArray(); - if (!(geometry instanceof Distance)) { - byte[] wkb = Bytes.getArray(geometry.asWellKnownBinary()); - assertThat(bytes).containsSequence(wkb); - } - ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes)); - return in.readObject(); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/graph/ContinuousGraphRequestHandlerSpeculativeExecutionTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/graph/ContinuousGraphRequestHandlerSpeculativeExecutionTest.java deleted file mode 100644 index f9ef1ebf6f0..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/graph/ContinuousGraphRequestHandlerSpeculativeExecutionTest.java +++ /dev/null @@ -1,584 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import static com.datastax.dse.driver.internal.core.graph.GraphTestUtils.createGraphBinaryModule; -import static com.datastax.dse.driver.internal.core.graph.GraphTestUtils.defaultDseFrameOf; -import static com.datastax.dse.driver.internal.core.graph.GraphTestUtils.singleGraphRow; -import static com.datastax.oss.driver.Assertions.assertThat; -import static com.datastax.oss.driver.Assertions.assertThatStage; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import com.datastax.dse.driver.DseTestDataProviders; -import com.datastax.dse.driver.api.core.graph.AsyncGraphResultSet; -import com.datastax.dse.driver.api.core.graph.GraphStatement; -import com.datastax.dse.driver.api.core.metrics.DseNodeMetric; -import com.datastax.dse.driver.internal.core.graph.binary.GraphBinaryModule; -import com.datastax.oss.driver.api.core.AllNodesFailedException; -import com.datastax.oss.driver.api.core.NoNodeAvailableException; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.datastax.oss.driver.api.core.metrics.DefaultNodeMetric; -import com.datastax.oss.driver.api.core.metrics.NodeMetric; -import com.datastax.oss.driver.api.core.servererrors.BootstrappingException; -import com.datastax.oss.driver.api.core.specex.SpeculativeExecutionPolicy; -import com.datastax.oss.driver.internal.core.cql.PoolBehavior; -import com.datastax.oss.driver.internal.core.metadata.DefaultNode; -import com.datastax.oss.driver.internal.core.metrics.NodeMetricUpdater; -import com.datastax.oss.driver.internal.core.util.concurrent.CapturingTimer.CapturedTimeout; -import com.datastax.oss.protocol.internal.ProtocolConstants; -import com.datastax.oss.protocol.internal.response.Error; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import java.time.Duration; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.TimeUnit; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -/** - * These tests are almost exact copies of {@link - * com.datastax.oss.driver.internal.core.cql.CqlRequestHandlerSpeculativeExecutionTest}. - */ -@RunWith(DataProviderRunner.class) -public class ContinuousGraphRequestHandlerSpeculativeExecutionTest { - - @Mock DefaultNode node1; - @Mock DefaultNode node2; - @Mock DefaultNode node3; - - @Mock NodeMetricUpdater nodeMetricUpdater1; - @Mock NodeMetricUpdater nodeMetricUpdater2; - @Mock NodeMetricUpdater nodeMetricUpdater3; - - @Mock GraphSupportChecker graphSupportChecker; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - when(node1.getMetricUpdater()).thenReturn(nodeMetricUpdater1); - when(node2.getMetricUpdater()).thenReturn(nodeMetricUpdater2); - when(node3.getMetricUpdater()).thenReturn(nodeMetricUpdater3); - when(nodeMetricUpdater1.isEnabled(any(NodeMetric.class), anyString())).thenReturn(true); - when(nodeMetricUpdater2.isEnabled(any(NodeMetric.class), anyString())).thenReturn(true); - when(nodeMetricUpdater3.isEnabled(any(NodeMetric.class), anyString())).thenReturn(true); - when(graphSupportChecker.inferGraphProtocol(any(), any(), any())) - .thenReturn(GraphProtocol.GRAPH_BINARY_1_0); - } - - @Test - @UseDataProvider(location = DseTestDataProviders.class, value = "nonIdempotentGraphConfig") - public void should_not_schedule_speculative_executions_if_not_idempotent( - boolean defaultIdempotence, GraphStatement statement) { - GraphRequestHandlerTestHarness.Builder harnessBuilder = - GraphRequestHandlerTestHarness.builder().withDefaultIdempotence(defaultIdempotence); - PoolBehavior node1Behavior = harnessBuilder.customBehavior(node1); - - try (GraphRequestHandlerTestHarness harness = harnessBuilder.build()) { - SpeculativeExecutionPolicy speculativeExecutionPolicy = - harness.getContext().getSpeculativeExecutionPolicy(DriverExecutionProfile.DEFAULT_NAME); - - GraphBinaryModule module = createGraphBinaryModule(harness.getContext()); - new ContinuousGraphRequestHandler( - statement, - harness.getSession(), - harness.getContext(), - "test", - module, - graphSupportChecker) - .handle(); - - node1Behavior.verifyWrite(); - node1Behavior.setWriteSuccess(); - - // should not schedule any timeout - assertThat(harness.nextScheduledTimeout()).isNull(); - - verifyNoMoreInteractions(speculativeExecutionPolicy); - verifyNoMoreInteractions(nodeMetricUpdater1); - } - } - - @Test - @UseDataProvider(location = DseTestDataProviders.class, value = "idempotentGraphConfig") - public void should_schedule_speculative_executions( - boolean defaultIdempotence, GraphStatement statement) throws Exception { - GraphRequestHandlerTestHarness.Builder harnessBuilder = - GraphRequestHandlerTestHarness.builder().withDefaultIdempotence(defaultIdempotence); - PoolBehavior node1Behavior = harnessBuilder.customBehavior(node1); - PoolBehavior node2Behavior = harnessBuilder.customBehavior(node2); - PoolBehavior node3Behavior = harnessBuilder.customBehavior(node3); - - try (GraphRequestHandlerTestHarness harness = harnessBuilder.build()) { - SpeculativeExecutionPolicy speculativeExecutionPolicy = - harness.getContext().getSpeculativeExecutionPolicy(DriverExecutionProfile.DEFAULT_NAME); - long firstExecutionDelay = 100L; - long secondExecutionDelay = 200L; - when(speculativeExecutionPolicy.nextExecution( - any(Node.class), eq(null), eq(statement), eq(1))) - .thenReturn(firstExecutionDelay); - when(speculativeExecutionPolicy.nextExecution( - any(Node.class), eq(null), eq(statement), eq(2))) - .thenReturn(secondExecutionDelay); - when(speculativeExecutionPolicy.nextExecution( - any(Node.class), eq(null), eq(statement), eq(3))) - .thenReturn(-1L); - - GraphBinaryModule module = createGraphBinaryModule(harness.getContext()); - new ContinuousGraphRequestHandler( - statement, - harness.getSession(), - harness.getContext(), - "test", - module, - graphSupportChecker) - .handle(); - - node1Behavior.verifyWrite(); - node1Behavior.setWriteSuccess(); - - CapturedTimeout speculativeExecution1 = harness.nextScheduledTimeout(); - assertThat(speculativeExecution1.getDelay(TimeUnit.MILLISECONDS)) - .isEqualTo(firstExecutionDelay); - verifyNoMoreInteractions(nodeMetricUpdater1); - speculativeExecution1.task().run(speculativeExecution1); - verify(nodeMetricUpdater1) - .incrementCounter( - DefaultNodeMetric.SPECULATIVE_EXECUTIONS, DriverExecutionProfile.DEFAULT_NAME); - node2Behavior.verifyWrite(); - node2Behavior.setWriteSuccess(); - - CapturedTimeout speculativeExecution2 = harness.nextScheduledTimeout(); - assertThat(speculativeExecution2.getDelay(TimeUnit.MILLISECONDS)) - .isEqualTo(secondExecutionDelay); - verifyNoMoreInteractions(nodeMetricUpdater2); - speculativeExecution2.task().run(speculativeExecution2); - verify(nodeMetricUpdater2) - .incrementCounter( - DefaultNodeMetric.SPECULATIVE_EXECUTIONS, DriverExecutionProfile.DEFAULT_NAME); - node3Behavior.verifyWrite(); - node3Behavior.setWriteSuccess(); - - // No more scheduled tasks since the policy returns 0 on the third call. - assertThat(harness.nextScheduledTimeout()).isNull(); - - // Note that we don't need to complete any response, the test is just about checking that - // executions are started. - } - } - - @Test - @UseDataProvider(location = DseTestDataProviders.class, value = "idempotentGraphConfig") - public void should_not_start_execution_if_result_complete( - boolean defaultIdempotence, GraphStatement statement) throws Exception { - GraphRequestHandlerTestHarness.Builder harnessBuilder = - GraphRequestHandlerTestHarness.builder() - .withGraphTimeout(Duration.ofSeconds(10)) - .withDefaultIdempotence(defaultIdempotence); - PoolBehavior node1Behavior = harnessBuilder.customBehavior(node1); - PoolBehavior node2Behavior = harnessBuilder.customBehavior(node2); - - try (GraphRequestHandlerTestHarness harness = harnessBuilder.build()) { - SpeculativeExecutionPolicy speculativeExecutionPolicy = - harness.getContext().getSpeculativeExecutionPolicy(DriverExecutionProfile.DEFAULT_NAME); - long firstExecutionDelay = 100L; - when(speculativeExecutionPolicy.nextExecution( - any(Node.class), eq(null), eq(statement), eq(1))) - .thenReturn(firstExecutionDelay); - - GraphBinaryModule module = createGraphBinaryModule(harness.getContext()); - ContinuousGraphRequestHandler requestHandler = - new ContinuousGraphRequestHandler( - statement, - harness.getSession(), - harness.getContext(), - "test", - module, - graphSupportChecker); - CompletionStage resultSetFuture = requestHandler.handle(); - node1Behavior.verifyWrite(); - node1Behavior.setWriteSuccess(); - - // The first timeout scheduled should be the global timeout - CapturedTimeout globalTimeout = harness.nextScheduledTimeout(); - assertThat(globalTimeout.getDelay(TimeUnit.SECONDS)).isEqualTo(10); - - // Check that the first execution was scheduled but don't run it yet - CapturedTimeout speculativeExecution1 = harness.nextScheduledTimeout(); - assertThat(speculativeExecution1.getDelay(TimeUnit.MILLISECONDS)) - .isEqualTo(firstExecutionDelay); - - // Complete the request from the initial execution - node1Behavior.setResponseSuccess( - defaultDseFrameOf(singleGraphRow(GraphProtocol.GRAPH_BINARY_1_0, module))); - assertThatStage(resultSetFuture).isSuccess(); - - // Pending speculative executions should have been cancelled. However we don't check - // firstExecutionTask directly because the request handler's onResponse can sometimes be - // invoked before operationComplete (this is very unlikely in practice, but happens in our - // Travis CI build). When that happens, the speculative execution is not recorded yet when - // cancelScheduledTasks runs. - - // The fact that we missed the speculative execution is not a problem; even if it starts, it - // will eventually find out that the result is already complete and cancel itself: - speculativeExecution1.task().run(speculativeExecution1); - node2Behavior.verifyNoWrite(); - - verify(nodeMetricUpdater1) - .updateTimer( - eq(DseNodeMetric.GRAPH_MESSAGES), - eq(DriverExecutionProfile.DEFAULT_NAME), - anyLong(), - eq(TimeUnit.NANOSECONDS)); - verifyNoMoreInteractions(nodeMetricUpdater1); - } - } - - @Test - @UseDataProvider(location = DseTestDataProviders.class, value = "idempotentGraphConfig") - public void should_cancel_pre_acquired_id_if_result_completes_after_channel_acquired( - boolean defaultIdempotence, GraphStatement statement) throws Exception { - GraphRequestHandlerTestHarness.Builder harnessBuilder = - GraphRequestHandlerTestHarness.builder().withDefaultIdempotence(defaultIdempotence); - PoolBehavior node1Behavior = harnessBuilder.customBehavior(node1); - PoolBehavior node2Behavior = harnessBuilder.customBehavior(node2); - - try (GraphRequestHandlerTestHarness harness = harnessBuilder.build()) { - SpeculativeExecutionPolicy speculativeExecutionPolicy = - harness.getContext().getSpeculativeExecutionPolicy(DriverExecutionProfile.DEFAULT_NAME); - long firstExecutionDelay = 100L; - when(speculativeExecutionPolicy.nextExecution( - any(Node.class), eq(null), eq(statement), eq(1))) - .thenReturn(firstExecutionDelay); - - GraphBinaryModule module = createGraphBinaryModule(harness.getContext()); - CompletionStage resultSetFuture = - new ContinuousGraphRequestHandler( - statement, - harness.getSession(), - harness.getContext(), - "test", - module, - graphSupportChecker) - .handle(); - node1Behavior.verifyWrite(); - node1Behavior.setWriteSuccess(); - - CapturedTimeout speculativeExecution = harness.nextScheduledTimeout(); - assertThat(speculativeExecution.getDelay(TimeUnit.MILLISECONDS)) - .isEqualTo(firstExecutionDelay); - - // Simulate the initial execution winning after the speculative execution reserves an ID, - // but before it submits its write. - doAnswer( - invocation -> { - node1Behavior.setResponseSuccess( - defaultDseFrameOf(singleGraphRow(GraphProtocol.GRAPH_BINARY_1_0, module))); - return node2Behavior.getChannel(); - }) - .when(harness.getSession()) - .getChannel(eq(node2), anyString()); - - speculativeExecution.task().run(speculativeExecution); - - assertThatStage(resultSetFuture).isSuccess(); - node2Behavior.verifyNoWrite(); - node2Behavior.verifyPreAcquireCancelled(); - } - } - - @Test - @UseDataProvider(location = DseTestDataProviders.class, value = "idempotentGraphConfig") - public void should_fail_if_no_nodes(boolean defaultIdempotence, GraphStatement statement) { - GraphRequestHandlerTestHarness.Builder harnessBuilder = - GraphRequestHandlerTestHarness.builder().withDefaultIdempotence(defaultIdempotence); - // No configured behaviors => will yield an empty query plan - - try (GraphRequestHandlerTestHarness harness = harnessBuilder.build()) { - SpeculativeExecutionPolicy speculativeExecutionPolicy = - harness.getContext().getSpeculativeExecutionPolicy(DriverExecutionProfile.DEFAULT_NAME); - long firstExecutionDelay = 100L; - when(speculativeExecutionPolicy.nextExecution( - any(Node.class), eq(null), eq(statement), eq(1))) - .thenReturn(firstExecutionDelay); - - GraphBinaryModule module = createGraphBinaryModule(harness.getContext()); - CompletionStage resultSetFuture = - new ContinuousGraphRequestHandler( - statement, - harness.getSession(), - harness.getContext(), - "test", - module, - graphSupportChecker) - .handle(); - - assertThatStage(resultSetFuture) - .isFailed(error -> assertThat(error).isInstanceOf(NoNodeAvailableException.class)); - } - } - - @Test - @UseDataProvider(location = DseTestDataProviders.class, value = "idempotentGraphConfig") - public void should_fail_if_no_more_nodes_and_initial_execution_is_last( - boolean defaultIdempotence, GraphStatement statement) throws Exception { - GraphRequestHandlerTestHarness.Builder harnessBuilder = - GraphRequestHandlerTestHarness.builder().withDefaultIdempotence(defaultIdempotence); - PoolBehavior node1Behavior = harnessBuilder.customBehavior(node1); - harnessBuilder.withResponse( - node2, - defaultDseFrameOf(new Error(ProtocolConstants.ErrorCode.IS_BOOTSTRAPPING, "mock message"))); - - try (GraphRequestHandlerTestHarness harness = harnessBuilder.build()) { - SpeculativeExecutionPolicy speculativeExecutionPolicy = - harness.getContext().getSpeculativeExecutionPolicy(DriverExecutionProfile.DEFAULT_NAME); - long firstExecutionDelay = 100L; - when(speculativeExecutionPolicy.nextExecution( - any(Node.class), eq(null), eq(statement), eq(1))) - .thenReturn(firstExecutionDelay); - - GraphBinaryModule module = createGraphBinaryModule(harness.getContext()); - CompletionStage resultSetFuture = - new ContinuousGraphRequestHandler( - statement, - harness.getSession(), - harness.getContext(), - "test", - module, - graphSupportChecker) - .handle(); - node1Behavior.verifyWrite(); - node1Behavior.setWriteSuccess(); - // do not simulate a response from node1 yet - - // Run the next scheduled task to start the speculative execution. node2 will reply with a - // BOOTSTRAPPING error, causing a RETRY_NEXT; but the query plan is now empty so the - // speculative execution stops. - // next scheduled timeout should be the first speculative execution. Get it and run it. - CapturedTimeout speculativeExecution1 = harness.nextScheduledTimeout(); - assertThat(speculativeExecution1.getDelay(TimeUnit.MILLISECONDS)) - .isEqualTo(firstExecutionDelay); - speculativeExecution1.task().run(speculativeExecution1); - - // node1 now replies with the same response, that triggers a RETRY_NEXT - node1Behavior.setResponseSuccess( - defaultDseFrameOf( - new Error(ProtocolConstants.ErrorCode.IS_BOOTSTRAPPING, "mock message"))); - - // But again the query plan is empty so that should fail the request - assertThatStage(resultSetFuture) - .isFailed( - error -> { - assertThat(error).isInstanceOf(AllNodesFailedException.class); - Map> nodeErrors = - ((AllNodesFailedException) error).getAllErrors(); - assertThat(nodeErrors).containsOnlyKeys(node1, node2); - assertThat(nodeErrors.get(node1).get(0)).isInstanceOf(BootstrappingException.class); - assertThat(nodeErrors.get(node2).get(0)).isInstanceOf(BootstrappingException.class); - }); - } - } - - @Test - @UseDataProvider(location = DseTestDataProviders.class, value = "idempotentGraphConfig") - public void should_fail_if_no_more_nodes_and_speculative_execution_is_last( - boolean defaultIdempotence, GraphStatement statement) throws Exception { - GraphRequestHandlerTestHarness.Builder harnessBuilder = - GraphRequestHandlerTestHarness.builder().withDefaultIdempotence(defaultIdempotence); - PoolBehavior node1Behavior = harnessBuilder.customBehavior(node1); - PoolBehavior node2Behavior = harnessBuilder.customBehavior(node2); - - try (GraphRequestHandlerTestHarness harness = harnessBuilder.build()) { - SpeculativeExecutionPolicy speculativeExecutionPolicy = - harness.getContext().getSpeculativeExecutionPolicy(DriverExecutionProfile.DEFAULT_NAME); - long firstExecutionDelay = 100L; - when(speculativeExecutionPolicy.nextExecution( - any(Node.class), eq(null), eq(statement), eq(1))) - .thenReturn(firstExecutionDelay); - - GraphBinaryModule module = createGraphBinaryModule(harness.getContext()); - CompletionStage resultSetFuture = - new ContinuousGraphRequestHandler( - statement, - harness.getSession(), - harness.getContext(), - "test", - module, - graphSupportChecker) - .handle(); - node1Behavior.verifyWrite(); - node1Behavior.setWriteSuccess(); - // do not simulate a response from node1 yet - - // next scheduled timeout should be the first speculative execution. Get it and run it. - CapturedTimeout speculativeExecution1 = harness.nextScheduledTimeout(); - assertThat(speculativeExecution1.getDelay(TimeUnit.MILLISECONDS)) - .isEqualTo(firstExecutionDelay); - speculativeExecution1.task().run(speculativeExecution1); - - // node1 now replies with a BOOTSTRAPPING error that triggers a RETRY_NEXT - // but the query plan is empty so the initial execution stops - node1Behavior.setResponseSuccess( - defaultDseFrameOf( - new Error(ProtocolConstants.ErrorCode.IS_BOOTSTRAPPING, "mock message"))); - - // Same thing with node2, so the speculative execution should reach the end of the query plan - // and fail the request - node2Behavior.setResponseSuccess( - defaultDseFrameOf( - new Error(ProtocolConstants.ErrorCode.IS_BOOTSTRAPPING, "mock message"))); - - assertThatStage(resultSetFuture) - .isFailed( - error -> { - assertThat(error).isInstanceOf(AllNodesFailedException.class); - Map> nodeErrors = - ((AllNodesFailedException) error).getAllErrors(); - assertThat(nodeErrors).containsOnlyKeys(node1, node2); - assertThat(nodeErrors.get(node1).get(0)).isInstanceOf(BootstrappingException.class); - assertThat(nodeErrors.get(node2).get(0)).isInstanceOf(BootstrappingException.class); - }); - } - } - - @Test - @UseDataProvider(location = DseTestDataProviders.class, value = "idempotentGraphConfig") - public void should_retry_in_speculative_executions( - boolean defaultIdempotence, GraphStatement statement) throws Exception { - GraphRequestHandlerTestHarness.Builder harnessBuilder = - GraphRequestHandlerTestHarness.builder().withDefaultIdempotence(defaultIdempotence); - PoolBehavior node1Behavior = harnessBuilder.customBehavior(node1); - PoolBehavior node2Behavior = harnessBuilder.customBehavior(node2); - PoolBehavior node3Behavior = harnessBuilder.customBehavior(node3); - - try (GraphRequestHandlerTestHarness harness = harnessBuilder.build()) { - SpeculativeExecutionPolicy speculativeExecutionPolicy = - harness.getContext().getSpeculativeExecutionPolicy(DriverExecutionProfile.DEFAULT_NAME); - long firstExecutionDelay = 100L; - when(speculativeExecutionPolicy.nextExecution( - any(Node.class), eq(null), eq(statement), eq(1))) - .thenReturn(firstExecutionDelay); - - GraphBinaryModule module = createGraphBinaryModule(harness.getContext()); - CompletionStage resultSetFuture = - new ContinuousGraphRequestHandler( - statement, - harness.getSession(), - harness.getContext(), - "test", - module, - graphSupportChecker) - .handle(); - node1Behavior.verifyWrite(); - node1Behavior.setWriteSuccess(); - // do not simulate a response from node1. The request will stay hanging for the rest of this - // test - - // next scheduled timeout should be the first speculative execution. Get it and run it. - CapturedTimeout speculativeExecution1 = harness.nextScheduledTimeout(); - assertThat(speculativeExecution1.getDelay(TimeUnit.MILLISECONDS)) - .isEqualTo(firstExecutionDelay); - speculativeExecution1.task().run(speculativeExecution1); - - node2Behavior.verifyWrite(); - node2Behavior.setWriteSuccess(); - - // node2 replies with a response that triggers a RETRY_NEXT - node2Behavior.setResponseSuccess( - defaultDseFrameOf( - new Error(ProtocolConstants.ErrorCode.IS_BOOTSTRAPPING, "mock message"))); - - node3Behavior.setResponseSuccess( - defaultDseFrameOf(singleGraphRow(GraphProtocol.GRAPH_BINARY_1_0, module))); - - // The second execution should move to node3 and complete the request - assertThatStage(resultSetFuture).isSuccess(); - - // The request to node1 was still in flight, it should have been cancelled - node1Behavior.verifyCancellation(); - } - } - - @Test - @UseDataProvider(location = DseTestDataProviders.class, value = "idempotentGraphConfig") - public void should_stop_retrying_other_executions_if_result_complete( - boolean defaultIdempotence, GraphStatement statement) throws Exception { - GraphRequestHandlerTestHarness.Builder harnessBuilder = - GraphRequestHandlerTestHarness.builder().withDefaultIdempotence(defaultIdempotence); - PoolBehavior node1Behavior = harnessBuilder.customBehavior(node1); - PoolBehavior node2Behavior = harnessBuilder.customBehavior(node2); - PoolBehavior node3Behavior = harnessBuilder.customBehavior(node3); - - try (GraphRequestHandlerTestHarness harness = harnessBuilder.build()) { - SpeculativeExecutionPolicy speculativeExecutionPolicy = - harness.getContext().getSpeculativeExecutionPolicy(DriverExecutionProfile.DEFAULT_NAME); - long firstExecutionDelay = 100L; - when(speculativeExecutionPolicy.nextExecution( - any(Node.class), eq(null), eq(statement), eq(1))) - .thenReturn(firstExecutionDelay); - - GraphBinaryModule module = createGraphBinaryModule(harness.getContext()); - CompletionStage resultSetFuture = - new ContinuousGraphRequestHandler( - statement, - harness.getSession(), - harness.getContext(), - "test", - module, - graphSupportChecker) - .handle(); - node1Behavior.verifyWrite(); - node1Behavior.setWriteSuccess(); - - // next scheduled timeout should be the first speculative execution. Get it and run it. - CapturedTimeout speculativeExecution1 = harness.nextScheduledTimeout(); - assertThat(speculativeExecution1.getDelay(TimeUnit.MILLISECONDS)) - .isEqualTo(firstExecutionDelay); - speculativeExecution1.task().run(speculativeExecution1); - - node2Behavior.verifyWrite(); - node2Behavior.setWriteSuccess(); - - // Complete the request from the initial execution - node1Behavior.setResponseSuccess( - defaultDseFrameOf(singleGraphRow(GraphProtocol.GRAPH_BINARY_1_0, module))); - assertThatStage(resultSetFuture).isSuccess(); - - // node2 replies with a response that would trigger a RETRY_NEXT if the request was still - // running - node2Behavior.setResponseSuccess( - defaultDseFrameOf( - new Error(ProtocolConstants.ErrorCode.IS_BOOTSTRAPPING, "mock message"))); - - // The speculative execution should not move to node3 because it is stopped - node3Behavior.verifyNoWrite(); - } - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/graph/ContinuousGraphRequestHandlerTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/graph/ContinuousGraphRequestHandlerTest.java deleted file mode 100644 index b374539f12e..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/graph/ContinuousGraphRequestHandlerTest.java +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import static com.datastax.dse.driver.internal.core.graph.GraphTestUtils.createGraphBinaryModule; -import static com.datastax.dse.driver.internal.core.graph.GraphTestUtils.defaultDseFrameOf; -import static com.datastax.dse.driver.internal.core.graph.GraphTestUtils.tenGraphRows; -import static com.datastax.oss.driver.Assertions.assertThat; -import static com.datastax.oss.driver.Assertions.assertThatStage; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import com.datastax.dse.driver.DseTestDataProviders; -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.dse.driver.api.core.graph.AsyncGraphResultSet; -import com.datastax.dse.driver.api.core.graph.GraphNode; -import com.datastax.dse.driver.api.core.graph.GraphStatement; -import com.datastax.dse.driver.api.core.graph.ScriptGraphStatement; -import com.datastax.dse.driver.api.core.metrics.DseNodeMetric; -import com.datastax.dse.driver.api.core.metrics.DseSessionMetric; -import com.datastax.dse.driver.internal.core.graph.binary.GraphBinaryModule; -import com.datastax.oss.driver.api.core.DriverTimeoutException; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import com.datastax.oss.driver.internal.core.context.DefaultDriverContext; -import com.datastax.oss.driver.internal.core.cql.PoolBehavior; -import com.datastax.oss.driver.internal.core.cql.RequestHandlerTestHarness; -import com.datastax.oss.driver.internal.core.metadata.DefaultNode; -import com.datastax.oss.driver.internal.core.metrics.NodeMetricUpdater; -import com.datastax.oss.driver.internal.core.util.concurrent.CapturingTimer.CapturedTimeout; -import com.datastax.oss.driver.internal.core.util.concurrent.CompletableFutures; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import java.io.IOException; -import java.time.Duration; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.TimeUnit; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -@RunWith(DataProviderRunner.class) -public class ContinuousGraphRequestHandlerTest { - - @Mock DefaultDriverContext mockContext; - @Mock DefaultNode node; - @Mock NodeMetricUpdater nodeMetricUpdater1; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - when(node.getMetricUpdater()).thenReturn(nodeMetricUpdater1); - } - - @Test - @UseDataProvider(location = DseTestDataProviders.class, value = "supportedGraphProtocols") - public void should_return_paged_results(GraphProtocol graphProtocol) throws IOException { - String profileName = "test-graph"; - when(nodeMetricUpdater1.isEnabled(DseNodeMetric.GRAPH_MESSAGES, profileName)).thenReturn(true); - - GraphBinaryModule module = createGraphBinaryModule(mockContext); - - GraphRequestHandlerTestHarness.Builder builder = - GraphRequestHandlerTestHarness.builder().withGraphProtocolForTestConfig(graphProtocol); - PoolBehavior node1Behavior = builder.customBehavior(node); - - try (RequestHandlerTestHarness harness = builder.build()) { - - GraphStatement graphStatement = - ScriptGraphStatement.newInstance("mockQuery").setExecutionProfileName(profileName); - - ContinuousGraphRequestHandler handler = - new ContinuousGraphRequestHandler( - graphStatement, - harness.getSession(), - harness.getContext(), - "test", - module, - new GraphSupportChecker()); - - // send the initial request - CompletionStage page1Future = handler.handle(); - - node1Behavior.setResponseSuccess( - defaultDseFrameOf(tenGraphRows(graphProtocol, module, 1, false))); - - assertThatStage(page1Future) - .isSuccess( - page1 -> { - assertThat(page1.hasMorePages()).isTrue(); - assertThat(page1.currentPage()).hasSize(10).allMatch(GraphNode::isVertex); - ExecutionInfo executionInfo = page1.getRequestExecutionInfo(); - assertThat(executionInfo.getCoordinator()).isEqualTo(node); - assertThat(executionInfo.getErrors()).isEmpty(); - assertThat(executionInfo.getIncomingPayload()).isEmpty(); - assertThat(executionInfo.getSpeculativeExecutionCount()).isEqualTo(0); - assertThat(executionInfo.getSuccessfulExecutionIndex()).isEqualTo(0); - assertThat(executionInfo.getWarnings()).isEmpty(); - }); - - AsyncGraphResultSet page1 = CompletableFutures.getCompleted(page1Future); - CompletionStage page2Future = page1.fetchNextPage(); - - node1Behavior.setResponseSuccess( - defaultDseFrameOf(tenGraphRows(graphProtocol, module, 2, true))); - - assertThatStage(page2Future) - .isSuccess( - page2 -> { - assertThat(page2.hasMorePages()).isFalse(); - assertThat(page2.currentPage()).hasSize(10).allMatch(GraphNode::isVertex); - ExecutionInfo executionInfo = page2.getRequestExecutionInfo(); - assertThat(executionInfo.getCoordinator()).isEqualTo(node); - assertThat(executionInfo.getErrors()).isEmpty(); - assertThat(executionInfo.getIncomingPayload()).isEmpty(); - assertThat(executionInfo.getSpeculativeExecutionCount()).isEqualTo(0); - assertThat(executionInfo.getSuccessfulExecutionIndex()).isEqualTo(0); - assertThat(executionInfo.getWarnings()).isEmpty(); - }); - - validateMetrics(profileName, harness); - } - } - - @Test - public void should_honor_default_timeout() throws Exception { - // given - GraphBinaryModule binaryModule = createGraphBinaryModule(mockContext); - Duration defaultTimeout = Duration.ofSeconds(1); - - RequestHandlerTestHarness.Builder builder = - GraphRequestHandlerTestHarness.builder().withGraphTimeout(defaultTimeout); - PoolBehavior node1Behavior = builder.customBehavior(node); - - try (RequestHandlerTestHarness harness = builder.build()) { - - DriverExecutionProfile profile = harness.getContext().getConfig().getDefaultProfile(); - when(profile.isDefined(DseDriverOption.GRAPH_SUB_PROTOCOL)).thenReturn(true); - when(profile.getString(DseDriverOption.GRAPH_SUB_PROTOCOL)) - .thenReturn(GraphProtocol.GRAPH_BINARY_1_0.toInternalCode()); - - GraphStatement graphStatement = ScriptGraphStatement.newInstance("mockQuery"); - - // when - ContinuousGraphRequestHandler handler = - new ContinuousGraphRequestHandler( - graphStatement, - harness.getSession(), - harness.getContext(), - "test", - binaryModule, - new GraphSupportChecker()); - - // send the initial request - CompletionStage page1Future = handler.handle(); - - // acknowledge the write, will set the global timeout - node1Behavior.verifyWrite(); - node1Behavior.setWriteSuccess(); - - CapturedTimeout globalTimeout = harness.nextScheduledTimeout(); - assertThat(globalTimeout.getDelay(TimeUnit.NANOSECONDS)).isEqualTo(defaultTimeout.toNanos()); - - // will trigger the global timeout and complete it exceptionally - globalTimeout.task().run(globalTimeout); - assertThat(page1Future.toCompletableFuture()).isCompletedExceptionally(); - - assertThatThrownBy(() -> page1Future.toCompletableFuture().get()) - .hasRootCauseExactlyInstanceOf(DriverTimeoutException.class) - .hasMessageContaining("Query timed out after " + defaultTimeout); - } - } - - @Test - public void should_honor_statement_timeout() throws Exception { - // given - GraphBinaryModule binaryModule = createGraphBinaryModule(mockContext); - Duration defaultTimeout = Duration.ofSeconds(1); - Duration statementTimeout = Duration.ofSeconds(2); - - RequestHandlerTestHarness.Builder builder = - GraphRequestHandlerTestHarness.builder().withGraphTimeout(defaultTimeout); - PoolBehavior node1Behavior = builder.customBehavior(node); - - try (RequestHandlerTestHarness harness = builder.build()) { - - DriverExecutionProfile profile = harness.getContext().getConfig().getDefaultProfile(); - when(profile.isDefined(DseDriverOption.GRAPH_SUB_PROTOCOL)).thenReturn(true); - when(profile.getString(DseDriverOption.GRAPH_SUB_PROTOCOL)) - .thenReturn(GraphProtocol.GRAPH_BINARY_1_0.toInternalCode()); - - GraphStatement graphStatement = - ScriptGraphStatement.newInstance("mockQuery").setTimeout(statementTimeout); - - // when - ContinuousGraphRequestHandler handler = - new ContinuousGraphRequestHandler( - graphStatement, - harness.getSession(), - harness.getContext(), - "test", - binaryModule, - new GraphSupportChecker()); - - // send the initial request - CompletionStage page1Future = handler.handle(); - - // acknowledge the write, will set the global timeout - node1Behavior.verifyWrite(); - node1Behavior.setWriteSuccess(); - - CapturedTimeout globalTimeout = harness.nextScheduledTimeout(); - assertThat(globalTimeout.getDelay(TimeUnit.NANOSECONDS)) - .isEqualTo(statementTimeout.toNanos()); - - // will trigger the global timeout and complete it exceptionally - globalTimeout.task().run(globalTimeout); - assertThat(page1Future.toCompletableFuture()).isCompletedExceptionally(); - - assertThatThrownBy(() -> page1Future.toCompletableFuture().get()) - .hasRootCauseExactlyInstanceOf(DriverTimeoutException.class) - .hasMessageContaining("Query timed out after " + statementTimeout); - } - } - - private void validateMetrics(String profileName, RequestHandlerTestHarness harness) { - // GRAPH_MESSAGES metrics update is invoked only for the first page - verify(nodeMetricUpdater1, times(1)) - .updateTimer( - eq(DseNodeMetric.GRAPH_MESSAGES), eq(profileName), anyLong(), eq(TimeUnit.NANOSECONDS)); - verifyNoMoreInteractions(nodeMetricUpdater1); - - verify(harness.getSession().getMetricUpdater()) - .updateTimer( - eq(DseSessionMetric.GRAPH_REQUESTS), eq(null), anyLong(), eq(TimeUnit.NANOSECONDS)); - verifyNoMoreInteractions(harness.getSession().getMetricUpdater()); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/graph/GraphExecutionInfoConverterTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/graph/GraphExecutionInfoConverterTest.java deleted file mode 100644 index 1814b12aa4e..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/graph/GraphExecutionInfoConverterTest.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import com.datastax.dse.driver.api.core.graph.GraphStatement; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.datastax.oss.driver.api.core.servererrors.ServerError; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import com.datastax.oss.protocol.internal.util.Bytes; -import java.nio.ByteBuffer; -import java.util.AbstractMap.SimpleEntry; -import java.util.Collections; -import java.util.List; -import java.util.Map.Entry; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; - -@RunWith(MockitoJUnitRunner.Strict.class) -@SuppressWarnings("deprecation") -public class GraphExecutionInfoConverterTest { - - @Mock GraphStatement request; - @Mock Node node; - - private List> errors; - private List warnings; - private ImmutableMap payload; - - @Before - public void setUp() { - errors = - Collections.singletonList( - new SimpleEntry<>(node, new ServerError(node, "this is a server error"))); - warnings = Collections.singletonList("this is a warning"); - payload = ImmutableMap.of("key", Bytes.fromHexString("0xcafebabe")); - } - - @Test - public void should_convert_to_graph_execution_info() { - - // given - ExecutionInfo executionInfo = mock(ExecutionInfo.class); - when(executionInfo.getRequest()).thenReturn(request); - when(executionInfo.getCoordinator()).thenReturn(node); - when(executionInfo.getSpeculativeExecutionCount()).thenReturn(42); - when(executionInfo.getSuccessfulExecutionIndex()).thenReturn(10); - when(executionInfo.getErrors()).thenReturn(errors); - when(executionInfo.getWarnings()).thenReturn(warnings); - when(executionInfo.getIncomingPayload()).thenReturn(payload); - - // when - com.datastax.dse.driver.api.core.graph.GraphExecutionInfo graphExecutionInfo = - GraphExecutionInfoConverter.convert(executionInfo); - - // then - assertThat(graphExecutionInfo.getStatement()).isSameAs(request); - assertThat(graphExecutionInfo.getCoordinator()).isSameAs(node); - assertThat(graphExecutionInfo.getSpeculativeExecutionCount()).isEqualTo(42); - assertThat(graphExecutionInfo.getSuccessfulExecutionIndex()).isEqualTo(10); - assertThat(graphExecutionInfo.getErrors()).isEqualTo(errors); - assertThat(graphExecutionInfo.getWarnings()).isEqualTo(warnings); - assertThat(graphExecutionInfo.getIncomingPayload()).isEqualTo(payload); - } - - @Test - public void should_convert_from_graph_execution_info() { - - // given - com.datastax.dse.driver.api.core.graph.GraphExecutionInfo graphExecutionInfo = - mock(com.datastax.dse.driver.api.core.graph.GraphExecutionInfo.class); - when(graphExecutionInfo.getStatement()).thenAnswer(args -> request); - when(graphExecutionInfo.getCoordinator()).thenReturn(node); - when(graphExecutionInfo.getSpeculativeExecutionCount()).thenReturn(42); - when(graphExecutionInfo.getSuccessfulExecutionIndex()).thenReturn(10); - when(graphExecutionInfo.getErrors()).thenReturn(errors); - when(graphExecutionInfo.getWarnings()).thenReturn(warnings); - when(graphExecutionInfo.getIncomingPayload()).thenReturn(payload); - - // when - ExecutionInfo executionInfo = GraphExecutionInfoConverter.convert(graphExecutionInfo); - - // then - assertThat(executionInfo.getRequest()).isSameAs(request); - assertThatThrownBy(executionInfo::getStatement).isInstanceOf(ClassCastException.class); - assertThat(executionInfo.getCoordinator()).isSameAs(node); - assertThat(executionInfo.getSpeculativeExecutionCount()).isEqualTo(42); - assertThat(executionInfo.getSuccessfulExecutionIndex()).isEqualTo(10); - assertThat(executionInfo.getErrors()).isEqualTo(errors); - assertThat(executionInfo.getWarnings()).isEqualTo(warnings); - assertThat(executionInfo.getIncomingPayload()).isEqualTo(payload); - assertThat(executionInfo.getPagingState()).isNull(); - assertThat(executionInfo.isSchemaInAgreement()).isTrue(); - assertThat(executionInfo.getQueryTraceAsync()).isCompletedExceptionally(); - assertThatThrownBy(executionInfo::getQueryTrace) - .isInstanceOf(IllegalStateException.class) - .hasMessage("Tracing was disabled for this request"); - assertThat(executionInfo.getResponseSizeInBytes()).isEqualTo(-1L); - assertThat(executionInfo.getCompressedResponseSizeInBytes()).isEqualTo(-1L); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/graph/GraphNodeTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/graph/GraphNodeTest.java deleted file mode 100644 index d7ded441e70..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/graph/GraphNodeTest.java +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import static com.datastax.dse.driver.internal.core.graph.GraphProtocol.GRAPHSON_1_0; -import static com.datastax.dse.driver.internal.core.graph.GraphProtocol.GRAPHSON_2_0; -import static com.datastax.dse.driver.internal.core.graph.GraphProtocol.GRAPH_BINARY_1_0; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import com.datastax.dse.driver.api.core.DseProtocolVersion; -import com.datastax.dse.driver.api.core.graph.GraphNode; -import com.datastax.dse.driver.internal.core.graph.binary.GraphBinaryModule; -import com.datastax.oss.driver.api.core.type.codec.registry.CodecRegistry; -import com.datastax.oss.driver.internal.core.context.DefaultDriverContext; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableSet; -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import org.apache.tinkerpop.gremlin.process.remote.traversal.DefaultRemoteTraverser; -import org.apache.tinkerpop.gremlin.process.traversal.Traverser; -import org.apache.tinkerpop.gremlin.process.traversal.step.util.EmptyPath; -import org.apache.tinkerpop.gremlin.structure.io.Buffer; -import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryReader; -import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryWriter; -import org.apache.tinkerpop.gremlin.structure.io.binary.TypeSerializerRegistry; -import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedEdge; -import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedProperty; -import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertex; -import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertexProperty; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(DataProviderRunner.class) -public class GraphNodeTest { - - private GraphBinaryModule graphBinaryModule; - - @Before - public void setup() { - DefaultDriverContext dseDriverContext = mock(DefaultDriverContext.class); - when(dseDriverContext.getCodecRegistry()).thenReturn(CodecRegistry.DEFAULT); - when(dseDriverContext.getProtocolVersion()).thenReturn(DseProtocolVersion.DSE_V2); - - TypeSerializerRegistry registry = - GraphBinaryModule.createDseTypeSerializerRegistry(dseDriverContext); - graphBinaryModule = - new GraphBinaryModule(new GraphBinaryReader(registry), new GraphBinaryWriter(registry)); - } - - @Test - public void should_not_support_set_for_graphson_2_0() throws IOException { - // when - GraphNode graphNode = serdeAndCreateGraphNode(ImmutableSet.of("value"), GRAPHSON_2_0); - - // then - assertThat(graphNode.isSet()).isFalse(); - } - - @Test - public void should_throw_for_set_for_graphson_1_0() throws IOException { - // when - GraphNode graphNode = serdeAndCreateGraphNode(ImmutableSet.of("value"), GRAPHSON_1_0); - - // then - assertThat(graphNode.isSet()).isFalse(); - assertThatThrownBy(graphNode::asSet).isExactlyInstanceOf(UnsupportedOperationException.class); - } - - @Test - @UseDataProvider(value = "allGraphProtocols") - public void should_create_graph_node_for_list(GraphProtocol graphVersion) throws IOException { - // when - GraphNode graphNode = serdeAndCreateGraphNode(ImmutableList.of("value"), graphVersion); - - // then - assertThat(graphNode.isList()).isTrue(); - List result = graphNode.asList(); - assertThat(result).isEqualTo(ImmutableList.of("value")); - } - - @Test - @UseDataProvider("allGraphProtocols") - public void should_create_graph_node_for_map(GraphProtocol graphProtocol) throws IOException { - // when - GraphNode graphNode = serdeAndCreateGraphNode(ImmutableMap.of("value", 1234), graphProtocol); - - // then - assertThat(graphNode.isMap()).isTrue(); - Map result = graphNode.asMap(); - assertThat(result).isEqualTo(ImmutableMap.of("value", 1234)); - } - - @Test - @UseDataProvider("graphson1_0and2_0") - public void should_create_graph_node_for_map_for_non_string_key(GraphProtocol graphProtocol) - throws IOException { - // when - GraphNode graphNode = serdeAndCreateGraphNode(ImmutableMap.of(12, 1234), graphProtocol); - - // then - assertThat(graphNode.isMap()).isTrue(); - Map result = graphNode.asMap(); - assertThat(result).isEqualTo(ImmutableMap.of("12", 1234)); - } - - @Test - @UseDataProvider(value = "allGraphProtocols") - public void should_calculate_size_of_collection_types(GraphProtocol graphProtocol) - throws IOException { - // when - GraphNode mapNode = serdeAndCreateGraphNode(ImmutableMap.of(12, 1234), graphProtocol); - GraphNode setNode = serdeAndCreateGraphNode(ImmutableSet.of(12, 1234), graphProtocol); - GraphNode listNode = serdeAndCreateGraphNode(ImmutableList.of(12, 1234, 99999), graphProtocol); - - // then - assertThat(mapNode.size()).isEqualTo(1); - assertThat(setNode.size()).isEqualTo(2); - assertThat(listNode.size()).isEqualTo(3); - } - - @Test - @UseDataProvider(value = "allGraphProtocols") - public void should_return_is_value_only_for_scalar_value(GraphProtocol graphProtocol) - throws IOException { - // when - GraphNode mapNode = serdeAndCreateGraphNode(ImmutableMap.of(12, 1234), graphProtocol); - GraphNode setNode = serdeAndCreateGraphNode(ImmutableMap.of(12, 1234), graphProtocol); - GraphNode listNode = serdeAndCreateGraphNode(ImmutableMap.of(12, 1234), graphProtocol); - GraphNode vertexNode = - serdeAndCreateGraphNode(new DetachedVertex("a", "l", null), graphProtocol); - GraphNode edgeNode = - serdeAndCreateGraphNode( - new DetachedEdge("a", "l", Collections.emptyMap(), "v1", "l1", "v2", "l2"), - graphProtocol); - GraphNode pathNode = serdeAndCreateGraphNode(EmptyPath.instance(), graphProtocol); - GraphNode propertyNode = serdeAndCreateGraphNode(new DetachedProperty<>("a", 1), graphProtocol); - GraphNode vertexPropertyNode = - serdeAndCreateGraphNode( - new DetachedVertexProperty<>("id", "l", "v", null, new DetachedVertex("a", "l", null)), - graphProtocol); - GraphNode scalarValueNode = serdeAndCreateGraphNode(true, graphProtocol); - - // then - assertThat(mapNode.isValue()).isFalse(); - assertThat(setNode.isValue()).isFalse(); - assertThat(listNode.isValue()).isFalse(); - assertThat(vertexNode.isValue()).isFalse(); - assertThat(edgeNode.isValue()).isFalse(); - assertThat(pathNode.isValue()).isFalse(); - assertThat(propertyNode.isValue()).isFalse(); - assertThat(vertexPropertyNode.isValue()).isFalse(); - assertThat(scalarValueNode.isValue()).isTrue(); - } - - @Test - @UseDataProvider("objectGraphNodeProtocols") - public void should_check_if_node_is_property_not_map(GraphProtocol graphProtocol) - throws IOException { - // when - GraphNode propertyNode = serdeAndCreateGraphNode(new DetachedProperty<>("a", 1), graphProtocol); - - // then - assertThat(propertyNode.isProperty()).isTrue(); - assertThat(propertyNode.isMap()).isFalse(); - assertThat(propertyNode.asProperty()).isNotNull(); - } - - @Test - public void should_check_if_node_is_property_or_map_for_1_0() throws IOException { - // when - GraphNode propertyNode = serdeAndCreateGraphNode(new DetachedProperty<>("a", 1), GRAPHSON_1_0); - - // then - assertThat(propertyNode.isProperty()).isTrue(); - assertThat(propertyNode.isMap()).isTrue(); - assertThat(propertyNode.asProperty()).isNotNull(); - } - - @Test - @UseDataProvider("allGraphProtocols") - public void should_check_if_node_is_vertex_property(GraphProtocol graphProtocol) - throws IOException { - // when - GraphNode vertexPropertyNode = - serdeAndCreateGraphNode( - new DetachedVertexProperty<>("id", "l", "v", null, new DetachedVertex("a", "l", null)), - graphProtocol); - - // then - assertThat(vertexPropertyNode.isVertexProperty()).isTrue(); - assertThat(vertexPropertyNode.isVertexProperty()).isNotNull(); - } - - @Test - public void should_check_if_node_is_path_for_graphson_1_0() throws IOException { - // when - GraphNode pathNode = serdeAndCreateGraphNode(EmptyPath.instance(), GRAPHSON_1_0); - - // then - assertThat(pathNode.isPath()).isFalse(); - assertThatThrownBy(pathNode::asPath).isExactlyInstanceOf(UnsupportedOperationException.class); - } - - @Test - @UseDataProvider("objectGraphNodeProtocols") - public void should_check_if_node_is_path(GraphProtocol graphProtocol) throws IOException { - // when - GraphNode pathNode = serdeAndCreateGraphNode(EmptyPath.instance(), graphProtocol); - - // then - assertThat(pathNode.isPath()).isTrue(); - assertThat(pathNode.asPath()).isNotNull(); - } - - @Test - @UseDataProvider("allGraphProtocols") - public void should_check_if_node_is_vertex(GraphProtocol graphProtocol) throws IOException { - // when - GraphNode vertexNode = - serdeAndCreateGraphNode(new DetachedVertex("a", "l", null), graphProtocol); - - // then - assertThat(vertexNode.isVertex()).isTrue(); - assertThat(vertexNode.asVertex()).isNotNull(); - } - - @Test - @UseDataProvider("allGraphProtocols") - public void should_check_if_node_is_edge(GraphProtocol graphProtocol) throws IOException { - // when - GraphNode edgeNode = - serdeAndCreateGraphNode( - new DetachedEdge("a", "l", Collections.emptyMap(), "v1", "l1", "v2", "l2"), - graphProtocol); - - // then - assertThat(edgeNode.isEdge()).isTrue(); - assertThat(edgeNode.asEdge()).isNotNull(); - } - - private GraphNode serdeAndCreateGraphNode(Object inputValue, GraphProtocol graphProtocol) - throws IOException { - if (graphProtocol.isGraphBinary()) { - Buffer tinkerBuf = graphBinaryModule.serialize(new DefaultRemoteTraverser<>(inputValue, 0L)); - ByteBuffer nioBuffer = tinkerBuf.nioBuffer(); - tinkerBuf.release(); - return new ObjectGraphNode( - GraphConversions.createGraphBinaryGraphNode( - ImmutableList.of(nioBuffer), graphBinaryModule) - .as(Traverser.class) - .get()); - } else { - return GraphSONUtils.createGraphNode( - ImmutableList.of(GraphSONUtils.serializeToByteBuffer(inputValue, graphProtocol)), - graphProtocol); - } - } - - @DataProvider - public static Object[][] allGraphProtocols() { - return new Object[][] {{GRAPHSON_1_0}, {GRAPHSON_2_0}, {GRAPH_BINARY_1_0}}; - } - - @DataProvider - public static Object[][] graphson1_0and2_0() { - return new Object[][] {{GRAPHSON_1_0}, {GRAPHSON_2_0}}; - } - - @DataProvider - public static Object[][] objectGraphNodeProtocols() { - return new Object[][] {{GRAPHSON_2_0}, {GRAPH_BINARY_1_0}}; - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/graph/GraphRequestHandlerTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/graph/GraphRequestHandlerTest.java deleted file mode 100644 index 852991b9607..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/graph/GraphRequestHandlerTest.java +++ /dev/null @@ -1,622 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import static com.datastax.dse.driver.internal.core.graph.GraphProtocol.GRAPHSON_1_0; -import static com.datastax.dse.driver.internal.core.graph.GraphProtocol.GRAPHSON_2_0; -import static com.datastax.dse.driver.internal.core.graph.GraphProtocol.GRAPH_BINARY_1_0; -import static com.datastax.dse.driver.internal.core.graph.GraphTestUtils.createGraphBinaryModule; -import static com.datastax.dse.driver.internal.core.graph.GraphTestUtils.defaultDseFrameOf; -import static com.datastax.dse.driver.internal.core.graph.GraphTestUtils.serialize; -import static com.datastax.dse.driver.internal.core.graph.GraphTestUtils.singleGraphRow; -import static com.datastax.oss.driver.api.core.type.codec.TypeCodecs.BIGINT; -import static com.datastax.oss.driver.api.core.type.codec.TypeCodecs.TEXT; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.matches; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import com.datastax.dse.driver.DseTestDataProviders; -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.dse.driver.api.core.data.geometry.Point; -import com.datastax.dse.driver.api.core.graph.BatchGraphStatement; -import com.datastax.dse.driver.api.core.graph.DseGraph; -import com.datastax.dse.driver.api.core.graph.FluentGraphStatement; -import com.datastax.dse.driver.api.core.graph.GraphNode; -import com.datastax.dse.driver.api.core.graph.GraphResultSet; -import com.datastax.dse.driver.api.core.graph.GraphStatement; -import com.datastax.dse.driver.api.core.graph.ScriptGraphStatement; -import com.datastax.dse.driver.api.core.metrics.DseNodeMetric; -import com.datastax.dse.driver.api.core.metrics.DseSessionMetric; -import com.datastax.dse.driver.internal.core.graph.binary.GraphBinaryModule; -import com.datastax.dse.protocol.internal.request.RawBytesQuery; -import com.datastax.dse.protocol.internal.request.query.DseQueryOptions; -import com.datastax.oss.driver.api.core.DefaultConsistencyLevel; -import com.datastax.oss.driver.api.core.Version; -import com.datastax.oss.driver.api.core.config.DefaultDriverOption; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.tracker.RequestTracker; -import com.datastax.oss.driver.api.core.uuid.Uuids; -import com.datastax.oss.driver.internal.core.cql.Conversions; -import com.datastax.oss.driver.internal.core.cql.PoolBehavior; -import com.datastax.oss.driver.internal.core.metadata.DefaultNode; -import com.datastax.oss.driver.internal.core.metrics.NodeMetricUpdater; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import com.datastax.oss.protocol.internal.Message; -import com.datastax.oss.protocol.internal.request.Query; -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import java.io.IOException; -import java.math.BigInteger; -import java.nio.ByteBuffer; -import java.time.Duration; -import java.time.LocalDateTime; -import java.time.ZoneOffset; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import java.util.regex.Pattern; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; - -@RunWith(DataProviderRunner.class) -public class GraphRequestHandlerTest { - - private static final Pattern LOG_PREFIX_PER_REQUEST = Pattern.compile("test-graph\\|\\d+"); - - @Mock DefaultNode node; - - @Mock protected NodeMetricUpdater nodeMetricUpdater1; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - when(node.getMetricUpdater()).thenReturn(nodeMetricUpdater1); - } - - @Test - @UseDataProvider(location = DseTestDataProviders.class, value = "supportedGraphProtocols") - public void should_create_query_message_from_script_statement(GraphProtocol graphProtocol) - throws IOException { - // initialization - GraphRequestHandlerTestHarness harness = GraphRequestHandlerTestHarness.builder().build(); - ScriptGraphStatement graphStatement = - ScriptGraphStatement.newInstance("mockQuery") - .setQueryParam("p1", 1L) - .setQueryParam("p2", Uuids.random()); - - GraphBinaryModule module = createGraphBinaryModule(harness.getContext()); - - // when - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(graphStatement, harness.getContext()); - - Message m = - GraphConversions.createMessageFromGraphStatement( - graphStatement, graphProtocol, executionProfile, harness.getContext(), module); - - // checks - assertThat(m).isInstanceOf(Query.class); - Query q = ((Query) m); - assertThat(q.query).isEqualTo("mockQuery"); - assertThat(q.options.positionalValues) - .containsExactly(serialize(graphStatement.getQueryParams(), graphProtocol, module)); - assertThat(q.options.namedValues).isEmpty(); - } - - @Test - @UseDataProvider(location = DseTestDataProviders.class, value = "supportedGraphProtocols") - public void should_create_query_message_from_fluent_statement(GraphProtocol graphProtocol) - throws IOException { - // initialization - GraphRequestHandlerTestHarness harness = GraphRequestHandlerTestHarness.builder().build(); - GraphTraversal traversalTest = - DseGraph.g.V().has("person", "name", "marko").has("p1", 1L).has("p2", Uuids.random()); - GraphStatement graphStatement = FluentGraphStatement.newInstance(traversalTest); - - GraphBinaryModule module = createGraphBinaryModule(harness.getContext()); - - // when - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(graphStatement, harness.getContext()); - - Message m = - GraphConversions.createMessageFromGraphStatement( - graphStatement, graphProtocol, executionProfile, harness.getContext(), module); - - Map createdCustomPayload = - GraphConversions.createCustomPayload( - graphStatement, graphProtocol, executionProfile, harness.getContext(), module); - - // checks - assertThat(m).isInstanceOf(RawBytesQuery.class); - testQueryRequestAndPayloadContents( - ((RawBytesQuery) m), - createdCustomPayload, - GraphConversions.bytecodeToSerialize(graphStatement), - graphProtocol, - module); - } - - @Test - @UseDataProvider(location = DseTestDataProviders.class, value = "supportedGraphProtocols") - public void should_create_query_message_from_batch_statement(GraphProtocol graphProtocol) - throws IOException { - // initialization - GraphRequestHandlerTestHarness harness = GraphRequestHandlerTestHarness.builder().build(); - @SuppressWarnings("rawtypes") - List traversalsTest = - ImmutableList.of( - // randomly testing some complex data types. Complete suite of data types test is in - // GraphDataTypesTest - DseGraph.g - .addV("person") - .property("p1", 2.3f) - .property("p2", LocalDateTime.now(ZoneOffset.UTC)), - DseGraph.g - .addV("software") - .property("p3", new BigInteger("123456789123456789123456789123456789")) - .property("p4", ImmutableList.of(Point.fromCoordinates(30.4, 25.63746284)))); - GraphStatement graphStatement = - BatchGraphStatement.builder().addTraversals(traversalsTest).build(); - - GraphBinaryModule module = createGraphBinaryModule(harness.getContext()); - - // when - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(graphStatement, harness.getContext()); - - Message m = - GraphConversions.createMessageFromGraphStatement( - graphStatement, graphProtocol, executionProfile, harness.getContext(), module); - - Map createdCustomPayload = - GraphConversions.createCustomPayload( - graphStatement, graphProtocol, executionProfile, harness.getContext(), module); - - // checks - assertThat(m).isInstanceOf(RawBytesQuery.class); - testQueryRequestAndPayloadContents( - ((RawBytesQuery) m), - createdCustomPayload, - GraphConversions.bytecodeToSerialize(graphStatement), - graphProtocol, - module); - } - - private void testQueryRequestAndPayloadContents( - RawBytesQuery q, - Map customPayload, - Object traversalTest, - GraphProtocol graphProtocol, - GraphBinaryModule module) - throws IOException { - if (graphProtocol.isGraphBinary()) { - assertThat(q.query).isEqualTo(GraphConversions.EMPTY_STRING_QUERY); - assertThat(customPayload).containsKey(GraphConversions.GRAPH_BINARY_QUERY_OPTION_KEY); - ByteBuffer encodedQuery = customPayload.get(GraphConversions.GRAPH_BINARY_QUERY_OPTION_KEY); - assertThat(encodedQuery).isNotNull(); - assertThat(encodedQuery).isEqualTo(serialize(traversalTest, graphProtocol, module)); - } else { - assertThat(q.query).isEqualTo(serialize(traversalTest, graphProtocol, module).array()); - assertThat(customPayload).doesNotContainKey(GraphConversions.GRAPH_BINARY_QUERY_OPTION_KEY); - } - } - - @Test - @UseDataProvider(location = DseTestDataProviders.class, value = "supportedGraphProtocols") - public void should_set_correct_query_options_from_graph_statement(GraphProtocol subProtocol) - throws IOException { - // initialization - GraphRequestHandlerTestHarness harness = GraphRequestHandlerTestHarness.builder().build(); - GraphStatement graphStatement = - ScriptGraphStatement.newInstance("mockQuery").setQueryParam("name", "value"); - - GraphBinaryModule module = createGraphBinaryModule(harness.getContext()); - - // when - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(graphStatement, harness.getContext()); - Message m = - GraphConversions.createMessageFromGraphStatement( - graphStatement, subProtocol, executionProfile, harness.getContext(), module); - - // checks - Query query = ((Query) m); - DseQueryOptions options = ((DseQueryOptions) query.options); - assertThat(options.consistency) - .isEqualTo( - DefaultConsistencyLevel.valueOf( - executionProfile.getString(DefaultDriverOption.REQUEST_CONSISTENCY)) - .getProtocolCode()); - // set by the mock timestamp generator - assertThat(options.defaultTimestamp).isEqualTo(-9223372036854775808L); - assertThat(options.positionalValues) - .isEqualTo( - ImmutableList.of(serialize(ImmutableMap.of("name", "value"), subProtocol, module))); - - m = - GraphConversions.createMessageFromGraphStatement( - graphStatement.setTimestamp(2L), - subProtocol, - executionProfile, - harness.getContext(), - module); - query = ((Query) m); - options = ((DseQueryOptions) query.options); - assertThat(options.defaultTimestamp).isEqualTo(2L); - } - - @Test - @UseDataProvider(location = DseTestDataProviders.class, value = "supportedGraphProtocols") - public void should_create_payload_from_config_options(GraphProtocol subProtocol) { - // initialization - GraphRequestHandlerTestHarness harness = GraphRequestHandlerTestHarness.builder().build(); - GraphStatement graphStatement = - ScriptGraphStatement.newInstance("mockQuery").setExecutionProfileName("test-graph"); - - GraphBinaryModule module = createGraphBinaryModule(harness.getContext()); - - // when - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(graphStatement, harness.getContext()); - - Map requestPayload = - GraphConversions.createCustomPayload( - graphStatement, subProtocol, executionProfile, harness.getContext(), module); - - // checks - Mockito.verify(executionProfile).getString(DseDriverOption.GRAPH_TRAVERSAL_SOURCE, null); - Mockito.verify(executionProfile).getString(DseDriverOption.GRAPH_NAME, null); - Mockito.verify(executionProfile).getBoolean(DseDriverOption.GRAPH_IS_SYSTEM_QUERY, false); - Mockito.verify(executionProfile).getDuration(DseDriverOption.GRAPH_TIMEOUT, Duration.ZERO); - Mockito.verify(executionProfile).getString(DseDriverOption.GRAPH_READ_CONSISTENCY_LEVEL, null); - Mockito.verify(executionProfile).getString(DseDriverOption.GRAPH_WRITE_CONSISTENCY_LEVEL, null); - - assertThat(requestPayload.get(GraphConversions.GRAPH_SOURCE_OPTION_KEY)) - .isEqualTo(TEXT.encode("a", harness.getContext().getProtocolVersion())); - assertThat(requestPayload.get(GraphConversions.GRAPH_RESULTS_OPTION_KEY)) - .isEqualTo( - TEXT.encode(subProtocol.toInternalCode(), harness.getContext().getProtocolVersion())); - assertThat(requestPayload.get(GraphConversions.GRAPH_NAME_OPTION_KEY)) - .isEqualTo(TEXT.encode("mockGraph", harness.getContext().getProtocolVersion())); - assertThat(requestPayload.get(GraphConversions.GRAPH_LANG_OPTION_KEY)) - .isEqualTo(TEXT.encode("gremlin-groovy", harness.getContext().getProtocolVersion())); - assertThat(requestPayload.get(GraphConversions.GRAPH_TIMEOUT_OPTION_KEY)) - .isEqualTo(BIGINT.encode(2L, harness.getContext().getProtocolVersion())); - assertThat(requestPayload.get(GraphConversions.GRAPH_READ_CONSISTENCY_LEVEL_OPTION_KEY)) - .isEqualTo(TEXT.encode("LOCAL_TWO", harness.getContext().getProtocolVersion())); - assertThat(requestPayload.get(GraphConversions.GRAPH_WRITE_CONSISTENCY_LEVEL_OPTION_KEY)) - .isEqualTo(TEXT.encode("LOCAL_THREE", harness.getContext().getProtocolVersion())); - } - - @Test - @UseDataProvider(location = DseTestDataProviders.class, value = "supportedGraphProtocols") - public void should_create_payload_from_statement_options(GraphProtocol subProtocol) { - // initialization - GraphRequestHandlerTestHarness harness = GraphRequestHandlerTestHarness.builder().build(); - GraphStatement graphStatement = - ScriptGraphStatement.builder("mockQuery") - .setGraphName("mockGraph") - .setTraversalSource("a") - .setTimeout(Duration.ofMillis(2)) - .setReadConsistencyLevel(DefaultConsistencyLevel.TWO) - .setWriteConsistencyLevel(DefaultConsistencyLevel.THREE) - .setSystemQuery(false) - .build(); - - GraphBinaryModule module = createGraphBinaryModule(harness.getContext()); - - // when - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(graphStatement, harness.getContext()); - - Map requestPayload = - GraphConversions.createCustomPayload( - graphStatement, subProtocol, executionProfile, harness.getContext(), module); - - // checks - Mockito.verify(executionProfile, never()) - .getString(DseDriverOption.GRAPH_TRAVERSAL_SOURCE, null); - Mockito.verify(executionProfile, never()).getString(DseDriverOption.GRAPH_NAME, null); - Mockito.verify(executionProfile, never()) - .getBoolean(DseDriverOption.GRAPH_IS_SYSTEM_QUERY, false); - Mockito.verify(executionProfile, never()) - .getDuration(DseDriverOption.GRAPH_TIMEOUT, Duration.ZERO); - Mockito.verify(executionProfile, never()) - .getString(DseDriverOption.GRAPH_READ_CONSISTENCY_LEVEL, null); - Mockito.verify(executionProfile, never()) - .getString(DseDriverOption.GRAPH_WRITE_CONSISTENCY_LEVEL, null); - - assertThat(requestPayload.get(GraphConversions.GRAPH_SOURCE_OPTION_KEY)) - .isEqualTo(TEXT.encode("a", harness.getContext().getProtocolVersion())); - assertThat(requestPayload.get(GraphConversions.GRAPH_RESULTS_OPTION_KEY)) - .isEqualTo( - TEXT.encode(subProtocol.toInternalCode(), harness.getContext().getProtocolVersion())); - assertThat(requestPayload.get(GraphConversions.GRAPH_NAME_OPTION_KEY)) - .isEqualTo(TEXT.encode("mockGraph", harness.getContext().getProtocolVersion())); - assertThat(requestPayload.get(GraphConversions.GRAPH_LANG_OPTION_KEY)) - .isEqualTo(TEXT.encode("gremlin-groovy", harness.getContext().getProtocolVersion())); - assertThat(requestPayload.get(GraphConversions.GRAPH_TIMEOUT_OPTION_KEY)) - .isEqualTo(BIGINT.encode(2L, harness.getContext().getProtocolVersion())); - assertThat(requestPayload.get(GraphConversions.GRAPH_READ_CONSISTENCY_LEVEL_OPTION_KEY)) - .isEqualTo(TEXT.encode("TWO", harness.getContext().getProtocolVersion())); - assertThat(requestPayload.get(GraphConversions.GRAPH_WRITE_CONSISTENCY_LEVEL_OPTION_KEY)) - .isEqualTo(TEXT.encode("THREE", harness.getContext().getProtocolVersion())); - } - - @Test - @UseDataProvider(location = DseTestDataProviders.class, value = "supportedGraphProtocols") - public void should_not_set_graph_name_on_system_queries(GraphProtocol subProtocol) { - // initialization - GraphRequestHandlerTestHarness harness = GraphRequestHandlerTestHarness.builder().build(); - GraphStatement graphStatement = - ScriptGraphStatement.newInstance("mockQuery").setSystemQuery(true); - - GraphBinaryModule module = createGraphBinaryModule(harness.getContext()); - - // when - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(graphStatement, harness.getContext()); - - Map requestPayload = - GraphConversions.createCustomPayload( - graphStatement, subProtocol, executionProfile, harness.getContext(), module); - - // checks - assertThat(requestPayload.get(GraphConversions.GRAPH_NAME_OPTION_KEY)).isNull(); - assertThat(requestPayload.get(GraphConversions.GRAPH_SOURCE_OPTION_KEY)).isNull(); - } - - @Test - @UseDataProvider("supportedGraphProtocolsWithDseVersions") - public void should_return_results_for_statements(GraphProtocol graphProtocol, Version dseVersion) - throws IOException { - - GraphRequestHandlerTestHarness.Builder builder = - GraphRequestHandlerTestHarness.builder() - .withGraphProtocolForTestConfig(graphProtocol) - .withDseVersionInMetadata(dseVersion); - PoolBehavior node1Behavior = builder.customBehavior(node); - GraphRequestHandlerTestHarness harness = builder.build(); - - GraphBinaryModule module = createGraphBinaryModule(harness.getContext()); - - // ideally we would be able to provide a function here to - // produce results instead of a static predefined response. - // Function to which we would pass the harness instance or a (mocked)DriverContext. - // Since that's not possible in the RequestHandlerTestHarness API at the moment, we - // have to use another DseDriverContext and GraphBinaryModule here, - // instead of reusing the one in the harness' DriverContext - node1Behavior.setResponseSuccess(defaultDseFrameOf(singleGraphRow(graphProtocol, module))); - - GraphSupportChecker graphSupportChecker = mock(GraphSupportChecker.class); - when(graphSupportChecker.isPagingEnabled(any(), any())).thenReturn(false); - when(graphSupportChecker.inferGraphProtocol(any(), any(), any())).thenReturn(graphProtocol); - - GraphRequestAsyncProcessor p = - Mockito.spy(new GraphRequestAsyncProcessor(harness.getContext(), graphSupportChecker)); - when(p.getGraphBinaryModule()).thenReturn(module); - - GraphStatement graphStatement = - ScriptGraphStatement.newInstance("mockQuery").setExecutionProfileName("test-graph"); - GraphResultSet grs = - new GraphRequestSyncProcessor(p) - .process(graphStatement, harness.getSession(), harness.getContext(), "test-graph"); - - List nodes = grs.all(); - assertThat(nodes.size()).isEqualTo(1); - - GraphNode graphNode = nodes.get(0); - assertThat(graphNode.isVertex()).isTrue(); - - Vertex vRead = graphNode.asVertex(); - assertThat(vRead.label()).isEqualTo("person"); - assertThat(vRead.id()).isEqualTo(1); - if (!graphProtocol.isGraphBinary()) { - // GraphBinary does not encode properties regardless of whether they are present in the - // parent element or not :/ - assertThat(vRead.property("name").id()).isEqualTo(11); - assertThat(vRead.property("name").value()).isEqualTo("marko"); - } - } - - @DataProvider - public static Object[][] supportedGraphProtocolsWithDseVersions() { - return new Object[][] { - {GRAPHSON_1_0, Version.parse("6.7.0")}, - {GRAPHSON_1_0, Version.parse("6.8.0")}, - {GRAPHSON_2_0, Version.parse("6.7.0")}, - {GRAPHSON_2_0, Version.parse("6.8.0")}, - {GRAPH_BINARY_1_0, Version.parse("6.7.0")}, - {GRAPH_BINARY_1_0, Version.parse("6.8.0")}, - }; - } - - @Test - @UseDataProvider("dseVersionsWithDefaultGraphProtocol") - public void should_invoke_request_tracker_and_update_metrics( - GraphProtocol graphProtocol, Version dseVersion) throws IOException { - when(nodeMetricUpdater1.isEnabled( - DseNodeMetric.GRAPH_MESSAGES, DriverExecutionProfile.DEFAULT_NAME)) - .thenReturn(true); - - GraphRequestHandlerTestHarness.Builder builder = - GraphRequestHandlerTestHarness.builder() - .withGraphProtocolForTestConfig(graphProtocol) - .withDseVersionInMetadata(dseVersion); - PoolBehavior node1Behavior = builder.customBehavior(node); - GraphRequestHandlerTestHarness harness = builder.build(); - - GraphBinaryModule module = createGraphBinaryModule(harness.getContext()); - - GraphSupportChecker graphSupportChecker = mock(GraphSupportChecker.class); - when(graphSupportChecker.isPagingEnabled(any(), any())).thenReturn(false); - when(graphSupportChecker.inferGraphProtocol(any(), any(), any())).thenReturn(graphProtocol); - - GraphRequestAsyncProcessor p = - Mockito.spy(new GraphRequestAsyncProcessor(harness.getContext(), graphSupportChecker)); - when(p.getGraphBinaryModule()).thenReturn(module); - - RequestTracker requestTracker = mock(RequestTracker.class); - when(harness.getContext().getRequestTracker()).thenReturn(requestTracker); - - GraphStatement graphStatement = ScriptGraphStatement.newInstance("mockQuery"); - - node1Behavior.setResponseSuccess(defaultDseFrameOf(singleGraphRow(graphProtocol, module))); - - GraphResultSet grs = - new GraphRequestSyncProcessor( - new GraphRequestAsyncProcessor(harness.getContext(), graphSupportChecker)) - .process(graphStatement, harness.getSession(), harness.getContext(), "test-graph"); - - List nodes = grs.all(); - assertThat(nodes.size()).isEqualTo(1); - - GraphNode graphNode = nodes.get(0); - assertThat(graphNode.isVertex()).isTrue(); - - Vertex actual = graphNode.asVertex(); - assertThat(actual.label()).isEqualTo("person"); - assertThat(actual.id()).isEqualTo(1); - if (!graphProtocol.isGraphBinary()) { - // GraphBinary does not encode properties regardless of whether they are present in the - // parent element or not :/ - assertThat(actual.property("name").id()).isEqualTo(11); - assertThat(actual.property("name").value()).isEqualTo("marko"); - } - - verify(requestTracker) - .onSuccess( - eq(graphStatement), - anyLong(), - any(DriverExecutionProfile.class), - eq(node), - matches(LOG_PREFIX_PER_REQUEST)); - verify(requestTracker) - .onNodeSuccess( - eq(graphStatement), - anyLong(), - any(DriverExecutionProfile.class), - eq(node), - matches(LOG_PREFIX_PER_REQUEST)); - verifyNoMoreInteractions(requestTracker); - - verify(nodeMetricUpdater1) - .isEnabled(DseNodeMetric.GRAPH_MESSAGES, DriverExecutionProfile.DEFAULT_NAME); - verify(nodeMetricUpdater1) - .updateTimer( - eq(DseNodeMetric.GRAPH_MESSAGES), - eq(DriverExecutionProfile.DEFAULT_NAME), - anyLong(), - eq(TimeUnit.NANOSECONDS)); - verifyNoMoreInteractions(nodeMetricUpdater1); - - verify(harness.getSession().getMetricUpdater()) - .isEnabled(DseSessionMetric.GRAPH_REQUESTS, DriverExecutionProfile.DEFAULT_NAME); - verify(harness.getSession().getMetricUpdater()) - .updateTimer( - eq(DseSessionMetric.GRAPH_REQUESTS), - eq(DriverExecutionProfile.DEFAULT_NAME), - anyLong(), - eq(TimeUnit.NANOSECONDS)); - verifyNoMoreInteractions(harness.getSession().getMetricUpdater()); - } - - @Test - public void should_honor_statement_consistency_level() { - // initialization - GraphRequestHandlerTestHarness harness = GraphRequestHandlerTestHarness.builder().build(); - ScriptGraphStatement graphStatement = - ScriptGraphStatement.builder("mockScript") - .setConsistencyLevel(DefaultConsistencyLevel.THREE) - .build(); - - GraphBinaryModule module = createGraphBinaryModule(harness.getContext()); - - // when - DriverExecutionProfile executionProfile = - Conversions.resolveExecutionProfile(graphStatement, harness.getContext()); - - Message m = - GraphConversions.createMessageFromGraphStatement( - graphStatement, GRAPH_BINARY_1_0, executionProfile, harness.getContext(), module); - - // checks - assertThat(m).isInstanceOf(Query.class); - Query q = ((Query) m); - assertThat(q.options.consistency).isEqualTo(DefaultConsistencyLevel.THREE.getProtocolCode()); - } - - @Test - public void should_cancel_pre_acquired_id_if_graph_payload_conversion_fails() { - RuntimeException failure = new RuntimeException("mock failure"); - ScriptGraphStatement graphStatement = - Mockito.spy(ScriptGraphStatement.newInstance("mock query")); - doThrow(failure).when(graphStatement).getCustomPayload(); - - GraphRequestHandlerTestHarness.Builder builder = GraphRequestHandlerTestHarness.builder(); - PoolBehavior nodeBehavior = builder.customBehavior(node); - try (GraphRequestHandlerTestHarness harness = builder.build()) { - GraphSupportChecker graphSupportChecker = mock(GraphSupportChecker.class); - when(graphSupportChecker.inferGraphProtocol(any(), any(), any())) - .thenReturn(GRAPH_BINARY_1_0); - GraphBinaryModule module = createGraphBinaryModule(harness.getContext()); - - assertThatThrownBy( - () -> - new GraphRequestHandler( - graphStatement, - harness.getSession(), - harness.getContext(), - "test", - module, - graphSupportChecker)) - .isSameAs(failure); - - nodeBehavior.verifyNoWrite(); - nodeBehavior.verifyPreAcquireCancelled(); - } - } - - @DataProvider - public static Object[][] dseVersionsWithDefaultGraphProtocol() { - // Default GraphSON sub protocol version differs based on DSE version, so test with a version - // less than DSE 6.8 as well as DSE 6.8. - return new Object[][] { - {GRAPHSON_2_0, Version.parse("6.7.0")}, - {GRAPH_BINARY_1_0, Version.parse("6.8.0")}, - }; - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/graph/GraphRequestHandlerTestHarness.java b/core/src/test/java/com/datastax/dse/driver/internal/core/graph/GraphRequestHandlerTestHarness.java deleted file mode 100644 index 9ce5dee1e8c..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/graph/GraphRequestHandlerTestHarness.java +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import static org.mockito.Mockito.when; - -import com.datastax.dse.driver.DseTestFixtures; -import com.datastax.dse.driver.api.core.DseProtocolVersion; -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.oss.driver.api.core.DefaultConsistencyLevel; -import com.datastax.oss.driver.api.core.ProtocolVersion; -import com.datastax.oss.driver.api.core.Version; -import com.datastax.oss.driver.api.core.config.DefaultDriverOption; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.datastax.oss.driver.api.core.type.codec.registry.CodecRegistry; -import com.datastax.oss.driver.internal.core.DefaultConsistencyLevelRegistry; -import com.datastax.oss.driver.internal.core.context.DefaultDriverContext; -import com.datastax.oss.driver.internal.core.cql.RequestHandlerTestHarness; -import com.datastax.oss.driver.internal.core.servererrors.DefaultWriteTypeRegistry; -import com.datastax.oss.driver.internal.core.session.throttling.PassThroughRequestThrottler; -import com.datastax.oss.driver.internal.core.tracker.NoopRequestTracker; -import com.datastax.oss.protocol.internal.Frame; -import edu.umd.cs.findbugs.annotations.Nullable; -import io.netty.channel.EventLoop; -import java.time.Duration; -import org.mockito.ArgumentMatchers; -import org.mockito.Mock; - -/** - * Provides the environment to test a request handler, where a query plan can be defined, and the - * behavior of each successive node simulated. - */ -public class GraphRequestHandlerTestHarness extends RequestHandlerTestHarness { - - @Mock DriverExecutionProfile testProfile; - - @Mock DriverExecutionProfile systemQueryExecutionProfile; - - @Mock DefaultDriverContext dseDriverContext; - - @Mock EventLoop eventLoop; - - protected GraphRequestHandlerTestHarness( - Builder builder, - @Nullable GraphProtocol graphProtocolForTestConfig, - Duration graphTimeout, - @Nullable Version dseVersionForTestMetadata) { - super(builder); - - // not mocked by RequestHandlerTestHarness, will be used when DseDriverOptions.GRAPH_TIMEOUT - // is not zero in the config - when(eventLoopGroup.next()).thenReturn(eventLoop); - - // default graph options as in the reference.conf file - when(defaultProfile.getString(DseDriverOption.GRAPH_TRAVERSAL_SOURCE, null)).thenReturn("g"); - when(defaultProfile.isDefined(DseDriverOption.GRAPH_SUB_PROTOCOL)).thenReturn(Boolean.FALSE); - when(defaultProfile.getBoolean(DseDriverOption.GRAPH_IS_SYSTEM_QUERY, false)).thenReturn(false); - when(defaultProfile.getString(DseDriverOption.GRAPH_NAME, null)).thenReturn("mockGraph"); - when(defaultProfile.getDuration(DseDriverOption.GRAPH_TIMEOUT, Duration.ZERO)) - .thenReturn(graphTimeout); - - when(testProfile.getName()).thenReturn("test-graph"); - when(testProfile.getDuration(DseDriverOption.GRAPH_TIMEOUT, Duration.ZERO)) - .thenReturn(Duration.ofMillis(2L)); - when(testProfile.getString(DefaultDriverOption.REQUEST_CONSISTENCY)) - .thenReturn(DefaultConsistencyLevel.LOCAL_ONE.name()); - when(testProfile.getInt(DefaultDriverOption.REQUEST_PAGE_SIZE)).thenReturn(5000); - when(testProfile.getString(DefaultDriverOption.REQUEST_SERIAL_CONSISTENCY)) - .thenReturn(DefaultConsistencyLevel.SERIAL.name()); - when(testProfile.getBoolean(DefaultDriverOption.REQUEST_DEFAULT_IDEMPOTENCE)).thenReturn(false); - when(testProfile.getBoolean(DefaultDriverOption.PREPARE_ON_ALL_NODES)).thenReturn(true); - when(testProfile.getString(DseDriverOption.GRAPH_TRAVERSAL_SOURCE, null)).thenReturn("a"); - when(testProfile.isDefined(DseDriverOption.GRAPH_SUB_PROTOCOL)) - .thenReturn(graphProtocolForTestConfig != null); - // only mock the config if graphProtocolForTestConfig is not null - if (graphProtocolForTestConfig != null) { - when(testProfile.getString(DseDriverOption.GRAPH_SUB_PROTOCOL)) - .thenReturn(graphProtocolForTestConfig.toInternalCode()); - } - when(testProfile.getBoolean(DseDriverOption.GRAPH_IS_SYSTEM_QUERY, false)).thenReturn(false); - when(testProfile.getString(DseDriverOption.GRAPH_NAME, null)).thenReturn("mockGraph"); - when(testProfile.getString(DseDriverOption.GRAPH_READ_CONSISTENCY_LEVEL, null)) - .thenReturn("LOCAL_TWO"); - when(testProfile.getString(DseDriverOption.GRAPH_WRITE_CONSISTENCY_LEVEL, null)) - .thenReturn("LOCAL_THREE"); - when(config.getProfile("test-graph")).thenReturn(testProfile); - - when(systemQueryExecutionProfile.getName()).thenReturn("graph-system-query"); - when(systemQueryExecutionProfile.getDuration(DseDriverOption.GRAPH_TIMEOUT, Duration.ZERO)) - .thenReturn(Duration.ZERO); - when(systemQueryExecutionProfile.getString(DefaultDriverOption.REQUEST_CONSISTENCY)) - .thenReturn(DefaultConsistencyLevel.LOCAL_ONE.name()); - when(systemQueryExecutionProfile.getInt(DefaultDriverOption.REQUEST_PAGE_SIZE)) - .thenReturn(5000); - when(systemQueryExecutionProfile.getString(DefaultDriverOption.REQUEST_SERIAL_CONSISTENCY)) - .thenReturn(DefaultConsistencyLevel.SERIAL.name()); - when(systemQueryExecutionProfile.getBoolean(DefaultDriverOption.REQUEST_DEFAULT_IDEMPOTENCE)) - .thenReturn(false); - when(systemQueryExecutionProfile.getBoolean(DefaultDriverOption.PREPARE_ON_ALL_NODES)) - .thenReturn(true); - when(systemQueryExecutionProfile.getName()).thenReturn("graph-system-query"); - when(systemQueryExecutionProfile.getDuration(DseDriverOption.GRAPH_TIMEOUT, Duration.ZERO)) - .thenReturn(Duration.ofMillis(2)); - when(systemQueryExecutionProfile.getBoolean(DseDriverOption.GRAPH_IS_SYSTEM_QUERY, false)) - .thenReturn(true); - when(systemQueryExecutionProfile.getString(DseDriverOption.GRAPH_READ_CONSISTENCY_LEVEL, null)) - .thenReturn("LOCAL_TWO"); - when(systemQueryExecutionProfile.getString(DseDriverOption.GRAPH_WRITE_CONSISTENCY_LEVEL, null)) - .thenReturn("LOCAL_THREE"); - - when(config.getProfile("graph-system-query")).thenReturn(systemQueryExecutionProfile); - - // need to re-mock everything on the context because the RequestHandlerTestHarness returns a - // InternalDriverContext and not a DseDriverContext. Couldn't figure out a way with mockito - // to say "mock this object (this.dseDriverContext), and delegate every call to that - // other object (this.context), except _this_ call and _this_ and so on" - // Spy wouldn't work because the spied object has to be of the same type as the final object - when(dseDriverContext.getConfig()).thenReturn(config); - when(dseDriverContext.getNettyOptions()).thenReturn(nettyOptions); - when(dseDriverContext.getLoadBalancingPolicyWrapper()).thenReturn(loadBalancingPolicyWrapper); - when(dseDriverContext.getRetryPolicy(ArgumentMatchers.anyString())).thenReturn(retryPolicy); - when(dseDriverContext.getSpeculativeExecutionPolicy(ArgumentMatchers.anyString())) - .thenReturn(speculativeExecutionPolicy); - when(dseDriverContext.getCodecRegistry()).thenReturn(CodecRegistry.DEFAULT); - when(dseDriverContext.getTimestampGenerator()).thenReturn(timestampGenerator); - when(dseDriverContext.getProtocolVersion()).thenReturn(DseProtocolVersion.DSE_V2); - when(dseDriverContext.getProtocolVersionRegistry()).thenReturn(protocolVersionRegistry); - when(dseDriverContext.getConsistencyLevelRegistry()) - .thenReturn(new DefaultConsistencyLevelRegistry()); - when(dseDriverContext.getWriteTypeRegistry()).thenReturn(new DefaultWriteTypeRegistry()); - when(dseDriverContext.getRequestThrottler()) - .thenReturn(new PassThroughRequestThrottler(dseDriverContext)); - when(dseDriverContext.getRequestTracker()).thenReturn(new NoopRequestTracker(dseDriverContext)); - // if DSE Version is specified for test metadata, then we need to mock that up on the context - if (dseVersionForTestMetadata != null) { - DseTestFixtures.mockNodesInMetadataWithVersions( - dseDriverContext, true, dseVersionForTestMetadata); - } - } - - @Override - public DefaultDriverContext getContext() { - return dseDriverContext; - } - - public static GraphRequestHandlerTestHarness.Builder builder() { - return new GraphRequestHandlerTestHarness.Builder(); - } - - public static class Builder extends RequestHandlerTestHarness.Builder { - - private GraphProtocol graphProtocolForTestConfig; - private Duration graphTimeout = Duration.ZERO; - private Version dseVersionForTestMetadata; - - public GraphRequestHandlerTestHarness.Builder withGraphProtocolForTestConfig( - GraphProtocol protocol) { - this.graphProtocolForTestConfig = protocol; - return this; - } - - public GraphRequestHandlerTestHarness.Builder withDseVersionInMetadata(Version dseVersion) { - this.dseVersionForTestMetadata = dseVersion; - return this; - } - - public GraphRequestHandlerTestHarness.Builder withGraphTimeout(Duration globalTimeout) { - this.graphTimeout = globalTimeout; - return this; - } - - @Override - public GraphRequestHandlerTestHarness.Builder withEmptyPool(Node node) { - super.withEmptyPool(node); - return this; - } - - @Override - public GraphRequestHandlerTestHarness.Builder withWriteFailure(Node node, Throwable cause) { - super.withWriteFailure(node, cause); - return this; - } - - @Override - public GraphRequestHandlerTestHarness.Builder withResponseFailure(Node node, Throwable cause) { - super.withResponseFailure(node, cause); - return this; - } - - @Override - public GraphRequestHandlerTestHarness.Builder withResponse(Node node, Frame response) { - super.withResponse(node, response); - return this; - } - - @Override - public GraphRequestHandlerTestHarness.Builder withDefaultIdempotence( - boolean defaultIdempotence) { - super.withDefaultIdempotence(defaultIdempotence); - return this; - } - - @Override - public GraphRequestHandlerTestHarness.Builder withProtocolVersion( - ProtocolVersion protocolVersion) { - super.withProtocolVersion(protocolVersion); - return this; - } - - @Override - public GraphRequestHandlerTestHarness build() { - return new GraphRequestHandlerTestHarness( - this, graphProtocolForTestConfig, graphTimeout, dseVersionForTestMetadata); - } - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/graph/GraphResultSetTestBase.java b/core/src/test/java/com/datastax/dse/driver/internal/core/graph/GraphResultSetTestBase.java deleted file mode 100644 index aed248675ae..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/graph/GraphResultSetTestBase.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - -import com.datastax.dse.driver.api.core.graph.AsyncGraphResultSet; -import com.datastax.dse.driver.api.core.graph.GraphNode; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import com.datastax.oss.driver.internal.core.util.CountingIterator; -import com.datastax.oss.driver.shaded.guava.common.collect.Lists; -import java.util.Arrays; -import java.util.Iterator; -import java.util.Queue; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; - -public abstract class GraphResultSetTestBase { - - /** Mocks an async result set where column 0 has type INT, with rows with the provided data. */ - protected AsyncGraphResultSet mockPage(boolean nextPage, Integer... data) { - AsyncGraphResultSet page = mock(AsyncGraphResultSet.class); - - ExecutionInfo executionInfo = mock(ExecutionInfo.class); - when(page.getRequestExecutionInfo()).thenReturn(executionInfo); - - if (nextPage) { - when(page.hasMorePages()).thenReturn(true); - when(page.fetchNextPage()).thenReturn(spy(new CompletableFuture<>())); - } else { - when(page.hasMorePages()).thenReturn(false); - when(page.fetchNextPage()).thenThrow(new IllegalStateException()); - } - - // Emulate DefaultAsyncResultSet's internals (this is a bit sketchy, maybe it would be better - // to use real DefaultAsyncResultSet instances) - Queue queue = Lists.newLinkedList(Arrays.asList(data)); - CountingIterator iterator = - new CountingIterator(queue.size()) { - @Override - protected GraphNode computeNext() { - Integer index = queue.poll(); - return (index == null) ? endOfData() : mockRow(index); - } - }; - when(page.currentPage()).thenReturn(() -> iterator); - when(page.remaining()).thenAnswer(invocation -> iterator.remaining()); - - return page; - } - - private GraphNode mockRow(int index) { - GraphNode row = mock(GraphNode.class); - when(row.asInt()).thenReturn(index); - return row; - } - - protected static void complete( - CompletionStage stage, AsyncGraphResultSet result) { - stage.toCompletableFuture().complete(result); - } - - protected void assertNextRow(Iterator iterator, int expectedValue) { - assertThat(iterator.hasNext()).isTrue(); - GraphNode row = iterator.next(); - assertThat(row.asInt()).isEqualTo(expectedValue); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/graph/GraphResultSetsTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/graph/GraphResultSetsTest.java deleted file mode 100644 index fd5cffd2530..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/graph/GraphResultSetsTest.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.dse.driver.api.core.graph.AsyncGraphResultSet; -import com.datastax.dse.driver.api.core.graph.GraphNode; -import com.datastax.dse.driver.api.core.graph.GraphResultSet; -import java.util.Iterator; -import org.junit.Test; - -public class GraphResultSetsTest extends GraphResultSetTestBase { - - @Test - public void should_create_result_set_from_single_page() { - // Given - AsyncGraphResultSet page1 = mockPage(false, 0, 1, 2); - - // When - GraphResultSet resultSet = GraphResultSets.toSync(page1); - - // Then - assertThat(resultSet.getRequestExecutionInfo()).isSameAs(page1.getRequestExecutionInfo()); - - Iterator iterator = resultSet.iterator(); - - assertNextRow(iterator, 0); - assertNextRow(iterator, 1); - assertNextRow(iterator, 2); - - assertThat(iterator.hasNext()).isFalse(); - } - - @Test - public void should_create_result_set_from_multiple_pages() { - // Given - AsyncGraphResultSet page1 = mockPage(true, 0, 1, 2); - AsyncGraphResultSet page2 = mockPage(true, 3, 4, 5); - AsyncGraphResultSet page3 = mockPage(false, 6, 7, 8); - - complete(page1.fetchNextPage(), page2); - complete(page2.fetchNextPage(), page3); - - // When - GraphResultSet resultSet = GraphResultSets.toSync(page1); - - // Then - assertThat(resultSet.iterator().hasNext()).isTrue(); - - assertThat(resultSet.getRequestExecutionInfo()).isSameAs(page1.getRequestExecutionInfo()); - assertThat(((MultiPageGraphResultSet) resultSet).getRequestExecutionInfos()) - .containsExactly(page1.getRequestExecutionInfo()); - - Iterator iterator = resultSet.iterator(); - - assertNextRow(iterator, 0); - assertNextRow(iterator, 1); - assertNextRow(iterator, 2); - - assertThat(iterator.hasNext()).isTrue(); - // This should have triggered the fetch of page2 - assertThat(resultSet.getRequestExecutionInfo()).isEqualTo(page2.getRequestExecutionInfo()); - assertThat(((MultiPageGraphResultSet) resultSet).getRequestExecutionInfos()) - .containsExactly(page1.getRequestExecutionInfo(), page2.getRequestExecutionInfo()); - - assertNextRow(iterator, 3); - assertNextRow(iterator, 4); - assertNextRow(iterator, 5); - - assertThat(iterator.hasNext()).isTrue(); - // This should have triggered the fetch of page3 - assertThat(resultSet.getRequestExecutionInfo()).isEqualTo(page3.getRequestExecutionInfo()); - assertThat(((MultiPageGraphResultSet) resultSet).getRequestExecutionInfos()) - .containsExactly( - page1.getRequestExecutionInfo(), - page2.getRequestExecutionInfo(), - page3.getRequestExecutionInfo()); - - assertNextRow(iterator, 6); - assertNextRow(iterator, 7); - assertNextRow(iterator, 8); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/graph/GraphStatementBuilderBaseTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/graph/GraphStatementBuilderBaseTest.java deleted file mode 100644 index 4799437e617..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/graph/GraphStatementBuilderBaseTest.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import com.datastax.dse.driver.api.core.graph.FluentGraphStatement; -import com.datastax.dse.driver.api.core.graph.GraphStatementBuilderBase; -import com.datastax.oss.driver.api.core.cql.Statement; -import edu.umd.cs.findbugs.annotations.NonNull; -import org.junit.Test; - -public class GraphStatementBuilderBaseTest { - - private static class MockGraphStatementBuilder - extends GraphStatementBuilderBase { - - @NonNull - @Override - public FluentGraphStatement build() { - FluentGraphStatement rv = mock(FluentGraphStatement.class); - when(rv.getTimestamp()).thenReturn(this.timestamp); - return rv; - } - } - - @Test - public void should_use_timestamp_if_set() { - - MockGraphStatementBuilder builder = new MockGraphStatementBuilder(); - builder.setTimestamp(1); - assertThat(builder.build().getTimestamp()).isEqualTo(1); - } - - @Test - public void should_use_correct_default_timestamp_if_not_set() { - - MockGraphStatementBuilder builder = new MockGraphStatementBuilder(); - assertThat(builder.build().getTimestamp()).isEqualTo(Statement.NO_DEFAULT_TIMESTAMP); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/graph/GraphSupportCheckerTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/graph/GraphSupportCheckerTest.java deleted file mode 100644 index eda3bbed446..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/graph/GraphSupportCheckerTest.java +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import static com.datastax.dse.driver.DseTestFixtures.mockNodesInMetadataWithVersions; -import static com.datastax.dse.driver.api.core.graph.PagingEnabledOptions.AUTO; -import static com.datastax.dse.driver.api.core.graph.PagingEnabledOptions.DISABLED; -import static com.datastax.dse.driver.api.core.graph.PagingEnabledOptions.ENABLED; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verifyNoInteractions; -import static org.mockito.Mockito.when; - -import com.datastax.dse.driver.DseTestDataProviders; -import com.datastax.dse.driver.api.core.DseProtocolVersion; -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.dse.driver.api.core.graph.GraphStatement; -import com.datastax.dse.driver.api.core.graph.PagingEnabledOptions; -import com.datastax.dse.driver.api.core.metadata.DseNodeProperties; -import com.datastax.dse.driver.internal.core.DseProtocolFeature; -import com.datastax.oss.driver.api.core.Version; -import com.datastax.oss.driver.api.core.config.DriverConfig; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.metadata.Metadata; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.datastax.oss.driver.internal.core.ProtocolVersionRegistry; -import com.datastax.oss.driver.internal.core.context.DefaultDriverContext; -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import com.datastax.oss.driver.internal.core.metadata.MetadataManager; -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(DataProviderRunner.class) -public class GraphSupportCheckerTest { - - @UseDataProvider("graphPagingEnabledAndDseVersions") - @Test - public void should_check_if_paging_is_supported( - boolean protocolWithPagingSupport, - PagingEnabledOptions statementGraphPagingEnabled, - PagingEnabledOptions contextGraphPagingEnabled, - List nodeDseVersions, - boolean expected) { - // given - GraphStatement graphStatement = mock(GraphStatement.class); - InternalDriverContext context = protocolWithPagingSupport(protocolWithPagingSupport); - statementGraphPagingEnabled(graphStatement, statementGraphPagingEnabled); - contextGraphPagingEnabled(context, contextGraphPagingEnabled); - addNodeWithDseVersion(context, nodeDseVersions); - - // when - boolean pagingEnabled = new GraphSupportChecker().isPagingEnabled(graphStatement, context); - - // then - assertThat(pagingEnabled).isEqualTo(expected); - } - - @Test - public void should_not_support_paging_when_statement_profile_not_present() { - // given - GraphStatement graphStatement = mock(GraphStatement.class); - InternalDriverContext context = protocolWithPagingSupport(true); - contextGraphPagingEnabled(context, DISABLED); - addNodeWithDseVersion(context, Collections.singletonList(Version.parse("6.8.0"))); - - // when - boolean pagingEnabled = new GraphSupportChecker().isPagingEnabled(graphStatement, context); - - // then - assertThat(pagingEnabled).isEqualTo(false); - } - - @Test - public void - should_support_paging_when_statement_profile_not_present_but_context_profile_has_paging_enabled() { - // given - GraphStatement graphStatement = mock(GraphStatement.class); - InternalDriverContext context = protocolWithPagingSupport(true); - contextGraphPagingEnabled(context, ENABLED); - addNodeWithDseVersion(context, Collections.singletonList(Version.parse("6.8.0"))); - - // when - boolean pagingEnabled = new GraphSupportChecker().isPagingEnabled(graphStatement, context); - - // then - assertThat(pagingEnabled).isEqualTo(true); - } - - @DataProvider() - public static Object[][] graphPagingEnabledAndDseVersions() { - List listWithGraphPagingNode = Collections.singletonList(Version.parse("6.8.0")); - List listWithoutGraphPagingNode = Collections.singletonList(Version.parse("6.7.0")); - List listWithNull = Collections.singletonList(null); - List listWithTwoNodesOneNotSupporting = - Arrays.asList(Version.parse("6.7.0"), Version.parse("6.8.0")); - - return new Object[][] { - {false, ENABLED, ENABLED, listWithGraphPagingNode, true}, - {true, ENABLED, ENABLED, listWithoutGraphPagingNode, true}, - {true, ENABLED, DISABLED, listWithGraphPagingNode, true}, - {true, ENABLED, ENABLED, listWithGraphPagingNode, true}, - {true, ENABLED, ENABLED, listWithNull, true}, - {true, ENABLED, ENABLED, listWithTwoNodesOneNotSupporting, true}, - {true, DISABLED, ENABLED, listWithGraphPagingNode, false}, - {true, DISABLED, AUTO, listWithGraphPagingNode, false}, - {true, DISABLED, DISABLED, listWithGraphPagingNode, false}, - {true, AUTO, AUTO, listWithGraphPagingNode, true}, - {true, AUTO, DISABLED, listWithGraphPagingNode, true}, - {false, AUTO, AUTO, listWithGraphPagingNode, false}, - {true, AUTO, AUTO, listWithTwoNodesOneNotSupporting, false}, - {true, AUTO, AUTO, listWithNull, false}, - }; - } - - private void addNodeWithDseVersion(InternalDriverContext context, List dseVersions) { - MetadataManager manager = mock(MetadataManager.class); - when(context.getMetadataManager()).thenReturn(manager); - Metadata metadata = mock(Metadata.class); - when(manager.getMetadata()).thenReturn(metadata); - Map nodes = new HashMap<>(); - for (Version v : dseVersions) { - Node node = mock(Node.class); - Map extras = new HashMap<>(); - extras.put(DseNodeProperties.DSE_VERSION, v); - when(node.getExtras()).thenReturn(extras); - nodes.put(UUID.randomUUID(), node); - } - when(metadata.getNodes()).thenReturn(nodes); - } - - private void contextGraphPagingEnabled( - InternalDriverContext context, PagingEnabledOptions option) { - DriverExecutionProfile driverExecutionProfile = mock(DriverExecutionProfile.class); - when(driverExecutionProfile.getString(DseDriverOption.GRAPH_PAGING_ENABLED)) - .thenReturn(option.name()); - DriverConfig config = mock(DriverConfig.class); - when(context.getConfig()).thenReturn(config); - when(config.getDefaultProfile()).thenReturn(driverExecutionProfile); - } - - private InternalDriverContext protocolWithPagingSupport(boolean pagingSupport) { - InternalDriverContext context = mock(InternalDriverContext.class); - when(context.getProtocolVersion()).thenReturn(DseProtocolVersion.DSE_V2); - ProtocolVersionRegistry protocolVersionRegistry = mock(ProtocolVersionRegistry.class); - when(protocolVersionRegistry.supports( - DseProtocolVersion.DSE_V2, DseProtocolFeature.CONTINUOUS_PAGING)) - .thenReturn(pagingSupport); - when(context.getProtocolVersionRegistry()).thenReturn(protocolVersionRegistry); - return context; - } - - private void statementGraphPagingEnabled( - GraphStatement graphStatement, PagingEnabledOptions option) { - DriverExecutionProfile driverExecutionProfile = mock(DriverExecutionProfile.class); - when(driverExecutionProfile.getString(DseDriverOption.GRAPH_PAGING_ENABLED)) - .thenReturn(option.name()); - when(graphStatement.getExecutionProfile()).thenReturn(driverExecutionProfile); - } - - @Test - @UseDataProvider("dseVersionsAndGraphProtocols") - public void should_determine_default_graph_protocol_from_dse_version( - Version[] dseVersions, GraphProtocol expectedProtocol) { - // mock up the metadata for the context - // using 'true' here will treat null test Versions as no DSE_VERSION info in the metadata - DefaultDriverContext context = - mockNodesInMetadataWithVersions(mock(DefaultDriverContext.class), true, dseVersions); - GraphProtocol graphProtocol = new GraphSupportChecker().getDefaultGraphProtocol(context); - assertThat(graphProtocol).isEqualTo(expectedProtocol); - } - - @Test - @UseDataProvider("dseVersionsAndGraphProtocols") - public void should_determine_default_graph_protocol_from_dse_version_with_null_versions( - Version[] dseVersions, GraphProtocol expectedProtocol) { - // mock up the metadata for the context - // using 'false' here will treat null test Versions as explicit NULL info for DSE_VERSION - DefaultDriverContext context = - mockNodesInMetadataWithVersions(mock(DefaultDriverContext.class), false, dseVersions); - GraphProtocol graphProtocol = new GraphSupportChecker().getDefaultGraphProtocol(context); - assertThat(graphProtocol).isEqualTo(expectedProtocol); - } - - @DataProvider - public static Object[][] dseVersionsAndGraphProtocols() { - return new Object[][] { - {new Version[] {Version.parse("5.0.3")}, GraphProtocol.GRAPHSON_2_0}, - {new Version[] {Version.parse("6.0.1")}, GraphProtocol.GRAPHSON_2_0}, - {new Version[] {Version.parse("6.7.4")}, GraphProtocol.GRAPHSON_2_0}, - {new Version[] {Version.parse("6.8.0")}, GraphProtocol.GRAPH_BINARY_1_0}, - {new Version[] {Version.parse("7.0.0")}, GraphProtocol.GRAPH_BINARY_1_0}, - {new Version[] {Version.parse("5.0.3"), Version.parse("6.8.0")}, GraphProtocol.GRAPHSON_2_0}, - {new Version[] {Version.parse("6.7.4"), Version.parse("6.8.0")}, GraphProtocol.GRAPHSON_2_0}, - {new Version[] {Version.parse("6.8.0"), Version.parse("6.7.4")}, GraphProtocol.GRAPHSON_2_0}, - { - new Version[] {Version.parse("6.8.0"), Version.parse("7.0.0")}, - GraphProtocol.GRAPH_BINARY_1_0 - }, - {new Version[] {Version.parse("6.7.4"), Version.parse("6.7.4")}, GraphProtocol.GRAPHSON_2_0}, - { - new Version[] {Version.parse("6.8.0"), Version.parse("6.8.0")}, - GraphProtocol.GRAPH_BINARY_1_0 - }, - {null, GraphProtocol.GRAPHSON_2_0}, - {new Version[] {null}, GraphProtocol.GRAPHSON_2_0}, - {new Version[] {null, Version.parse("6.8.0")}, GraphProtocol.GRAPHSON_2_0}, - { - new Version[] {Version.parse("6.8.0"), Version.parse("7.0.0"), null}, - GraphProtocol.GRAPHSON_2_0 - }, - }; - } - - @Test - @UseDataProvider(location = DseTestDataProviders.class, value = "supportedGraphProtocols") - public void should_pickup_graph_protocol_from_statement(GraphProtocol graphProtocol) { - GraphStatement graphStatement = mock(GraphStatement.class); - DriverExecutionProfile executionProfile = mock(DriverExecutionProfile.class); - when(graphStatement.getSubProtocol()).thenReturn(graphProtocol.toInternalCode()); - - GraphProtocol inferredProtocol = - new GraphSupportChecker() - .inferGraphProtocol( - graphStatement, executionProfile, mock(InternalDriverContext.class)); - - assertThat(inferredProtocol).isEqualTo(graphProtocol); - verifyNoInteractions(executionProfile); - } - - @Test - @UseDataProvider("graphProtocolStringsAndDseVersions") - public void should_pickup_graph_protocol_and_parse_from_string_config( - String stringConfig, Version dseVersion) { - GraphStatement graphStatement = mock(GraphStatement.class); - DriverExecutionProfile executionProfile = mock(DriverExecutionProfile.class); - when(executionProfile.isDefined(DseDriverOption.GRAPH_SUB_PROTOCOL)).thenReturn(Boolean.TRUE); - when(executionProfile.getString(eq(DseDriverOption.GRAPH_SUB_PROTOCOL))) - .thenReturn(stringConfig); - - DefaultDriverContext context = - mockNodesInMetadataWithVersions(mock(DefaultDriverContext.class), true, dseVersion); - GraphProtocol inferredProtocol = - new GraphSupportChecker().inferGraphProtocol(graphStatement, executionProfile, context); - assertThat(inferredProtocol.toInternalCode()).isEqualTo(stringConfig); - } - - @DataProvider - public static Object[][] graphProtocolStringsAndDseVersions() { - // putting manual strings here to be sure to be notified if a value in - // GraphProtocol ever changes - return new Object[][] { - {"graphson-1.0", Version.parse("6.7.0")}, - {"graphson-1.0", Version.parse("6.8.0")}, - {"graphson-2.0", Version.parse("6.7.0")}, - {"graphson-2.0", Version.parse("6.8.0")}, - {"graph-binary-1.0", Version.parse("6.7.0")}, - {"graph-binary-1.0", Version.parse("6.8.0")}, - }; - } - - @Test - @UseDataProvider("dseVersions6") - public void should_use_correct_default_protocol_when_parsing(Version dseVersion) { - GraphStatement graphStatement = mock(GraphStatement.class); - DriverExecutionProfile executionProfile = mock(DriverExecutionProfile.class); - DefaultDriverContext context = - mockNodesInMetadataWithVersions(mock(DefaultDriverContext.class), true, dseVersion); - GraphProtocol inferredProtocol = - new GraphSupportChecker().inferGraphProtocol(graphStatement, executionProfile, context); - // For DSE 6.8 and newer, the default should be GraphSON binary - // for DSE older than 6.8, the default should be GraphSON2 - assertThat(inferredProtocol) - .isEqualTo( - (dseVersion.compareTo(Version.parse("6.8.0")) < 0) - ? GraphProtocol.GRAPHSON_2_0 - : GraphProtocol.GRAPH_BINARY_1_0); - } - - @DataProvider - public static Object[][] dseVersions6() { - return new Object[][] {{Version.parse("6.7.0")}, {Version.parse("6.8.0")}}; - } - - @Test - public void should_fail_if_graph_protocol_used_is_invalid() { - assertThatThrownBy(() -> GraphProtocol.fromString("invalid")) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage( - "Graph protocol used [\"invalid\"] unknown. Possible values are: [ \"graphson-1.0\", \"graphson-2.0\", \"graph-binary-1.0\"]"); - } - - @Test - public void should_fail_if_graph_protocol_used_is_graphson_3() { - assertThatThrownBy(() -> GraphProtocol.fromString("graphson-3.0")) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage( - "Graph protocol used [\"graphson-3.0\"] unknown. Possible values are: [ \"graphson-1.0\", \"graphson-2.0\", \"graph-binary-1.0\"]"); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/graph/GraphTestUtils.java b/core/src/test/java/com/datastax/dse/driver/internal/core/graph/GraphTestUtils.java deleted file mode 100644 index f58fc54d8c7..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/graph/GraphTestUtils.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.dse.driver.api.core.DseProtocolVersion; -import com.datastax.dse.driver.internal.core.graph.binary.GraphBinaryModule; -import com.datastax.dse.protocol.internal.response.result.DseRowsMetadata; -import com.datastax.oss.driver.internal.core.context.DefaultDriverContext; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import com.datastax.oss.protocol.internal.Frame; -import com.datastax.oss.protocol.internal.Message; -import com.datastax.oss.protocol.internal.ProtocolConstants; -import com.datastax.oss.protocol.internal.response.result.ColumnSpec; -import com.datastax.oss.protocol.internal.response.result.DefaultRows; -import com.datastax.oss.protocol.internal.response.result.RawType; -import com.datastax.oss.protocol.internal.response.result.Rows; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.ArrayDeque; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Queue; -import org.apache.tinkerpop.gremlin.process.remote.traversal.DefaultRemoteTraverser; -import org.apache.tinkerpop.gremlin.structure.Direction; -import org.apache.tinkerpop.gremlin.structure.T; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.apache.tinkerpop.gremlin.structure.io.Buffer; -import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryReader; -import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryWriter; -import org.apache.tinkerpop.gremlin.structure.io.binary.TypeSerializerRegistry; -import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertex; -import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertexProperty; -import org.assertj.core.api.InstanceOfAssertFactories; - -public class GraphTestUtils { - - public static ByteBuffer serialize( - Object value, GraphProtocol graphProtocol, GraphBinaryModule graphBinaryModule) - throws IOException { - - Buffer tinkerBuf = graphBinaryModule.serialize(value); - ByteBuffer nioBuffer = tinkerBuf.nioBuffer(); - tinkerBuf.release(); - return graphProtocol.isGraphBinary() - ? nioBuffer - : GraphSONUtils.serializeToByteBuffer(value, graphProtocol); - } - - public static Frame defaultDseFrameOf(Message responseMessage) { - return Frame.forResponse( - DseProtocolVersion.DSE_V2.getCode(), - 0, - null, - Frame.NO_PAYLOAD, - Collections.emptyList(), - responseMessage); - } - - public static Message singleGraphRow(GraphProtocol graphProtocol, GraphBinaryModule module) - throws IOException { - Vertex value = - DetachedVertex.build() - .setId(1) - .setLabel("person") - .addProperty( - DetachedVertexProperty.build() - .setId(11) - .setLabel("name") - .setValue("marko") - .create()) - .create(); - DseRowsMetadata metadata = - new DseRowsMetadata( - ImmutableList.of( - new ColumnSpec( - "ks", - "table", - "gremlin", - 0, - graphProtocol.isGraphBinary() - ? RawType.PRIMITIVES.get(ProtocolConstants.DataType.BLOB) - : RawType.PRIMITIVES.get(ProtocolConstants.DataType.VARCHAR))), - null, - new int[] {}, - null, - 1, - true); - Queue> data = new ArrayDeque<>(); - data.add( - ImmutableList.of( - serialize( - graphProtocol.isGraphBinary() - // GraphBinary returns results directly inside a Traverser - ? new DefaultRemoteTraverser<>(value, 1) - : ImmutableMap.of("result", value), - graphProtocol, - module))); - return new DefaultRows(metadata, data); - } - - // Returns 10 rows, each with a vertex - public static Rows tenGraphRows( - GraphProtocol graphProtocol, GraphBinaryModule module, int page, boolean last) - throws IOException { - DseRowsMetadata metadata = - new DseRowsMetadata( - ImmutableList.of( - new ColumnSpec( - "ks", - "table", - "gremlin", - 0, - graphProtocol.isGraphBinary() - ? RawType.PRIMITIVES.get(ProtocolConstants.DataType.BLOB) - : RawType.PRIMITIVES.get(ProtocolConstants.DataType.VARCHAR))), - null, - new int[] {}, - null, - page, - last); - Queue> data = new ArrayDeque<>(); - int start = (page - 1) * 10; - for (int i = start; i < start + 10; i++) { - Vertex v = - DetachedVertex.build() - .setId("vertex" + i) - .setLabel("person") - .addProperty( - DetachedVertexProperty.build() - .setId("property" + i) - .setLabel("name") - .setValue("user" + i) - .create()) - .create(); - data.add( - ImmutableList.of( - serialize( - graphProtocol.isGraphBinary() - // GraphBinary returns results directly inside a Traverser - ? new DefaultRemoteTraverser<>(v, 1) - : ImmutableMap.of("result", v), - graphProtocol, - module))); - } - return new DefaultRows(metadata, data); - } - - public static GraphBinaryModule createGraphBinaryModule(DefaultDriverContext context) { - TypeSerializerRegistry registry = GraphBinaryModule.createDseTypeSerializerRegistry(context); - return new GraphBinaryModule(new GraphBinaryReader(registry), new GraphBinaryWriter(registry)); - } - - public static void assertThatContainsProperties( - Map properties, Object... propsToMatch) { - for (int i = 0; i < propsToMatch.length; i += 2) { - assertThat(properties).containsEntry(propsToMatch[i], propsToMatch[i + 1]); - } - } - - public static void assertThatContainsLabel( - Map properties, Direction direction, String label) { - assertThat(properties) - .hasEntrySatisfying( - direction, - value -> - assertThat(value) - .asInstanceOf(InstanceOfAssertFactories.MAP) - .containsEntry(T.label, label)); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/graph/binary/GraphDataTypesTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/graph/binary/GraphDataTypesTest.java deleted file mode 100644 index e36f7e97e5a..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/graph/binary/GraphDataTypesTest.java +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph.binary; - -import static com.datastax.oss.driver.api.core.type.DataTypes.BIGINT; -import static com.datastax.oss.driver.api.core.type.DataTypes.DOUBLE; -import static com.datastax.oss.driver.api.core.type.DataTypes.DURATION; -import static com.datastax.oss.driver.api.core.type.DataTypes.FLOAT; -import static com.datastax.oss.driver.api.core.type.DataTypes.INT; -import static com.datastax.oss.driver.api.core.type.DataTypes.TEXT; -import static com.datastax.oss.driver.api.core.type.DataTypes.listOf; -import static com.datastax.oss.driver.api.core.type.DataTypes.mapOf; -import static com.datastax.oss.driver.api.core.type.DataTypes.setOf; -import static com.datastax.oss.driver.api.core.type.DataTypes.tupleOf; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.when; - -import com.datastax.dse.driver.api.core.DseProtocolVersion; -import com.datastax.dse.driver.api.core.data.geometry.LineString; -import com.datastax.dse.driver.api.core.data.geometry.Point; -import com.datastax.dse.driver.api.core.data.geometry.Polygon; -import com.datastax.dse.driver.api.core.graph.BatchGraphStatement; -import com.datastax.dse.driver.api.core.graph.DseGraph; -import com.datastax.dse.driver.api.core.graph.GraphNode; -import com.datastax.dse.driver.api.core.type.DseDataTypes; -import com.datastax.dse.driver.api.core.type.codec.DseTypeCodecs; -import com.datastax.dse.driver.internal.core.data.geometry.Distance; -import com.datastax.dse.driver.internal.core.graph.EditDistance; -import com.datastax.dse.driver.internal.core.graph.GraphConversions; -import com.datastax.dse.driver.internal.core.graph.GraphProtocol; -import com.datastax.dse.driver.internal.core.graph.GraphSONUtils; -import com.datastax.oss.driver.TestDataProviders; -import com.datastax.oss.driver.api.core.data.CqlDuration; -import com.datastax.oss.driver.api.core.type.DataTypes; -import com.datastax.oss.driver.api.core.type.TupleType; -import com.datastax.oss.driver.api.core.type.UserDefinedType; -import com.datastax.oss.driver.api.core.type.codec.registry.MutableCodecRegistry; -import com.datastax.oss.driver.internal.core.context.DefaultDriverContext; -import com.datastax.oss.driver.internal.core.type.UserDefinedTypeBuilder; -import com.datastax.oss.driver.internal.core.type.codec.registry.DefaultCodecRegistry; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableSet; -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import java.io.IOException; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.nio.ByteBuffer; -import java.time.Instant; -import java.time.LocalDate; -import java.time.LocalTime; -import java.time.ZoneOffset; -import java.util.List; -import java.util.Set; -import org.apache.tinkerpop.gremlin.structure.io.Buffer; -import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryReader; -import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryWriter; -import org.apache.tinkerpop.gremlin.structure.io.binary.TypeSerializerRegistry; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -@RunWith(DataProviderRunner.class) -public class GraphDataTypesTest { - - private GraphBinaryModule graphBinaryModule; - - @Mock private DefaultDriverContext context; - - private static final MutableCodecRegistry CODEC_REGISTRY = - new DefaultCodecRegistry("testDseRegistry"); - - static { - CODEC_REGISTRY.register(DseTypeCodecs.POINT, DseTypeCodecs.LINE_STRING, DseTypeCodecs.POLYGON); - } - - private static Object[][] graphsonOneDataTypes = - new Object[][] { - {"~’~^ää#123#ö"}, - {(byte) 34}, - {BigDecimal.TEN}, - {BigInteger.TEN}, - {Boolean.TRUE}, - {false}, - {23}, - {23L}, - {23.0d}, - {23f}, - {(short) 23}, - {LocalDate.now(ZoneOffset.UTC)}, - {LocalTime.now(ZoneOffset.UTC)}, - {java.util.UUID.randomUUID()}, - {Instant.now()}, - }; - - private static Object[][] graphsonTwoDataTypes = - new Object[][] { - {ImmutableList.of(1L, 2L, 3L)}, - {ImmutableSet.of(1L, 2L, 3L)}, - {ImmutableMap.of("a", 1, "b", 2)}, - {Point.fromCoordinates(3.3, 4.4)}, - { - LineString.fromPoints( - Point.fromCoordinates(1, 1), Point.fromCoordinates(2, 2), Point.fromCoordinates(3, 3)) - }, - { - Polygon.fromPoints( - Point.fromCoordinates(3, 4), Point.fromCoordinates(5, 4), Point.fromCoordinates(6, 6)) - }, - }; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - when(context.getCodecRegistry()).thenReturn(CODEC_REGISTRY); - when(context.getProtocolVersion()).thenReturn(DseProtocolVersion.DSE_V2); - - TypeSerializerRegistry registry = GraphBinaryModule.createDseTypeSerializerRegistry(context); - graphBinaryModule = - new GraphBinaryModule(new GraphBinaryReader(registry), new GraphBinaryWriter(registry)); - } - - @DataProvider - public static Object[][] graphsonOneDataProvider() { - - return graphsonOneDataTypes; - } - - @DataProvider - public static Object[][] graphsonTwoDataProvider() { - - return TestDataProviders.concat(graphsonOneDataTypes, graphsonTwoDataTypes); - } - - @DataProvider - public static Object[][] binaryDataProvider() throws UnknownHostException { - - Object[][] binaryDataTypes = - new Object[][] { - {InetAddress.getLocalHost()}, - {ImmutableList.of(ImmutableList.of(1L, 3L), ImmutableList.of(2L, 4L))}, - {ImmutableSet.of(ImmutableSet.of(1, 2, 3))}, - {ImmutableMap.of(ImmutableMap.of("a", 1), ImmutableMap.of(2, "b"))}, - {tupleOf(INT, TEXT, FLOAT).newValue(1, "2", 3.41f)}, - { - tupleOf(INT, TEXT, tupleOf(TEXT, DURATION)) - .newValue( - 1, "2", tupleOf(TEXT, DURATION).newValue("a", CqlDuration.newInstance(2, 1, 0))) - }, - { - tupleOf( - listOf(INT), - setOf(FLOAT), - DataTypes.mapOf(TEXT, BIGINT), - listOf(listOf(DOUBLE)), - setOf(setOf(FLOAT)), - listOf(tupleOf(INT, TEXT))) - .newValue( - ImmutableList.of(4, 8, 22, 34, 37, 59), - ImmutableSet.of(28f, 44f, 59f), - ImmutableMap.of("big10", 2345L), - ImmutableList.of( - ImmutableList.of(11.1d, 33.3d), ImmutableList.of(22.2d, 44.4d)), - ImmutableSet.of(ImmutableSet.of(55.5f)), - ImmutableList.of(tupleOf(INT, TEXT).newValue(3, "three"))) - }, - { - new UserDefinedTypeBuilder("ks", "udt1") - .withField("a", INT) - .withField("b", TEXT) - .build() - .newValue(1, "two") - }, - {new Distance(Point.fromCoordinates(3.4, 17.0), 2.5)}, - {new EditDistance("xyz", 3)}, - {DseGraph.g.V().has("name", "marko").asAdmin().getBytecode()}, - { - GraphConversions.bytecodeToSerialize( - BatchGraphStatement.builder() - .addTraversal(DseGraph.g.addV("person").property("name", "1")) - .addTraversal(DseGraph.g.addV("person").property("name", "1")) - .build()) - }, - }; - return TestDataProviders.concat(graphsonTwoDataProvider(), binaryDataTypes); - } - - @Test - @UseDataProvider("binaryDataProvider") - public void dataTypesTest(Object value) throws IOException { - verifySerDeBinary(value); - } - - @Test - @UseDataProvider("graphsonOneDataProvider") - public void dataTypesTestGraphsonOne(Object value) throws IOException { - verifySerDeGraphson(value, GraphProtocol.GRAPHSON_1_0); - } - - @Test - @UseDataProvider("graphsonTwoDataProvider") - public void dataTypesTestGraphsonTwo(Object value) throws IOException { - verifySerDeGraphson(value, GraphProtocol.GRAPHSON_2_0); - } - - @Test - public void complexUdtTests() throws IOException { - UserDefinedType type1 = - new UserDefinedTypeBuilder("ks", "udt1").withField("a", INT).withField("b", TEXT).build(); - verifySerDeBinary(type1.newValue(1, "2")); - - TupleType secondNested = tupleOf(BIGINT, listOf(BIGINT)); - TupleType firstNested = tupleOf(TEXT, secondNested); - - UserDefinedType type2 = - new UserDefinedTypeBuilder("ks", "udt2") - .withField("a", INT) - .withField("b", TEXT) - .withField("c", type1) - .withField("mylist", listOf(BIGINT)) - .withField("mytuple_withlist", firstNested) - .build(); - - verifySerDeBinary( - type2.newValue( - 1, - "2", - type1.newValue(3, "4"), - ImmutableList.of(5L), - firstNested.newValue("6", secondNested.newValue(7L, ImmutableList.of(8L))))); - - UserDefinedType type3 = - new UserDefinedTypeBuilder("ks", "udt3") - .withField("a", listOf(INT)) - .withField("b", setOf(FLOAT)) - .withField("c", mapOf(TEXT, BIGINT)) - .withField("d", listOf(listOf(DOUBLE))) - .withField("e", setOf(setOf(FLOAT))) - .withField("f", listOf(tupleOf(INT, TEXT))) - .build(); - - verifySerDeBinary( - type3.newValue( - ImmutableList.of(1), - ImmutableSet.of(2.1f), - ImmutableMap.of("3", 4L), - ImmutableList.of(ImmutableList.of(5.1d, 6.1d), ImmutableList.of(7.1d)), - ImmutableSet.of(ImmutableSet.of(8.1f), ImmutableSet.of(9.1f)), - ImmutableList.of(tupleOf(INT, TEXT).newValue(10, "11")))); - } - - @Test - public void complexTypesAndGeoTests() throws IOException { - - TupleType tuple = tupleOf(DseDataTypes.POINT, DseDataTypes.LINE_STRING, DseDataTypes.POLYGON); - tuple.attach(context); - - verifySerDeBinary( - tuple.newValue( - Point.fromCoordinates(3.3, 4.4), - LineString.fromPoints( - Point.fromCoordinates(1, 1), - Point.fromCoordinates(2, 2), - Point.fromCoordinates(3, 3)), - Polygon.fromPoints( - Point.fromCoordinates(3, 4), - Point.fromCoordinates(5, 4), - Point.fromCoordinates(6, 6)))); - - UserDefinedType udt = - new UserDefinedTypeBuilder("ks", "udt1") - .withField("a", DseDataTypes.POINT) - .withField("b", DseDataTypes.LINE_STRING) - .withField("c", DseDataTypes.POLYGON) - .build(); - udt.attach(context); - - verifySerDeBinary( - udt.newValue( - Point.fromCoordinates(3.3, 4.4), - LineString.fromPoints( - Point.fromCoordinates(1, 1), - Point.fromCoordinates(2, 2), - Point.fromCoordinates(3, 3)), - Polygon.fromPoints( - Point.fromCoordinates(3, 4), - Point.fromCoordinates(5, 4), - Point.fromCoordinates(6, 6)))); - } - - private void verifySerDeBinary(Object input) throws IOException { - Buffer result = graphBinaryModule.serialize(input); - Object deserialized = graphBinaryModule.deserialize(result); - result.release(); - assertThat(deserialized).isEqualTo(input); - } - - private void verifySerDeGraphson(Object input, GraphProtocol protocol) throws IOException { - ByteBuffer buffer = GraphSONUtils.serializeToByteBuffer(input, protocol); - Object deserialized = deserializeGraphson(buffer, protocol, input.getClass()); - - Object expected = (input instanceof Set) ? ImmutableList.copyOf((Set) input) : input; - assertThat(deserialized).isEqualTo(expected); - } - - private Object deserializeGraphson( - ByteBuffer buffer, GraphProtocol protocol, Class expectedClass) throws IOException { - List data = ImmutableList.of(buffer); - GraphNode node = GraphSONUtils.createGraphNode(data, protocol); - return node.as(expectedClass); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/graph/reactive/ReactiveGraphRequestProcessorTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/graph/reactive/ReactiveGraphRequestProcessorTest.java deleted file mode 100644 index 324c4ff4672..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/graph/reactive/ReactiveGraphRequestProcessorTest.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph.reactive; - -import static com.datastax.dse.driver.api.core.DseProtocolVersion.DSE_V1; -import static com.datastax.dse.driver.internal.core.graph.GraphTestUtils.createGraphBinaryModule; -import static com.datastax.dse.driver.internal.core.graph.GraphTestUtils.defaultDseFrameOf; -import static com.datastax.dse.driver.internal.core.graph.GraphTestUtils.tenGraphRows; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import com.datastax.dse.driver.DseTestDataProviders; -import com.datastax.dse.driver.api.core.DseProtocolVersion; -import com.datastax.dse.driver.api.core.graph.GraphStatement; -import com.datastax.dse.driver.api.core.graph.ScriptGraphStatement; -import com.datastax.dse.driver.api.core.graph.reactive.ReactiveGraphNode; -import com.datastax.dse.driver.api.core.graph.reactive.ReactiveGraphResultSet; -import com.datastax.dse.driver.internal.core.cql.continuous.ContinuousCqlRequestHandlerTestBase; -import com.datastax.dse.driver.internal.core.graph.GraphProtocol; -import com.datastax.dse.driver.internal.core.graph.GraphRequestAsyncProcessor; -import com.datastax.dse.driver.internal.core.graph.GraphRequestHandlerTestHarness; -import com.datastax.dse.driver.internal.core.graph.GraphSupportChecker; -import com.datastax.dse.driver.internal.core.graph.binary.GraphBinaryModule; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import com.datastax.oss.driver.internal.core.context.DefaultDriverContext; -import com.datastax.oss.driver.internal.core.cql.PoolBehavior; -import com.datastax.oss.driver.internal.core.session.DefaultSession; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import io.reactivex.Flowable; -import java.io.IOException; -import java.util.List; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mockito; - -public class ReactiveGraphRequestProcessorTest extends ContinuousCqlRequestHandlerTestBase { - - private GraphRequestAsyncProcessor asyncProcessor; - private GraphSupportChecker graphSupportChecker; - - @Before - public void setUp() { - DefaultDriverContext context = mock(DefaultDriverContext.class); - graphSupportChecker = mock(GraphSupportChecker.class); - asyncProcessor = Mockito.spy(new GraphRequestAsyncProcessor(context, graphSupportChecker)); - } - - @Test - public void should_be_able_to_process_graph_reactive_result_set() { - ReactiveGraphRequestProcessor processor = new ReactiveGraphRequestProcessor(asyncProcessor); - assertThat( - processor.canProcess( - ScriptGraphStatement.newInstance("g.V()"), - ReactiveGraphRequestProcessor.REACTIVE_GRAPH_RESULT_SET)) - .isTrue(); - } - - @Test - public void should_create_reactive_result_set() { - GraphRequestHandlerTestHarness.Builder builder = - GraphRequestHandlerTestHarness.builder().withProtocolVersion(DSE_V1); - try (GraphRequestHandlerTestHarness harness = builder.build()) { - ReactiveGraphRequestProcessor processor = new ReactiveGraphRequestProcessor(asyncProcessor); - GraphStatement graphStatement = ScriptGraphStatement.newInstance("g.V()"); - assertThat( - processor.process(graphStatement, harness.getSession(), harness.getContext(), "test")) - .isInstanceOf(DefaultReactiveGraphResultSet.class); - } - } - - @Test - @UseDataProvider( - value = "allDseProtocolVersionsAndSupportedGraphProtocols", - location = DseTestDataProviders.class) - public void should_complete_single_page_result( - DseProtocolVersion version, GraphProtocol graphProtocol) throws IOException { - when(graphSupportChecker.isPagingEnabled(any(), any())).thenReturn(false); - when(graphSupportChecker.inferGraphProtocol(any(), any(), any())).thenReturn(graphProtocol); - - GraphRequestHandlerTestHarness.Builder builder = - GraphRequestHandlerTestHarness.builder().withProtocolVersion(version); - PoolBehavior node1Behavior = builder.customBehavior(node1); - try (GraphRequestHandlerTestHarness harness = builder.build()) { - - DefaultSession session = harness.getSession(); - DefaultDriverContext context = harness.getContext(); - GraphStatement graphStatement = ScriptGraphStatement.newInstance("g.V()"); - - GraphBinaryModule graphBinaryModule = createGraphBinaryModule(context); - when(asyncProcessor.getGraphBinaryModule()).thenReturn(graphBinaryModule); - - ReactiveGraphResultSet publisher = - new ReactiveGraphRequestProcessor(asyncProcessor) - .process(graphStatement, session, context, "test"); - - Flowable rowsPublisher = Flowable.fromPublisher(publisher).cache(); - rowsPublisher.subscribe(); - - // emulate single page - node1Behavior.setResponseSuccess( - defaultDseFrameOf(tenGraphRows(graphProtocol, graphBinaryModule, 1, true))); - - List rows = rowsPublisher.toList().blockingGet(); - - assertThat(rows).hasSize(10); - checkResultSet(rows); - - Flowable execInfosFlowable = - Flowable.fromPublisher(publisher.getExecutionInfos()); - assertThat(execInfosFlowable.toList().blockingGet()) - .hasSize(1) - .containsExactly(rows.get(0).getExecutionInfo()); - } - } - - @Test - @UseDataProvider( - value = "allDseProtocolVersionsAndSupportedGraphProtocols", - location = DseTestDataProviders.class) - public void should_complete_multi_page_result( - DseProtocolVersion version, GraphProtocol graphProtocol) throws IOException { - when(graphSupportChecker.isPagingEnabled(any(), any())).thenReturn(true); - when(graphSupportChecker.inferGraphProtocol(any(), any(), any())).thenReturn(graphProtocol); - - GraphRequestHandlerTestHarness.Builder builder = - GraphRequestHandlerTestHarness.builder().withProtocolVersion(version); - PoolBehavior node1Behavior = builder.customBehavior(node1); - try (GraphRequestHandlerTestHarness harness = builder.build()) { - - DefaultSession session = harness.getSession(); - DefaultDriverContext context = harness.getContext(); - GraphStatement graphStatement = ScriptGraphStatement.newInstance("g.V()"); - - GraphBinaryModule graphBinaryModule = createGraphBinaryModule(context); - when(asyncProcessor.getGraphBinaryModule()).thenReturn(graphBinaryModule); - - ReactiveGraphResultSet publisher = - new ReactiveGraphRequestProcessor(asyncProcessor) - .process(graphStatement, session, context, "test"); - - Flowable rowsPublisher = Flowable.fromPublisher(publisher).cache(); - rowsPublisher.subscribe(); - - // emulate page 1 - node1Behavior.setResponseSuccess( - defaultDseFrameOf(tenGraphRows(graphProtocol, graphBinaryModule, 1, false))); - // emulate page 2 - node1Behavior.setResponseSuccess( - defaultDseFrameOf(tenGraphRows(graphProtocol, graphBinaryModule, 2, true))); - - List rows = rowsPublisher.toList().blockingGet(); - assertThat(rows).hasSize(20); - checkResultSet(rows); - - Flowable execInfosFlowable = - Flowable.fromPublisher(publisher.getExecutionInfos()); - assertThat(execInfosFlowable.toList().blockingGet()) - .hasSize(2) - .containsExactly(rows.get(0).getExecutionInfo(), rows.get(10).getExecutionInfo()); - } - } - - private void checkResultSet(List rows) { - for (ReactiveGraphNode row : rows) { - assertThat(row.isVertex()).isTrue(); - ExecutionInfo executionInfo = row.getExecutionInfo(); - assertThat(executionInfo.getCoordinator()).isEqualTo(node1); - assertThat(executionInfo.getErrors()).isEmpty(); - assertThat(executionInfo.getIncomingPayload()).isEmpty(); - assertThat(executionInfo.getSpeculativeExecutionCount()).isEqualTo(0); - assertThat(executionInfo.getSuccessfulExecutionIndex()).isEqualTo(0); - assertThat(executionInfo.getWarnings()).isEmpty(); - } - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/graph/schema/refresh/GraphSchemaRefreshTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/graph/schema/refresh/GraphSchemaRefreshTest.java deleted file mode 100644 index 0d05f129520..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/graph/schema/refresh/GraphSchemaRefreshTest.java +++ /dev/null @@ -1,418 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.graph.schema.refresh; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.when; - -import com.datastax.dse.driver.api.core.metadata.schema.DseEdgeMetadata; -import com.datastax.dse.driver.api.core.metadata.schema.DseGraphTableMetadata; -import com.datastax.dse.driver.api.core.metadata.schema.DseVertexMetadata; -import com.datastax.dse.driver.internal.core.metadata.schema.DefaultDseEdgeMetadata; -import com.datastax.dse.driver.internal.core.metadata.schema.DefaultDseKeyspaceMetadata; -import com.datastax.dse.driver.internal.core.metadata.schema.DefaultDseTableMetadata; -import com.datastax.dse.driver.internal.core.metadata.schema.DefaultDseVertexMetadata; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.metadata.schema.ColumnMetadata; -import com.datastax.oss.driver.api.core.metadata.schema.TableMetadata; -import com.datastax.oss.driver.api.core.type.DataTypes; -import com.datastax.oss.driver.internal.core.channel.ChannelFactory; -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import com.datastax.oss.driver.internal.core.metadata.DefaultMetadata; -import com.datastax.oss.driver.internal.core.metadata.MetadataRefresh; -import com.datastax.oss.driver.internal.core.metadata.schema.DefaultColumnMetadata; -import com.datastax.oss.driver.internal.core.metadata.schema.events.KeyspaceChangeEvent; -import com.datastax.oss.driver.internal.core.metadata.schema.events.TableChangeEvent; -import com.datastax.oss.driver.internal.core.metadata.schema.refresh.SchemaRefresh; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.util.Collections; -import java.util.Map; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; - -@RunWith(MockitoJUnitRunner.class) -public class GraphSchemaRefreshTest { - - private static final DefaultDseTableMetadata OLD_TABLE = - newTable( - CqlIdentifier.fromInternal("ks_with_engine"), - CqlIdentifier.fromInternal("tbl"), - null, - null); - private static final DefaultDseKeyspaceMetadata OLD_KS1 = newKeyspace("ks1", null); - private static final DefaultDseKeyspaceMetadata KS_WITH_ENGINE = - newKeyspace( - CqlIdentifier.fromInternal("ks_with_engine"), - "Core", - ImmutableMap.of(CqlIdentifier.fromInternal("tbl"), OLD_TABLE)); - - @Mock private InternalDriverContext context; - @Mock private ChannelFactory channelFactory; - private DefaultMetadata oldMetadata; - - @Before - public void setup() { - when(context.getChannelFactory()).thenReturn(channelFactory); - oldMetadata = - DefaultMetadata.EMPTY.withSchema( - ImmutableMap.of(OLD_KS1.getName(), OLD_KS1, KS_WITH_ENGINE.getName(), KS_WITH_ENGINE), - false, - context); - } - - @Test - public void should_detect_created_keyspace_without_graph_engine() { - DefaultDseKeyspaceMetadata ks2 = newKeyspace("ks2", null); - SchemaRefresh refresh = - new SchemaRefresh( - ImmutableMap.of( - OLD_KS1.getName(), - OLD_KS1, - KS_WITH_ENGINE.getName(), - KS_WITH_ENGINE, - ks2.getName(), - ks2)); - MetadataRefresh.Result result = refresh.compute(oldMetadata, false, context); - assertThat(result.newMetadata.getKeyspaces()).hasSize(3); - assertThat(result.events).containsExactly(KeyspaceChangeEvent.created(ks2)); - } - - @Test - public void should_detect_created_keyspace_with_graph_engine() { - DefaultDseKeyspaceMetadata ks2 = newKeyspace("ks2", "Core"); - SchemaRefresh refresh = - new SchemaRefresh( - ImmutableMap.of( - OLD_KS1.getName(), - OLD_KS1, - KS_WITH_ENGINE.getName(), - KS_WITH_ENGINE, - ks2.getName(), - ks2)); - MetadataRefresh.Result result = refresh.compute(oldMetadata, false, context); - assertThat(result.newMetadata.getKeyspaces()).hasSize(3); - assertThat(result.events).containsExactly(KeyspaceChangeEvent.created(ks2)); - } - - @Test - public void should_detect_top_level_graph_engine_update_in_keyspace() { - // Change only one top-level option (graph_engine) - DefaultDseKeyspaceMetadata newKs1 = newKeyspace("ks1", "Core"); - SchemaRefresh refresh = - new SchemaRefresh( - ImmutableMap.of(KS_WITH_ENGINE.getName(), KS_WITH_ENGINE, OLD_KS1.getName(), newKs1)); - MetadataRefresh.Result result = refresh.compute(oldMetadata, false, context); - assertThat(result.newMetadata.getKeyspaces()).hasSize(2); - assertThat(result.events).containsExactly(KeyspaceChangeEvent.updated(OLD_KS1, newKs1)); - } - - @Test - public void should_detect_adding_and_renaming_and_removing_vertex_label() { - DefaultDseTableMetadata newTable = - newTable( - KS_WITH_ENGINE.getName(), - CqlIdentifier.fromInternal("tbl"), - new DefaultDseVertexMetadata(CqlIdentifier.fromInternal("someLabel")), - null); - DefaultDseKeyspaceMetadata ks = - newKeyspace( - KS_WITH_ENGINE.getName(), - "Core", - ImmutableMap.of(CqlIdentifier.fromInternal("tbl"), newTable)); - SchemaRefresh refresh = - new SchemaRefresh( - ImmutableMap.of(KS_WITH_ENGINE.getName(), ks, OLD_KS1.getName(), OLD_KS1)); - MetadataRefresh.Result result = refresh.compute(oldMetadata, false, context); - assertThat(result.newMetadata.getKeyspaces()).hasSize(2); - assertThat(result.events).containsExactly(TableChangeEvent.updated(OLD_TABLE, newTable)); - assertThat(result.newMetadata.getKeyspaces().get(KS_WITH_ENGINE.getName())).isNotNull(); - assertThat( - ((DseGraphTableMetadata) - result - .newMetadata - .getKeyspaces() - .get(KS_WITH_ENGINE.getName()) - .getTable("tbl") - .get()) - .getVertex()) - .isNotNull(); - assertThat( - ((DseGraphTableMetadata) - result - .newMetadata - .getKeyspaces() - .get(KS_WITH_ENGINE.getName()) - .getTable("tbl") - .get()) - .getVertex() - .get() - .getLabelName() - .asInternal()) - .isEqualTo("someLabel"); - - // now rename the vertex label - newTable = - newTable( - KS_WITH_ENGINE.getName(), - CqlIdentifier.fromInternal("tbl"), - new DefaultDseVertexMetadata(CqlIdentifier.fromInternal("someNewLabel")), - null); - ks = - newKeyspace( - KS_WITH_ENGINE.getName(), - "Core", - ImmutableMap.of(CqlIdentifier.fromInternal("tbl"), newTable)); - refresh = - new SchemaRefresh( - ImmutableMap.of(KS_WITH_ENGINE.getName(), ks, OLD_KS1.getName(), OLD_KS1)); - result = refresh.compute(oldMetadata, false, context); - assertThat(result.newMetadata.getKeyspaces()).hasSize(2); - assertThat(result.events).containsExactly(TableChangeEvent.updated(OLD_TABLE, newTable)); - assertThat( - ((DseGraphTableMetadata) - result - .newMetadata - .getKeyspaces() - .get(KS_WITH_ENGINE.getName()) - .getTable("tbl") - .get()) - .getVertex() - .get() - .getLabelName() - .asInternal()) - .isEqualTo("someNewLabel"); - - // now remove the vertex label from the table - DefaultMetadata metadataWithVertexLabel = result.newMetadata; - DefaultDseTableMetadata tableWithRemovedLabel = - newTable(KS_WITH_ENGINE.getName(), CqlIdentifier.fromInternal("tbl"), null, null); - ks = - newKeyspace( - KS_WITH_ENGINE.getName(), - "Core", - ImmutableMap.of(CqlIdentifier.fromInternal("tbl"), tableWithRemovedLabel)); - refresh = - new SchemaRefresh( - ImmutableMap.of(KS_WITH_ENGINE.getName(), ks, OLD_KS1.getName(), OLD_KS1)); - result = refresh.compute(metadataWithVertexLabel, false, context); - assertThat(result.newMetadata.getKeyspaces()).hasSize(2); - assertThat(result.events) - .containsExactly(TableChangeEvent.updated(newTable, tableWithRemovedLabel)); - assertThat( - ((DseGraphTableMetadata) - result - .newMetadata - .getKeyspaces() - .get(KS_WITH_ENGINE.getName()) - .getTable("tbl") - .get()) - .getVertex() - .isPresent()) - .isFalse(); - } - - @Test - public void should_detect_adding_and_renaming_and_removing_edge_label() { - DefaultDseTableMetadata newTable = - newTable( - KS_WITH_ENGINE.getName(), - CqlIdentifier.fromInternal("tbl"), - null, - newEdgeMetadata( - CqlIdentifier.fromInternal("created"), - CqlIdentifier.fromInternal("person"), - CqlIdentifier.fromInternal("software"))); - DefaultDseKeyspaceMetadata ks = - newKeyspace( - KS_WITH_ENGINE.getName(), - "Core", - ImmutableMap.of(CqlIdentifier.fromInternal("tbl"), newTable)); - SchemaRefresh refresh = - new SchemaRefresh( - ImmutableMap.of(KS_WITH_ENGINE.getName(), ks, OLD_KS1.getName(), OLD_KS1)); - MetadataRefresh.Result result = refresh.compute(oldMetadata, false, context); - assertThat(result.newMetadata.getKeyspaces()).hasSize(2); - assertThat(result.events).containsExactly(TableChangeEvent.updated(OLD_TABLE, newTable)); - assertThat(result.newMetadata.getKeyspaces().get(KS_WITH_ENGINE.getName())).isNotNull(); - assertThat( - ((DseGraphTableMetadata) - result - .newMetadata - .getKeyspaces() - .get(KS_WITH_ENGINE.getName()) - .getTable("tbl") - .get()) - .getVertex()) - .isNotNull(); - assertThat( - ((DseGraphTableMetadata) - result - .newMetadata - .getKeyspaces() - .get(KS_WITH_ENGINE.getName()) - .getTable("tbl") - .get()) - .getEdge() - .get() - .getLabelName() - .asInternal()) - .isEqualTo("created"); - - // now rename the edge label - newTable = - newTable( - KS_WITH_ENGINE.getName(), - CqlIdentifier.fromInternal("tbl"), - null, - newEdgeMetadata( - CqlIdentifier.fromInternal("CHANGED"), - CqlIdentifier.fromInternal("person"), - CqlIdentifier.fromInternal("software"))); - ks = - newKeyspace( - KS_WITH_ENGINE.getName(), - "Core", - ImmutableMap.of(CqlIdentifier.fromInternal("tbl"), newTable)); - refresh = - new SchemaRefresh( - ImmutableMap.of(KS_WITH_ENGINE.getName(), ks, OLD_KS1.getName(), OLD_KS1)); - result = refresh.compute(oldMetadata, false, context); - assertThat(result.newMetadata.getKeyspaces()).hasSize(2); - assertThat(result.events).containsExactly(TableChangeEvent.updated(OLD_TABLE, newTable)); - assertThat( - ((DseGraphTableMetadata) - result - .newMetadata - .getKeyspaces() - .get(KS_WITH_ENGINE.getName()) - .getTable("tbl") - .get()) - .getEdge() - .get() - .getLabelName() - .asInternal()) - .isEqualTo("CHANGED"); - - // now remove the edge label from the table - DefaultMetadata metadataWithEdgeLabel = result.newMetadata; - DefaultDseTableMetadata tableWithRemovedLabel = - newTable(KS_WITH_ENGINE.getName(), CqlIdentifier.fromInternal("tbl"), null, null); - ks = - newKeyspace( - KS_WITH_ENGINE.getName(), - "Core", - ImmutableMap.of(CqlIdentifier.fromInternal("tbl"), tableWithRemovedLabel)); - refresh = - new SchemaRefresh( - ImmutableMap.of(KS_WITH_ENGINE.getName(), ks, OLD_KS1.getName(), OLD_KS1)); - result = refresh.compute(metadataWithEdgeLabel, false, context); - assertThat(result.newMetadata.getKeyspaces()).hasSize(2); - assertThat(result.events) - .containsExactly(TableChangeEvent.updated(newTable, tableWithRemovedLabel)); - assertThat( - ((DseGraphTableMetadata) - result - .newMetadata - .getKeyspaces() - .get(KS_WITH_ENGINE.getName()) - .getTable("tbl") - .get()) - .getEdge() - .isPresent()) - .isFalse(); - } - - private static DefaultDseKeyspaceMetadata newKeyspace(String name, String graphEngine) { - return new DefaultDseKeyspaceMetadata( - CqlIdentifier.fromInternal(name), - false, - false, - graphEngine, - Collections.emptyMap(), - Collections.emptyMap(), - Collections.emptyMap(), - Collections.emptyMap(), - Collections.emptyMap(), - Collections.emptyMap()); - } - - private static DefaultDseKeyspaceMetadata newKeyspace( - CqlIdentifier name, String graphEngine, @NonNull Map tables) { - return new DefaultDseKeyspaceMetadata( - name, - false, - false, - graphEngine, - Collections.emptyMap(), - Collections.emptyMap(), - tables, - Collections.emptyMap(), - Collections.emptyMap(), - Collections.emptyMap()); - } - - private static DefaultDseTableMetadata newTable( - @NonNull CqlIdentifier keyspace, - @NonNull CqlIdentifier name, - @Nullable DseVertexMetadata vertex, - @Nullable DseEdgeMetadata edge) { - ImmutableList cols = - ImmutableList.of( - new DefaultColumnMetadata( - keyspace, - CqlIdentifier.fromInternal("parent"), - CqlIdentifier.fromInternal("id"), - DataTypes.INT, - false)); - return new DefaultDseTableMetadata( - keyspace, - name, - null, - false, - false, - cols, - Collections.emptyMap(), - Collections.emptyMap(), - Collections.emptyMap(), - Collections.emptyMap(), - vertex, - edge); - } - - private static DefaultDseEdgeMetadata newEdgeMetadata( - @NonNull CqlIdentifier labelName, - @NonNull CqlIdentifier fromTable, - @NonNull CqlIdentifier toTable) { - return new DefaultDseEdgeMetadata( - labelName, - fromTable, - fromTable, - Collections.emptyList(), - Collections.emptyList(), - toTable, - toTable, - Collections.emptyList(), - Collections.emptyList()); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/insights/AddressFormatterTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/insights/AddressFormatterTest.java deleted file mode 100644 index 85af9b5691b..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/insights/AddressFormatterTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.UnknownHostException; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(DataProviderRunner.class) -public class AddressFormatterTest { - - @Test - @UseDataProvider("addressesProvider") - public void should_format_addresses(Object address, String expected) { - // when - String result = AddressFormatter.nullSafeToString(address); - - // then - assertThat(result).isEqualTo(expected); - } - - @DataProvider - public static Object[][] addressesProvider() throws UnknownHostException { - return new Object[][] { - {new InetSocketAddress(8888), "0.0.0.0:8888"}, - {new InetSocketAddress("127.0.0.1", 8888), "127.0.0.1:8888"}, - {InetSocketAddress.createUnresolved("127.0.0.2", 8080), "127.0.0.2:8080"}, - {InetAddress.getByName("127.0.0.1"), "127.0.0.1"}, - }; - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/insights/ConfigAntiPatternsFinderTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/insights/ConfigAntiPatternsFinderTest.java deleted file mode 100644 index d5466b23dbc..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/insights/ConfigAntiPatternsFinderTest.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights; - -import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.SSL_ENGINE_FACTORY_CLASS; -import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.SSL_HOSTNAME_VALIDATION; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import com.datastax.oss.driver.api.core.config.DriverConfig; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import java.util.Collections; -import java.util.Map; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(DataProviderRunner.class) -public class ConfigAntiPatternsFinderTest { - - private static final ImmutableMap SSL_ANTI_PATTERN = - ImmutableMap.of( - "sslWithoutCertValidation", - "Client-to-node encryption is enabled but server certificate validation is disabled"); - - @Test - @UseDataProvider("sslConfigProvider") - public void should_find_ssl_anti_pattern( - boolean sslEngineFactoryClassDefined, - boolean hostnameValidation, - Map expected) { - // given - InternalDriverContext context = - mockDefaultProfile(sslEngineFactoryClassDefined, hostnameValidation); - - // when - Map antiPatterns = new ConfigAntiPatternsFinder().findAntiPatterns(context); - - // then - assertThat(antiPatterns).isEqualTo(expected); - } - - private InternalDriverContext mockDefaultProfile( - boolean sslEngineFactoryClassDefined, boolean hostnameValidation) { - InternalDriverContext context = mock(InternalDriverContext.class); - DriverConfig driverConfig = mock(DriverConfig.class); - when(context.getConfig()).thenReturn(driverConfig); - DriverExecutionProfile profile = mock(DriverExecutionProfile.class); - when(profile.isDefined(SSL_ENGINE_FACTORY_CLASS)).thenReturn(sslEngineFactoryClassDefined); - when(profile.getBoolean(SSL_HOSTNAME_VALIDATION, false)).thenReturn(hostnameValidation); - when(driverConfig.getDefaultProfile()).thenReturn(profile); - return context; - } - - @DataProvider - public static Object[][] sslConfigProvider() { - return new Object[][] { - {true, true, Collections.emptyMap()}, - {true, false, SSL_ANTI_PATTERN}, - {false, false, Collections.emptyMap()}, - {false, true, Collections.emptyMap()} - }; - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/insights/DataCentersFinderTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/insights/DataCentersFinderTest.java deleted file mode 100644 index dde6db6059e..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/insights/DataCentersFinderTest.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights; - -import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.CONNECTION_POOL_REMOTE_SIZE; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.loadbalancing.NodeDistance; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableSet; -import com.datastax.oss.driver.shaded.guava.common.collect.Sets; -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import java.util.Collection; -import java.util.Set; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(DataProviderRunner.class) -public class DataCentersFinderTest { - - @Test - @UseDataProvider("hostProvider") - public void should_detect_data_centers( - int numberOfRemoteHosts, - String dc1, - NodeDistance h1Distance, - String dc2, - NodeDistance h2Distance, - Set expected) { - // given - DriverExecutionProfile executionProfile = mock(DriverExecutionProfile.class); - when(executionProfile.getInt(CONNECTION_POOL_REMOTE_SIZE)).thenReturn(numberOfRemoteHosts); - Collection nodes = mockNodes(dc1, h1Distance, dc2, h2Distance); - - // when - Set dataCenters = new DataCentersFinder().getDataCenters(nodes, executionProfile); - - // then - assertThat(dataCenters).isEqualTo(Sets.newHashSet(expected)); - } - - @DataProvider - public static Object[][] hostProvider() { - return new Object[][] { - {1, "dc1", NodeDistance.LOCAL, "dc2", NodeDistance.REMOTE, Sets.newHashSet("dc1", "dc2")}, - {1, "dc1", NodeDistance.LOCAL, "dc1", NodeDistance.REMOTE, Sets.newHashSet("dc1")}, - {0, "dc1", NodeDistance.LOCAL, "dc2", NodeDistance.REMOTE, Sets.newHashSet("dc1")}, - {0, "dc1", NodeDistance.IGNORED, "dc2", NodeDistance.REMOTE, Sets.newHashSet()}, - {1, "dc1", NodeDistance.IGNORED, "dc2", NodeDistance.REMOTE, Sets.newHashSet("dc2")}, - {1, "dc1", NodeDistance.LOCAL, "dc2", NodeDistance.IGNORED, Sets.newHashSet("dc1")}, - {0, "dc1", NodeDistance.IGNORED, "dc2", NodeDistance.REMOTE, Sets.newHashSet()}, - {0, "dc1", NodeDistance.LOCAL, "dc2", NodeDistance.IGNORED, Sets.newHashSet("dc1")}, - }; - } - - private Collection mockNodes( - String dc1, NodeDistance h1Distance, String dc2, NodeDistance h2Distance) { - Node n1 = mock(Node.class); - when(n1.getDatacenter()).thenReturn(dc1); - when(n1.getDistance()).thenReturn(h1Distance); - - Node n2 = mock(Node.class); - when(n2.getDatacenter()).thenReturn(dc2); - when(n2.getDistance()).thenReturn(h2Distance); - - return ImmutableSet.of(n1, n2); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/insights/ExecutionProfileMockUtil.java b/core/src/test/java/com/datastax/dse/driver/internal/core/insights/ExecutionProfileMockUtil.java deleted file mode 100644 index de0f3a9d60b..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/insights/ExecutionProfileMockUtil.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights; - -import static com.datastax.dse.driver.api.core.config.DseDriverOption.GRAPH_TRAVERSAL_SOURCE; -import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.AUTH_PROVIDER_CLASS; -import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.CONNECTION_POOL_LOCAL_SIZE; -import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.CONNECTION_POOL_REMOTE_SIZE; -import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.HEARTBEAT_INTERVAL; -import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.LOAD_BALANCING_DISTANCE_EVALUATOR_CLASS; -import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.LOAD_BALANCING_LOCAL_DATACENTER; -import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.LOAD_BALANCING_POLICY_CLASS; -import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.PROTOCOL_COMPRESSION; -import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.RECONNECTION_BASE_DELAY; -import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.REQUEST_CONSISTENCY; -import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.REQUEST_SERIAL_CONSISTENCY; -import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.REQUEST_TIMEOUT; -import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.SPECULATIVE_EXECUTION_DELAY; -import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.SPECULATIVE_EXECUTION_MAX; -import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.SPECULATIVE_EXECUTION_POLICY_CLASS; -import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.SSL_ENGINE_FACTORY_CLASS; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import java.time.Duration; - -class ExecutionProfileMockUtil { - static final String DEFAULT_LOCAL_DC = "local-dc"; - static final int SPECEX_MAX_DEFAULT = 100; - static final int SPECEX_DELAY_DEFAULT = 20; - - static DriverExecutionProfile mockDefaultExecutionProfile() { - DriverExecutionProfile profile = mock(DriverExecutionProfile.class); - - when(profile.getDuration(REQUEST_TIMEOUT)).thenReturn(Duration.ofMillis(100)); - when(profile.getString(LOAD_BALANCING_POLICY_CLASS)).thenReturn("LoadBalancingPolicyImpl"); - when(profile.isDefined(LOAD_BALANCING_DISTANCE_EVALUATOR_CLASS)).thenReturn(true); - when(profile.isDefined(LOAD_BALANCING_LOCAL_DATACENTER)).thenReturn(true); - when(profile.getString(LOAD_BALANCING_LOCAL_DATACENTER)).thenReturn(DEFAULT_LOCAL_DC); - when(profile.isDefined(SPECULATIVE_EXECUTION_MAX)).thenReturn(true); - when(profile.getInt(SPECULATIVE_EXECUTION_MAX)).thenReturn(SPECEX_MAX_DEFAULT); - when(profile.isDefined(SPECULATIVE_EXECUTION_DELAY)).thenReturn(true); - when(profile.getInt(SPECULATIVE_EXECUTION_DELAY)).thenReturn(SPECEX_DELAY_DEFAULT); - when(profile.getString(SPECULATIVE_EXECUTION_POLICY_CLASS)) - .thenReturn("SpeculativeExecutionImpl"); - when(profile.getString(REQUEST_CONSISTENCY)).thenReturn("LOCAL_ONE"); - when(profile.getString(REQUEST_SERIAL_CONSISTENCY)).thenReturn("SERIAL"); - when(profile.getInt(CONNECTION_POOL_LOCAL_SIZE)).thenReturn(2); - when(profile.getInt(CONNECTION_POOL_REMOTE_SIZE)).thenReturn(1); - when(profile.getString(eq(PROTOCOL_COMPRESSION), any())).thenReturn("none"); - when(profile.getDuration(HEARTBEAT_INTERVAL)).thenReturn(Duration.ofMillis(100)); - when(profile.getDuration(RECONNECTION_BASE_DELAY)).thenReturn(Duration.ofMillis(100)); - when(profile.isDefined(SSL_ENGINE_FACTORY_CLASS)).thenReturn(true); - when(profile.getString(eq(AUTH_PROVIDER_CLASS), any())).thenReturn("AuthProviderImpl"); - when(profile.getString(GRAPH_TRAVERSAL_SOURCE, null)).thenReturn("src-graph"); - return profile; - } - - static DriverExecutionProfile mockNonDefaultRequestTimeoutExecutionProfile() { - DriverExecutionProfile profile = mockDefaultExecutionProfile(); - when(profile.getDuration(REQUEST_TIMEOUT)).thenReturn(Duration.ofMillis(50)); - return profile; - } - - static DriverExecutionProfile mockNonDefaultLoadBalancingExecutionProfile() { - DriverExecutionProfile profile = mockDefaultExecutionProfile(); - when(profile.getString(LOAD_BALANCING_POLICY_CLASS)).thenReturn("NonDefaultLoadBalancing"); - return profile; - } - - static DriverExecutionProfile mockUndefinedLocalDcExecutionProfile() { - DriverExecutionProfile profile = mockNonDefaultLoadBalancingExecutionProfile(); - when(profile.isDefined(LOAD_BALANCING_LOCAL_DATACENTER)).thenReturn(false); - return profile; - } - - static DriverExecutionProfile mockNonDefaultSpeculativeExecutionInfo() { - DriverExecutionProfile profile = mockDefaultExecutionProfile(); - when(profile.getString(SPECULATIVE_EXECUTION_POLICY_CLASS)) - .thenReturn("NonDefaultSpecexPolicy"); - return profile; - } - - static DriverExecutionProfile mockNonDefaultConsistency() { - DriverExecutionProfile profile = mockDefaultExecutionProfile(); - when(profile.getString(REQUEST_CONSISTENCY)).thenReturn("ALL"); - return profile; - } - - static DriverExecutionProfile mockNonDefaultSerialConsistency() { - DriverExecutionProfile profile = mockDefaultExecutionProfile(); - when(profile.getString(REQUEST_SERIAL_CONSISTENCY)).thenReturn("ONE"); - return profile; - } - - static DriverExecutionProfile mockNonDefaultGraphOptions() { - DriverExecutionProfile profile = mockDefaultExecutionProfile(); - when(profile.getString(GRAPH_TRAVERSAL_SOURCE, null)).thenReturn("non-default-graph"); - return profile; - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/insights/ExecutionProfilesInfoFinderTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/insights/ExecutionProfilesInfoFinderTest.java deleted file mode 100644 index fc92ab20521..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/insights/ExecutionProfilesInfoFinderTest.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights; - -import static com.datastax.dse.driver.internal.core.insights.ExecutionProfileMockUtil.DEFAULT_LOCAL_DC; -import static com.datastax.dse.driver.internal.core.insights.ExecutionProfileMockUtil.SPECEX_DELAY_DEFAULT; -import static com.datastax.dse.driver.internal.core.insights.ExecutionProfileMockUtil.SPECEX_MAX_DEFAULT; -import static com.datastax.dse.driver.internal.core.insights.ExecutionProfileMockUtil.mockDefaultExecutionProfile; -import static com.datastax.dse.driver.internal.core.insights.ExecutionProfileMockUtil.mockNonDefaultConsistency; -import static com.datastax.dse.driver.internal.core.insights.ExecutionProfileMockUtil.mockNonDefaultGraphOptions; -import static com.datastax.dse.driver.internal.core.insights.ExecutionProfileMockUtil.mockNonDefaultLoadBalancingExecutionProfile; -import static com.datastax.dse.driver.internal.core.insights.ExecutionProfileMockUtil.mockNonDefaultRequestTimeoutExecutionProfile; -import static com.datastax.dse.driver.internal.core.insights.ExecutionProfileMockUtil.mockNonDefaultSerialConsistency; -import static com.datastax.dse.driver.internal.core.insights.ExecutionProfileMockUtil.mockNonDefaultSpeculativeExecutionInfo; -import static com.datastax.dse.driver.internal.core.insights.ExecutionProfileMockUtil.mockUndefinedLocalDcExecutionProfile; -import static com.datastax.dse.driver.internal.core.insights.PackageUtil.DEFAULT_LOAD_BALANCING_PACKAGE; -import static com.datastax.dse.driver.internal.core.insights.PackageUtil.DEFAULT_SPECULATIVE_EXECUTION_PACKAGE; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import com.datastax.dse.driver.internal.core.insights.schema.LoadBalancingInfo; -import com.datastax.dse.driver.internal.core.insights.schema.SpecificExecutionProfile; -import com.datastax.dse.driver.internal.core.insights.schema.SpeculativeExecutionInfo; -import com.datastax.oss.driver.api.core.config.DriverConfig; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import java.util.Map; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; - -@RunWith(DataProviderRunner.class) -public class ExecutionProfilesInfoFinderTest { - - @Test - public void should_include_info_about_default_profile() { - // given - DriverExecutionProfile defaultExecutionProfile = mockDefaultExecutionProfile(); - Map profiles = - ImmutableMap.of("default", defaultExecutionProfile); - - InternalDriverContext context = - mockDriverContextWithProfiles(defaultExecutionProfile, profiles); - - // when - Map executionProfilesInfo = - new ExecutionProfilesInfoFinder().getExecutionProfilesInfo(context); - - // then - assertThat(executionProfilesInfo) - .isEqualTo( - ImmutableMap.of( - "default", - new SpecificExecutionProfile( - 100, - new LoadBalancingInfo( - "LoadBalancingPolicyImpl", - ImmutableMap.of("localDataCenter", "local-dc", "filterFunction", true), - DEFAULT_LOAD_BALANCING_PACKAGE), - new SpeculativeExecutionInfo( - "SpeculativeExecutionImpl", - ImmutableMap.of("maxSpeculativeExecutions", 100, "delay", 20), - DEFAULT_SPECULATIVE_EXECUTION_PACKAGE), - "LOCAL_ONE", - "SERIAL", - ImmutableMap.of("source", "src-graph")))); - } - - @Test - @UseDataProvider("executionProfileProvider") - public void should_include_info_about_default_profile_and_only_difference_for_specific_profile( - DriverExecutionProfile nonDefaultExecutionProfile, SpecificExecutionProfile expected) { - // given - - DriverExecutionProfile defaultExecutionProfile = mockDefaultExecutionProfile(); - Map profiles = - ImmutableMap.of( - "default", defaultExecutionProfile, "non-default", nonDefaultExecutionProfile); - InternalDriverContext context = - mockDriverContextWithProfiles(defaultExecutionProfile, profiles); - // when - Map executionProfilesInfo = - new ExecutionProfilesInfoFinder().getExecutionProfilesInfo(context); - - // then - assertThat(executionProfilesInfo) - .isEqualTo( - ImmutableMap.of( - "default", - new SpecificExecutionProfile( - 100, - new LoadBalancingInfo( - "LoadBalancingPolicyImpl", - ImmutableMap.of("localDataCenter", "local-dc", "filterFunction", true), - DEFAULT_LOAD_BALANCING_PACKAGE), - new SpeculativeExecutionInfo( - "SpeculativeExecutionImpl", - ImmutableMap.of("maxSpeculativeExecutions", 100, "delay", 20), - DEFAULT_SPECULATIVE_EXECUTION_PACKAGE), - "LOCAL_ONE", - "SERIAL", - ImmutableMap.of("source", "src-graph")), - "non-default", - expected)); - } - - @DataProvider - public static Object[][] executionProfileProvider() { - return new Object[][] { - { - mockNonDefaultRequestTimeoutExecutionProfile(), - new SpecificExecutionProfile(50, null, null, null, null, null) - }, - { - mockNonDefaultLoadBalancingExecutionProfile(), - new SpecificExecutionProfile( - null, - new LoadBalancingInfo( - "NonDefaultLoadBalancing", - ImmutableMap.of("localDataCenter", DEFAULT_LOCAL_DC, "filterFunction", true), - DEFAULT_LOAD_BALANCING_PACKAGE), - null, - null, - null, - null) - }, - { - mockUndefinedLocalDcExecutionProfile(), - new SpecificExecutionProfile( - null, - new LoadBalancingInfo( - "NonDefaultLoadBalancing", - ImmutableMap.of("filterFunction", true), - DEFAULT_LOAD_BALANCING_PACKAGE), - null, - null, - null, - null) - }, - { - mockNonDefaultSpeculativeExecutionInfo(), - new SpecificExecutionProfile( - null, - null, - new SpeculativeExecutionInfo( - "NonDefaultSpecexPolicy", - ImmutableMap.of( - "maxSpeculativeExecutions", SPECEX_MAX_DEFAULT, "delay", SPECEX_DELAY_DEFAULT), - DEFAULT_SPECULATIVE_EXECUTION_PACKAGE), - null, - null, - null) - }, - { - mockNonDefaultConsistency(), - new SpecificExecutionProfile(null, null, null, "ALL", null, null) - }, - { - mockNonDefaultSerialConsistency(), - new SpecificExecutionProfile(null, null, null, null, "ONE", null) - }, - { - mockNonDefaultGraphOptions(), - new SpecificExecutionProfile( - null, null, null, null, null, ImmutableMap.of("source", "non-default-graph")) - }, - { - mockDefaultExecutionProfile(), - new SpecificExecutionProfile(null, null, null, null, null, null) - } - }; - } - - @Test - public void should_not_include_null_fields_in_json() throws JsonProcessingException { - // given - SpecificExecutionProfile specificExecutionProfile = - new SpecificExecutionProfile(50, null, null, "ONE", null, ImmutableMap.of("a", "b")); - - // when - String result = new ObjectMapper().writeValueAsString(specificExecutionProfile); - - // then - assertThat(result) - .isEqualTo("{\"readTimeout\":50,\"consistency\":\"ONE\",\"graphOptions\":{\"a\":\"b\"}}"); - } - - @Test - public void should_include_empty_execution_profile_if_has_all_nulls() - throws JsonProcessingException { - // given - Map executionProfiles = - ImmutableMap.of("p", new SpecificExecutionProfile(null, null, null, null, null, null)); - - // when - String result = new ObjectMapper().writeValueAsString(executionProfiles); - - // then - assertThat(result).isEqualTo("{\"p\":{}}"); - } - - private InternalDriverContext mockDriverContextWithProfiles( - DriverExecutionProfile defaultExecutionProfile, - Map profiles) { - InternalDriverContext context = mock(InternalDriverContext.class); - DriverConfig driverConfig = mock(DriverConfig.class); - Mockito.>when(driverConfig.getProfiles()) - .thenReturn(profiles); - when(driverConfig.getDefaultProfile()).thenReturn(defaultExecutionProfile); - when(context.getConfig()).thenReturn(driverConfig); - return context; - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/insights/InsightsClientTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/insights/InsightsClientTest.java deleted file mode 100644 index 5085432dbec..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/insights/InsightsClientTest.java +++ /dev/null @@ -1,535 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights; - -import static com.datastax.dse.driver.api.core.DseProtocolVersion.DSE_V2; -import static com.datastax.dse.driver.internal.core.insights.ExecutionProfileMockUtil.mockDefaultExecutionProfile; -import static com.datastax.dse.driver.internal.core.insights.ExecutionProfileMockUtil.mockNonDefaultRequestTimeoutExecutionProfile; -import static com.datastax.dse.driver.internal.core.insights.PackageUtil.DEFAULT_AUTH_PROVIDER_PACKAGE; -import static com.datastax.dse.driver.internal.core.insights.PackageUtil.DEFAULT_LOAD_BALANCING_PACKAGE; -import static com.datastax.dse.driver.internal.core.insights.PackageUtil.DEFAULT_SPECULATIVE_EXECUTION_PACKAGE; -import static java.util.concurrent.TimeUnit.SECONDS; -import static org.assertj.core.api.Assertions.assertThat; -import static org.awaitility.Awaitility.await; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import com.datastax.dse.driver.api.core.metadata.DseNodeProperties; -import com.datastax.dse.driver.internal.core.insights.configuration.InsightsConfiguration; -import com.datastax.dse.driver.internal.core.insights.schema.AuthProviderType; -import com.datastax.dse.driver.internal.core.insights.schema.Insight; -import com.datastax.dse.driver.internal.core.insights.schema.InsightMetadata; -import com.datastax.dse.driver.internal.core.insights.schema.InsightType; -import com.datastax.dse.driver.internal.core.insights.schema.InsightsPlatformInfo; -import com.datastax.dse.driver.internal.core.insights.schema.InsightsPlatformInfo.CPUS; -import com.datastax.dse.driver.internal.core.insights.schema.InsightsPlatformInfo.OS; -import com.datastax.dse.driver.internal.core.insights.schema.InsightsPlatformInfo.RuntimeAndCompileTimeVersions; -import com.datastax.dse.driver.internal.core.insights.schema.InsightsStartupData; -import com.datastax.dse.driver.internal.core.insights.schema.InsightsStatusData; -import com.datastax.dse.driver.internal.core.insights.schema.LoadBalancingInfo; -import com.datastax.dse.driver.internal.core.insights.schema.PoolSizeByHostDistance; -import com.datastax.dse.driver.internal.core.insights.schema.ReconnectionPolicyInfo; -import com.datastax.dse.driver.internal.core.insights.schema.SSL; -import com.datastax.dse.driver.internal.core.insights.schema.SessionStateForNode; -import com.datastax.dse.driver.internal.core.insights.schema.SpecificExecutionProfile; -import com.datastax.dse.driver.internal.core.insights.schema.SpeculativeExecutionInfo; -import com.datastax.oss.driver.api.core.Version; -import com.datastax.oss.driver.api.core.config.DriverConfig; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.metadata.EndPoint; -import com.datastax.oss.driver.api.core.metadata.Metadata; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.datastax.oss.driver.internal.core.channel.DriverChannel; -import com.datastax.oss.driver.internal.core.context.DefaultDriverContext; -import com.datastax.oss.driver.internal.core.context.StartupOptionsBuilder; -import com.datastax.oss.driver.internal.core.control.ControlConnection; -import com.datastax.oss.driver.internal.core.metadata.DefaultNode; -import com.datastax.oss.driver.internal.core.metadata.MetadataManager; -import com.datastax.oss.driver.internal.core.pool.ChannelPool; -import com.datastax.oss.driver.internal.core.session.PoolManager; -import com.datastax.oss.driver.shaded.guava.common.base.Suppliers; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableSet; -import com.datastax.oss.driver.shaded.guava.common.collect.Sets; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import io.netty.channel.DefaultEventLoop; -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.UnknownHostException; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Executors; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Supplier; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; - -@RunWith(DataProviderRunner.class) -public class InsightsClientTest { - private static final StackTraceElement[] EMPTY_STACK_TRACE = {}; - private static final Map EMPTY_OBJECT_MAP = Collections.emptyMap(); - private static final Supplier MOCK_TIME_SUPPLIER = Suppliers.ofInstance(1L); - private static final InsightsConfiguration INSIGHTS_CONFIGURATION = - new InsightsConfiguration(true, 300000L, new DefaultEventLoop()); - - @Test - public void should_construct_json_event_startup_message() throws IOException { - // given - DefaultDriverContext context = mockDefaultDriverContext(); - PlatformInfoFinder platformInfoFinder = mock(PlatformInfoFinder.class); - OS os = new OS("linux", "1.2", "x64"); - CPUS cpus = new CPUS(8, "intel i7"); - Map javaDeps = - ImmutableMap.of("version", new RuntimeAndCompileTimeVersions("11.0.0", "11.0.0", false)); - Map> runtimeInfo = - ImmutableMap.of("java", javaDeps); - InsightsPlatformInfo insightsPlatformInfo = new InsightsPlatformInfo(os, cpus, runtimeInfo); - when(platformInfoFinder.getInsightsPlatformInfo()).thenReturn(insightsPlatformInfo); - - ConfigAntiPatternsFinder configAntiPatternsFinder = mock(ConfigAntiPatternsFinder.class); - when(configAntiPatternsFinder.findAntiPatterns(any(DefaultDriverContext.class))) - .thenReturn( - ImmutableMap.of( - "contactPointsMultipleDCs", - "Contact points contain hosts from multiple data centers")); - - DataCentersFinder dataCentersFinder = mock(DataCentersFinder.class); - when(dataCentersFinder.getDataCenters(any(DefaultDriverContext.class))) - .thenReturn(Sets.newHashSet("dc1", "dc2")); - ReconnectionPolicyInfoFinder reconnectionPolicyInfoFinder = - mock(ReconnectionPolicyInfoFinder.class); - when(reconnectionPolicyInfoFinder.getReconnectionPolicyInfo(any(), any())) - .thenReturn( - new ReconnectionPolicyInfo( - "reconnection-policy-a", ImmutableMap.of("opt-a", 1), "com.datastax.dse")); - - InsightsClient insightsClient = - new InsightsClient( - context, - MOCK_TIME_SUPPLIER, - INSIGHTS_CONFIGURATION, - platformInfoFinder, - reconnectionPolicyInfoFinder, - new ExecutionProfilesInfoFinder(), - configAntiPatternsFinder, - dataCentersFinder, - EMPTY_STACK_TRACE); - - // when - String startupMessage = insightsClient.createStartupMessage(); - Insight insight = - new ObjectMapper() - .readValue(startupMessage, new TypeReference>() {}); - - // then - assertThat(insight.getMetadata()) - .isEqualTo( - new InsightMetadata( - "driver.startup", - 1L, - ImmutableMap.of("language", "java"), - InsightType.EVENT, - "v1")); - - InsightsStartupData insightData = insight.getInsightData(); - assertThat(insightData.getClientId()).isEqualTo("client-id"); - assertThat(insightData.getSessionId()).isNotNull(); - assertThat(insightData.getDriverName()).isEqualTo("DataStax Enterprise Java Driver"); - assertThat(insightData.getDriverVersion()).isNotEmpty(); - assertThat(insightData.getApplicationName()).isEqualTo("app-name"); - assertThat(insightData.getApplicationVersion()).isEqualTo("1.0.0"); - assertThat(insightData.isApplicationNameWasGenerated()).isEqualTo(false); - assertThat(insightData.getContactPoints()) - .isEqualTo(ImmutableMap.of("localhost", Collections.singletonList("127.0.0.1:9999"))); - - assertThat(insightData.getInitialControlConnection()).isEqualTo("127.0.0.1:10"); - assertThat(insightData.getLocalAddress()).isEqualTo("127.0.0.1"); - assertThat(insightData.getHostName()).isNotEmpty(); - assertThat(insightData.getProtocolVersion()).isEqualTo(DSE_V2.getCode()); - assertThat(insightData.getExecutionProfiles()) - .isEqualTo( - ImmutableMap.of( - "default", - new SpecificExecutionProfile( - 100, - new LoadBalancingInfo( - "LoadBalancingPolicyImpl", - ImmutableMap.of("localDataCenter", "local-dc", "filterFunction", true), - DEFAULT_LOAD_BALANCING_PACKAGE), - new SpeculativeExecutionInfo( - "SpeculativeExecutionImpl", - ImmutableMap.of("maxSpeculativeExecutions", 100, "delay", 20), - DEFAULT_SPECULATIVE_EXECUTION_PACKAGE), - "LOCAL_ONE", - "SERIAL", - ImmutableMap.of("source", "src-graph")), - "non-default", - new SpecificExecutionProfile(50, null, null, null, null, null))); - assertThat(insightData.getPoolSizeByHostDistance()) - .isEqualTo(new PoolSizeByHostDistance(2, 1, 0)); - assertThat(insightData.getHeartbeatInterval()).isEqualTo(100); - assertThat(insightData.getCompression()).isEqualTo("none"); - assertThat(insightData.getReconnectionPolicy()) - .isEqualTo( - new ReconnectionPolicyInfo( - "reconnection-policy-a", ImmutableMap.of("opt-a", 1), "com.datastax.dse")); - assertThat(insightData.getSsl()).isEqualTo(new SSL(true, false)); - assertThat(insightData.getAuthProvider()) - .isEqualTo(new AuthProviderType("AuthProviderImpl", DEFAULT_AUTH_PROVIDER_PACKAGE)); - assertThat(insightData.getOtherOptions()).isEqualTo(EMPTY_OBJECT_MAP); - assertThat(insightData.getPlatformInfo()).isEqualTo(insightsPlatformInfo); - assertThat(insightData.getConfigAntiPatterns()) - .isEqualTo( - ImmutableMap.of( - "contactPointsMultipleDCs", - "Contact points contain hosts from multiple data centers")); - assertThat(insightData.getPeriodicStatusInterval()).isEqualTo(300); - assertThat(insightData.getDataCenters()).isEqualTo(Sets.newHashSet("dc1", "dc2")); - } - - @Test - public void should_group_contact_points_by_host_name() { - // given - Set contactPoints = - ImmutableSet.of( - InetSocketAddress.createUnresolved("127.0.0.1", 8080), - InetSocketAddress.createUnresolved("127.0.0.1", 8081), - InetSocketAddress.createUnresolved("127.0.0.2", 8081)); - - Map> expected = - ImmutableMap.of( - "127.0.0.1", - ImmutableList.of("127.0.0.1:8080", "127.0.0.1:8081"), - "127.0.0.2", - ImmutableList.of("127.0.0.2:8081")); - - // when - Map> resolvedContactPoints = - InsightsClient.getResolvedContactPoints(contactPoints); - - // then - assertThat(resolvedContactPoints).isEqualTo(expected); - } - - @Test - public void should_construct_json_event_status_message() throws IOException { - // given - InsightsClient insightsClient = - new InsightsClient( - mockDefaultDriverContext(), - MOCK_TIME_SUPPLIER, - INSIGHTS_CONFIGURATION, - null, - null, - null, - null, - null, - EMPTY_STACK_TRACE); - - // when - String statusMessage = insightsClient.createStatusMessage(); - - // then - Insight insight = - new ObjectMapper() - .readValue(statusMessage, new TypeReference>() {}); - assertThat(insight.getMetadata()) - .isEqualTo( - new InsightMetadata( - "driver.status", 1L, ImmutableMap.of("language", "java"), InsightType.EVENT, "v1")); - InsightsStatusData insightData = insight.getInsightData(); - assertThat(insightData.getClientId()).isEqualTo("client-id"); - assertThat(insightData.getSessionId()).isNotNull(); - assertThat(insightData.getControlConnection()).isEqualTo("127.0.0.1:10"); - assertThat(insightData.getConnectedNodes()) - .isEqualTo( - ImmutableMap.of( - "127.0.0.1:10", new SessionStateForNode(1, 10), - "127.0.0.1:20", new SessionStateForNode(2, 20))); - } - - @Test - public void should_schedule_task_with_initial_delay() { - // given - final AtomicInteger counter = new AtomicInteger(); - Runnable runnable = counter::incrementAndGet; - - // when - InsightsClient.scheduleInsightsTask(100L, Executors.newScheduledThreadPool(1), runnable); - - // then - await().atMost(1, SECONDS).until(() -> counter.get() >= 1); - } - - @Test - @UseDataProvider(value = "stackTraceProvider") - public void should_get_caller_of_create_cluster(StackTraceElement[] stackTrace, String expected) { - // when - String result = InsightsClient.getClusterCreateCaller(stackTrace); - - // then - assertThat(result).isEqualTo(expected); - } - - @Test - @SuppressWarnings("ResultOfMethodCallIgnored") - public void should_execute_should_send_event_check_only_once() - throws UnknownHostException, InterruptedException { - // given - InsightsConfiguration insightsConfiguration = mock(InsightsConfiguration.class); - when(insightsConfiguration.isMonitorReportingEnabled()).thenReturn(true); - when(insightsConfiguration.getStatusEventDelayMillis()).thenReturn(10L); - when(insightsConfiguration.getExecutor()).thenReturn(new DefaultEventLoop()); - - InsightsClient insightsClient = - new InsightsClient( - mockDefaultDriverContext(), - MOCK_TIME_SUPPLIER, - insightsConfiguration, - null, - null, - null, - null, - null, - EMPTY_STACK_TRACE); - - // when - insightsClient.scheduleStatusMessageSend(); - // emulate periodic calls to sendStatusMessage - insightsClient.sendStatusMessage(); - insightsClient.sendStatusMessage(); - insightsClient.sendStatusMessage(); - - // then - verify(insightsConfiguration, times(1)).isMonitorReportingEnabled(); - } - - @DataProvider - public static Object[][] stackTraceProvider() { - StackTraceElement[] onlyInitCall = - new StackTraceElement[] { - new StackTraceElement( - "com.datastax.oss.driver.internal.core.context.DefaultDriverContext", - "", - "DefaultDriverContext.java", - 94), - }; - - StackTraceElement[] stackTraceElementsWithoutInitCall = - new StackTraceElement[] { - new StackTraceElement("java.lang.Thread", "getStackTrace", "Thread.java", 1559), - new StackTraceElement( - "com.datastax.driver.core.InsightsClient", - "getClusterCreateCaller", - "InsightsClient.java", - 302) - }; - StackTraceElement[] stackTraceWithOneInitCall = - new StackTraceElement[] { - new StackTraceElement("java.lang.Thread", "getStackTrace", "Thread.java", 1559), - new StackTraceElement( - "com.datastax.oss.driver.internal.core.context.DefaultDriverContext", - "", - "DefaultDriverContext.java", - 243), - }; - StackTraceElement[] stackTraceWithOneInitCallAndCaller = - new StackTraceElement[] { - new StackTraceElement("java.lang.Thread", "getStackTrace", "Thread.java", 1559), - new StackTraceElement( - "com.datastax.oss.driver.internal.core.context.DefaultDriverContext", - "", - "DefaultDriverContext.java", - 243), - new StackTraceElement( - "com.example.ActualCallerNameApp", "main", "ActualCallerNameApp.java", 1) - }; - - StackTraceElement[] stackTraceWithTwoInitCallsAndCaller = - new StackTraceElement[] { - new StackTraceElement("java.lang.Thread", "getStackTrace", "Thread.java", 1559), - new StackTraceElement( - "com.datastax.oss.driver.internal.core.context.DefaultDriverContext", - "", - "DefaultDriverContext.java", - 243), - new StackTraceElement( - "com.datastax.oss.driver.api.core.session.SessionBuilder", - "buildDefaultSessionAsync", - "SessionBuilder.java", - 300), - new StackTraceElement( - "com.example.ActualCallerNameApp", "main", "ActualCallerNameApp.java", 1) - }; - StackTraceElement[] stackTraceWithChainOfInitCalls = - new StackTraceElement[] { - new StackTraceElement( - "com.datastax.oss.driver.internal.core.context.DefaultDriverContext", - "", - "DefaultDriverContext.java", - 243), - new StackTraceElement( - "com.datastax.oss.driver.api.core.session.SessionBuilder", - "buildDefaultSessionAsync", - "SessionBuilder.java", - 332), - new StackTraceElement( - "com.datastax.oss.driver.api.core.session.SessionBuilder", - "buildAsync", - "SessionBuilder.java", - 291), - new StackTraceElement( - "com.datastax.oss.driver.api.core.session.SessionBuilder", - "build", - "SessionBuilder.java", - 306) - }; - StackTraceElement[] stackTraceWithChainOfInitCallsAndCaller = - new StackTraceElement[] { - new StackTraceElement("java.lang.Thread", "getStackTrace", "Thread.java", 1559), - new StackTraceElement( - "com.datastax.oss.driver.internal.core.context.DefaultDriverContext", - "", - "DefaultDriverContext.java", - 243), - new StackTraceElement( - "com.datastax.oss.driver.api.core.session.SessionBuilder", - "buildContext", - "SessionBuilder.java", - 687), - new StackTraceElement( - "com.datastax.oss.driver.api.core.session.SessionBuilder", - "buildDefaultSessionAsync", - "SessionBuilder.java", - 332), - new StackTraceElement( - "com.datastax.oss.driver.api.core.session.SessionBuilder", - "buildAsync", - "SessionBuilder.java", - 291), - new StackTraceElement( - "com.datastax.oss.driver.api.core.session.SessionBuilder", - "build", - "SessionBuilder.java", - 306), - new StackTraceElement( - "com.example.ActualCallerNameApp", "main", "ActualCallerNameApp.java", 8) - }; - - return new Object[][] { - {new StackTraceElement[] {}, InsightsClient.DEFAULT_JAVA_APPLICATION}, - {stackTraceElementsWithoutInitCall, InsightsClient.DEFAULT_JAVA_APPLICATION}, - {stackTraceWithOneInitCall, InsightsClient.DEFAULT_JAVA_APPLICATION}, - {onlyInitCall, InsightsClient.DEFAULT_JAVA_APPLICATION}, - {stackTraceWithOneInitCallAndCaller, "com.example.ActualCallerNameApp"}, - {stackTraceWithTwoInitCallsAndCaller, "com.example.ActualCallerNameApp"}, - {stackTraceWithChainOfInitCalls, InsightsClient.DEFAULT_JAVA_APPLICATION}, - {stackTraceWithChainOfInitCallsAndCaller, "com.example.ActualCallerNameApp"} - }; - } - - private DefaultDriverContext mockDefaultDriverContext() throws UnknownHostException { - DefaultDriverContext context = mock(DefaultDriverContext.class); - mockConnectionPools(context); - MetadataManager manager = mock(MetadataManager.class); - when(context.getMetadataManager()).thenReturn(manager); - Metadata metadata = mock(Metadata.class); - when(manager.getMetadata()).thenReturn(metadata); - Node node = mock(Node.class); - when(node.getExtras()) - .thenReturn( - ImmutableMap.of( - DseNodeProperties.DSE_VERSION, Objects.requireNonNull(Version.parse("6.0.5")))); - when(metadata.getNodes()).thenReturn(ImmutableMap.of(UUID.randomUUID(), node)); - DriverExecutionProfile defaultExecutionProfile = mockDefaultExecutionProfile(); - DriverExecutionProfile nonDefaultExecutionProfile = - mockNonDefaultRequestTimeoutExecutionProfile(); - - Map startupOptions = new HashMap<>(); - startupOptions.put(StartupOptionsBuilder.CLIENT_ID_KEY, "client-id"); - startupOptions.put(StartupOptionsBuilder.APPLICATION_VERSION_KEY, "1.0.0"); - startupOptions.put(StartupOptionsBuilder.APPLICATION_NAME_KEY, "app-name"); - startupOptions.put(StartupOptionsBuilder.DRIVER_VERSION_KEY, "2.x"); - startupOptions.put(StartupOptionsBuilder.DRIVER_NAME_KEY, "DataStax Enterprise Java Driver"); - - when(context.getStartupOptions()).thenReturn(startupOptions); - when(context.getProtocolVersion()).thenReturn(DSE_V2); - DefaultNode contactPoint = mock(DefaultNode.class); - EndPoint contactEndPoint = mock(EndPoint.class); - when(contactEndPoint.resolve()).thenReturn(new InetSocketAddress("127.0.0.1", 9999)); - when(contactPoint.getEndPoint()).thenReturn(contactEndPoint); - when(manager.getContactPoints()).thenReturn(ImmutableSet.of(contactPoint)); - - DriverConfig driverConfig = mock(DriverConfig.class); - when(context.getConfig()).thenReturn(driverConfig); - Map profiles = - ImmutableMap.of( - "default", defaultExecutionProfile, "non-default", nonDefaultExecutionProfile); - Mockito.>when(driverConfig.getProfiles()) - .thenReturn(profiles); - when(driverConfig.getDefaultProfile()).thenReturn(defaultExecutionProfile); - - ControlConnection controlConnection = mock(ControlConnection.class); - DriverChannel channel = mock(DriverChannel.class); - EndPoint controlConnectionEndpoint = mock(EndPoint.class); - when(controlConnectionEndpoint.resolve()).thenReturn(new InetSocketAddress("127.0.0.1", 10)); - - when(channel.getEndPoint()).thenReturn(controlConnectionEndpoint); - when(channel.localAddress()).thenReturn(new InetSocketAddress("127.0.0.1", 10)); - when(controlConnection.channel()).thenReturn(channel); - when(context.getControlConnection()).thenReturn(controlConnection); - return context; - } - - private void mockConnectionPools(DefaultDriverContext driverContext) { - Node node1 = mock(Node.class); - EndPoint endPoint1 = mock(EndPoint.class); - when(endPoint1.resolve()).thenReturn(new InetSocketAddress("127.0.0.1", 10)); - when(node1.getEndPoint()).thenReturn(endPoint1); - when(node1.getOpenConnections()).thenReturn(1); - ChannelPool channelPool1 = mock(ChannelPool.class); - when(channelPool1.getInFlight()).thenReturn(10); - - Node node2 = mock(Node.class); - EndPoint endPoint2 = mock(EndPoint.class); - when(endPoint2.resolve()).thenReturn(new InetSocketAddress("127.0.0.1", 20)); - when(node2.getEndPoint()).thenReturn(endPoint2); - when(node2.getOpenConnections()).thenReturn(2); - ChannelPool channelPool2 = mock(ChannelPool.class); - when(channelPool2.getInFlight()).thenReturn(20); - - Map channelPools = ImmutableMap.of(node1, channelPool1, node2, channelPool2); - PoolManager poolManager = mock(PoolManager.class); - when(poolManager.getPools()).thenReturn(channelPools); - when(driverContext.getPoolManager()).thenReturn(poolManager); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/insights/InsightsSupportVerifierTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/insights/InsightsSupportVerifierTest.java deleted file mode 100644 index 9edd4494bdd..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/insights/InsightsSupportVerifierTest.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import com.datastax.dse.driver.api.core.metadata.DseNodeProperties; -import com.datastax.oss.driver.api.core.Version; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import java.util.Collection; -import java.util.Collections; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(DataProviderRunner.class) -public class InsightsSupportVerifierTest { - - @Test - @UseDataProvider(value = "dseHostsProvider") - public void should_detect_DSE_versions_that_supports_insights( - Collection hosts, boolean expected) { - // when - boolean result = InsightsSupportVerifier.supportsInsights(hosts); - - // then - assertThat(result).isEqualTo(expected); - } - - @DataProvider - public static Object[][] dseHostsProvider() { - Node dse605 = mock(Node.class); - when(dse605.getExtras()) - .thenReturn(ImmutableMap.of(DseNodeProperties.DSE_VERSION, Version.parse("6.0.5"))); - Node dse604 = mock(Node.class); - when(dse604.getExtras()) - .thenReturn(ImmutableMap.of(DseNodeProperties.DSE_VERSION, Version.parse("6.0.4"))); - Node dse600 = mock(Node.class); - when(dse600.getExtras()) - .thenReturn(ImmutableMap.of(DseNodeProperties.DSE_VERSION, Version.parse("6.0.0"))); - Node dse5113 = mock(Node.class); - when(dse5113.getExtras()) - .thenReturn(ImmutableMap.of(DseNodeProperties.DSE_VERSION, Version.parse("5.1.13"))); - Node dse500 = mock(Node.class); - when(dse500.getExtras()) - .thenReturn(ImmutableMap.of(DseNodeProperties.DSE_VERSION, Version.parse("5.0.0"))); - Node nodeWithoutExtras = mock(Node.class); - when(nodeWithoutExtras.getExtras()).thenReturn(Collections.emptyMap()); - - return new Object[][] { - {ImmutableList.of(dse605), true}, - {ImmutableList.of(dse604), false}, - {ImmutableList.of(dse600), false}, - {ImmutableList.of(dse5113), true}, - {ImmutableList.of(dse500), false}, - {ImmutableList.of(dse5113, dse605), true}, - {ImmutableList.of(dse5113, dse600), false}, - {ImmutableList.of(dse500, dse600), false}, - {ImmutableList.of(), false}, - {ImmutableList.of(nodeWithoutExtras), false} - }; - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/insights/PackageUtilTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/insights/PackageUtilTest.java deleted file mode 100644 index 336f19184d3..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/insights/PackageUtilTest.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(DataProviderRunner.class) -public class PackageUtilTest { - - private static final String DEFAULT_PACKAGE = "default.package"; - - @Test - public void should_find_package_name_for_class() { - // given - TestClass testClass = new TestClass(); - - // then - String namespace = PackageUtil.getNamespace(testClass.getClass()); - - // then - assertThat(namespace).isEqualTo("com.datastax.dse.driver.internal.core.insights"); - } - - @Test - @UseDataProvider("packagesProvider") - public void should_get_full_package_or_return_default(String fullClassSetting, String expected) { - // when - String result = PackageUtil.getFullPackageOrDefault(fullClassSetting, DEFAULT_PACKAGE); - - // then - assertThat(result).isEqualTo(expected); - } - - @Test - @UseDataProvider("classesProvider") - public void should_get_class_name_from_full_class_setting( - String fullClassSetting, String expected) { - // when - String result = PackageUtil.getClassName(fullClassSetting); - - // then - assertThat(result).isEqualTo(expected); - } - - @DataProvider - public static Object[][] packagesProvider() { - return new Object[][] { - {"com.P", "com"}, - {"ClassName", DEFAULT_PACKAGE}, - {"", DEFAULT_PACKAGE}, - {"com.p.a.2.x.12.Class", "com.p.a.2.x.12"}, - }; - } - - @DataProvider - public static Object[][] classesProvider() { - return new Object[][] { - {"com.P", "P"}, - {"ClassName", "ClassName"}, - {"", ""}, - {"com.p.a.2.x.12.Class", "Class"}, - }; - } - - private static class TestClass {} -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/insights/PlatformInfoFinderTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/insights/PlatformInfoFinderTest.java deleted file mode 100644 index 79818d906b6..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/insights/PlatformInfoFinderTest.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights; - -import static com.datastax.dse.driver.internal.core.insights.PlatformInfoFinder.UNVERIFIED_RUNTIME_VERSION; -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.dse.driver.internal.core.insights.schema.InsightsPlatformInfo.RuntimeAndCompileTimeVersions; -import java.io.InputStream; -import java.net.URL; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; -import org.junit.Test; - -public class PlatformInfoFinderTest { - - private URL nullUrlProvider(PlatformInfoFinder.DependencyFromFile d) { - return null; - } - - private URL nettyUrlProvider(PlatformInfoFinder.DependencyFromFile d) { - return this.getClass().getResource("/insights/pom.properties"); - } - - private URL malformedUrlProvider(PlatformInfoFinder.DependencyFromFile d) { - return this.getClass().getResource("/insights/malformed-pom.properties"); - } - - private URL nonExistingUrlProvider(PlatformInfoFinder.DependencyFromFile d) { - return this.getClass().getResource("/insights/non-existing.pom"); - } - - @Test - public void should_find_dependencies_from_file() { - // given - InputStream inputStream = - this.getClass().getResourceAsStream("/insights/test-dependencies.txt"); - Map expected = new HashMap<>(); - expected.put( - "io.netty:netty-transport-native-epoll", - withUnverifiedRuntimeVersionOptional("4.0.56.Final")); - expected.put("org.slf4j:slf4j-api", withUnverifiedRuntimeVersion("1.7.25")); - expected.put("org.ow2.asm:asm", withUnverifiedRuntimeVersion("5.0.3")); - expected.put("com.esri.geometry:esri-geometry-api", withUnverifiedRuntimeVersion("1.2.1")); - expected.put("io.netty:netty-transport", withUnverifiedRuntimeVersion("4.0.56.Final")); - expected.put("com.github.jnr:jnr-x86asm", withUnverifiedRuntimeVersion("1.0.2")); - expected.put("org.ow2.asm:asm-analysis", withUnverifiedRuntimeVersion("5.0.3")); - expected.put("com.github.jnr:jnr-constants", withUnverifiedRuntimeVersion("0.9.9")); - expected.put("io.netty:netty-common", withUnverifiedRuntimeVersion("4.0.56.Final")); - expected.put("com.google.guava:guava", withUnverifiedRuntimeVersion("19.0")); - expected.put("org.xerial.snappy:snappy-java", withUnverifiedRuntimeVersionOptional("1.1.2.6")); - expected.put("io.dropwizard.metrics:metrics-core", withUnverifiedRuntimeVersion("3.2.2")); - expected.put("org.ow2.asm:asm-tree", withUnverifiedRuntimeVersion("5.0.3")); - expected.put("com.github.jnr:jnr-posix", withUnverifiedRuntimeVersion("3.0.44")); - expected.put("org.codehaus.jackson:jackson-core-asl", withUnverifiedRuntimeVersion("1.9.12")); - expected.put( - "com.fasterxml.jackson.core:jackson-databind", withUnverifiedRuntimeVersion("2.7.9.3")); - expected.put("io.netty:netty-codec", withUnverifiedRuntimeVersion("4.0.56.Final")); - expected.put( - "com.fasterxml.jackson.core:jackson-annotations", withUnverifiedRuntimeVersion("2.8.11")); - expected.put("com.fasterxml.jackson.core:jackson-core", withUnverifiedRuntimeVersion("2.8.11")); - expected.put("io.netty:netty-handler", withUnverifiedRuntimeVersion("4.0.56.Final")); - expected.put("at.yawk.lz4:lz4-java", withUnverifiedRuntimeVersionOptional("1.8.1")); - expected.put("org.hdrhistogram:HdrHistogram", withUnverifiedRuntimeVersionOptional("2.1.10")); - expected.put("com.github.jnr:jffi", withUnverifiedRuntimeVersion("1.2.16")); - expected.put("io.netty:netty-buffer", withUnverifiedRuntimeVersion("4.0.56.Final")); - expected.put("org.ow2.asm:asm-commons", withUnverifiedRuntimeVersion("5.0.3")); - expected.put("org.json:json", withUnverifiedRuntimeVersion("20090211")); - expected.put("org.ow2.asm:asm-util", withUnverifiedRuntimeVersion("5.0.3")); - expected.put("com.github.jnr:jnr-ffi", withUnverifiedRuntimeVersion("2.1.7")); - - // when - Map stringStringMap = - new PlatformInfoFinder(this::nullUrlProvider).fetchDependenciesFromFile(inputStream); - - // then - assertThat(stringStringMap).hasSize(28); - assertThat(stringStringMap).isEqualTo(expected); - } - - @Test - public void should_find_dependencies_from_file_without_duplicate() { - // given - InputStream inputStream = - this.getClass().getResourceAsStream("/insights/duplicate-dependencies.txt"); - - // when - Map stringStringMap = - new PlatformInfoFinder(this::nullUrlProvider).fetchDependenciesFromFile(inputStream); - - // then - assertThat(stringStringMap).hasSize(1); - } - - @Test - public void should_keep_order_of_dependencies() { - // given - InputStream inputStream = - this.getClass().getResourceAsStream("/insights/ordered-dependencies.txt"); - Map expected = new LinkedHashMap<>(); - expected.put("b-org.com:art1", withUnverifiedRuntimeVersion("1.0")); - expected.put("a-org.com:art1", withUnverifiedRuntimeVersion("2.0")); - expected.put("c-org.com:art1", withUnverifiedRuntimeVersion("3.0")); - - // when - Map stringStringMap = - new PlatformInfoFinder(this::nullUrlProvider).fetchDependenciesFromFile(inputStream); - - // then - assertThat(stringStringMap).isEqualTo(expected); - Iterator iterator = expected.keySet().iterator(); - assertThat(iterator.next()).isEqualTo("b-org.com:art1"); - assertThat(iterator.next()).isEqualTo("a-org.com:art1"); - assertThat(iterator.next()).isEqualTo("c-org.com:art1"); - } - - @Test - public void should_add_information_about_java_platform() { - // given - Map> runtimeDependencies = new HashMap<>(); - - // when - new PlatformInfoFinder(this::nullUrlProvider).addJavaVersion(runtimeDependencies); - - // then - Map javaDependencies = runtimeDependencies.get("java"); - assertThat(javaDependencies.size()).isEqualTo(3); - } - - @Test - public void should_load_runtime_version_from_pom_properties_URL() { - // given - InputStream inputStream = this.getClass().getResourceAsStream("/insights/netty-dependency.txt"); - Map expected = new LinkedHashMap<>(); - expected.put( - "io.netty:netty-handler", - new RuntimeAndCompileTimeVersions("4.0.56.Final", "4.0.0.Final", false)); - - // when - Map stringStringMap = - new PlatformInfoFinder(this::nettyUrlProvider).fetchDependenciesFromFile(inputStream); - - // then - assertThat(stringStringMap).isEqualTo(expected); - } - - @Test - public void should_load_runtime_version_of_optional_dependency_from_pom_properties_URL() { - // given - InputStream inputStream = - this.getClass().getResourceAsStream("/insights/netty-dependency-optional.txt"); - Map expected = new LinkedHashMap<>(); - expected.put( - "io.netty:netty-handler", - new RuntimeAndCompileTimeVersions("4.0.56.Final", "4.0.0.Final", true)); - - // when - Map stringStringMap = - new PlatformInfoFinder(this::nettyUrlProvider).fetchDependenciesFromFile(inputStream); - - // then - assertThat(stringStringMap).isEqualTo(expected); - } - - @Test - public void should_not_load_runtime_dependency_from_malformed_pom_properties() { - // given - InputStream inputStream = this.getClass().getResourceAsStream("/insights/netty-dependency.txt"); - Map expected = new LinkedHashMap<>(); - expected.put("io.netty:netty-handler", withUnverifiedRuntimeVersion("4.0.0.Final")); - - // when - Map stringStringMap = - new PlatformInfoFinder(this::malformedUrlProvider).fetchDependenciesFromFile(inputStream); - - // then - assertThat(stringStringMap).isEqualTo(expected); - } - - @Test - public void should_not_load_runtime_dependency_from_non_existing_pom_properties() { - // given - InputStream inputStream = this.getClass().getResourceAsStream("/insights/netty-dependency.txt"); - Map expected = new LinkedHashMap<>(); - expected.put("io.netty:netty-handler", withUnverifiedRuntimeVersion("4.0.0.Final")); - - // when - Map stringStringMap = - new PlatformInfoFinder(this::nonExistingUrlProvider).fetchDependenciesFromFile(inputStream); - - // then - assertThat(stringStringMap).isEqualTo(expected); - } - - private RuntimeAndCompileTimeVersions withUnverifiedRuntimeVersion(String compileVersion) { - return new RuntimeAndCompileTimeVersions(UNVERIFIED_RUNTIME_VERSION, compileVersion, false); - } - - private RuntimeAndCompileTimeVersions withUnverifiedRuntimeVersionOptional( - String compileVersion) { - return new RuntimeAndCompileTimeVersions(UNVERIFIED_RUNTIME_VERSION, compileVersion, true); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/insights/ReconnectionPolicyInfoFinderTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/insights/ReconnectionPolicyInfoFinderTest.java deleted file mode 100644 index a076ca38b1c..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/insights/ReconnectionPolicyInfoFinderTest.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.insights; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import com.datastax.dse.driver.internal.core.insights.schema.ReconnectionPolicyInfo; -import com.datastax.oss.driver.api.core.config.DefaultDriverOption; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.connection.ReconnectionPolicy; -import com.datastax.oss.driver.internal.core.connection.ConstantReconnectionPolicy; -import com.datastax.oss.driver.internal.core.connection.ExponentialReconnectionPolicy; -import java.time.Duration; -import org.assertj.core.data.MapEntry; -import org.junit.Test; - -public class ReconnectionPolicyInfoFinderTest { - - @Test - public void should_find_an_info_about_constant_reconnection_policy() { - // given - DriverExecutionProfile driverExecutionProfile = mock(DriverExecutionProfile.class); - when(driverExecutionProfile.getDuration(DefaultDriverOption.RECONNECTION_BASE_DELAY)) - .thenReturn(Duration.ofMillis(100)); - ReconnectionPolicy constantReconnectionPolicy = mock(ConstantReconnectionPolicy.class); - - // when - ReconnectionPolicyInfo reconnectionPolicyInfo = - new ReconnectionPolicyInfoFinder() - .getReconnectionPolicyInfo(constantReconnectionPolicy, driverExecutionProfile); - - // then - assertThat(reconnectionPolicyInfo.getOptions()).contains(MapEntry.entry("delayMs", 100L)); - assertThat(reconnectionPolicyInfo.getType()).contains("ConstantReconnectionPolicy"); - } - - @Test - public void should_find_an_info_about_exponential_reconnection_policy() { - ExponentialReconnectionPolicy exponentialReconnectionPolicy = - mock(ExponentialReconnectionPolicy.class); - when(exponentialReconnectionPolicy.getBaseDelayMs()).thenReturn(100L); - when(exponentialReconnectionPolicy.getMaxAttempts()).thenReturn(10L); - when(exponentialReconnectionPolicy.getMaxDelayMs()).thenReturn(200L); - - // when - ReconnectionPolicyInfo reconnectionPolicyInfo = - new ReconnectionPolicyInfoFinder() - .getReconnectionPolicyInfo(exponentialReconnectionPolicy, null); - - // then - assertThat(reconnectionPolicyInfo.getOptions()).contains(MapEntry.entry("baseDelayMs", 100L)); - assertThat(reconnectionPolicyInfo.getOptions()).contains(MapEntry.entry("maxAttempts", 10L)); - assertThat(reconnectionPolicyInfo.getOptions()).contains(MapEntry.entry("maxDelayMs", 200L)); - assertThat(reconnectionPolicyInfo.getType()).contains("ExponentialReconnectionPolicy"); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/protocol/TinkerpopBufferPrimitiveCodecTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/protocol/TinkerpopBufferPrimitiveCodecTest.java deleted file mode 100644 index 3ef89c78714..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/protocol/TinkerpopBufferPrimitiveCodecTest.java +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.protocol; - -import static com.datastax.dse.driver.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import com.datastax.dse.driver.Assertions; -import com.datastax.dse.driver.internal.core.graph.binary.buffer.DseNettyBufferFactory; -import com.datastax.oss.driver.internal.core.protocol.ByteBufPrimitiveCodecTest; -import com.datastax.oss.protocol.internal.util.Bytes; -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.nio.ByteBuffer; -import java.util.function.Supplier; -import org.apache.tinkerpop.gremlin.structure.io.Buffer; -import org.junit.Test; -import org.junit.runner.RunWith; - -/** - * Note: like {@link ByteBufPrimitiveCodecTest} we don't test trivial methods that simply delegate - * to the underlying Buffer, nor default implementations inherited from {@link - * com.datastax.oss.protocol.internal.PrimitiveCodec}. - */ -@RunWith(DataProviderRunner.class) -public class TinkerpopBufferPrimitiveCodecTest { - - private static final DseNettyBufferFactory factory = new DseNettyBufferFactory(); - private final TinkerpopBufferPrimitiveCodec codec = new TinkerpopBufferPrimitiveCodec(factory); - - @Test - public void should_concatenate() { - Buffer left = factory.withBytes(0xca, 0xfe); - Buffer right = factory.withBytes(0xba, 0xbe); - assertThat(codec.concat(left, right)).containsExactly("0xcafebabe"); - } - - @Test - public void should_read_inet_v4() { - Buffer source = - factory.withBytes( - // length (as a byte) - 0x04, - // address - 0x7f, - 0x00, - 0x00, - 0x01, - // port (as an int) - 0x00, - 0x00, - 0x23, - 0x52); - InetSocketAddress inet = codec.readInet(source); - assertThat(inet.getAddress().getHostAddress()).isEqualTo("127.0.0.1"); - assertThat(inet.getPort()).isEqualTo(9042); - } - - @Test - public void should_read_inet_v6() { - Buffer lengthAndAddress = factory.heap(17); - lengthAndAddress.writeByte(16); - lengthAndAddress.writeLong(0); - lengthAndAddress.writeLong(1); - Buffer source = - codec.concat( - lengthAndAddress, - // port (as an int) - factory.withBytes(0x00, 0x00, 0x23, 0x52)); - InetSocketAddress inet = codec.readInet(source); - assertThat(inet.getAddress().getHostAddress()).isEqualTo("0:0:0:0:0:0:0:1"); - assertThat(inet.getPort()).isEqualTo(9042); - } - - @Test - public void should_fail_to_read_inet_if_length_invalid() { - Buffer source = - factory.withBytes( - // length (as a byte) - 0x03, - // address - 0x7f, - 0x00, - 0x01, - // port (as an int) - 0x00, - 0x00, - 0x23, - 0x52); - assertThatThrownBy(() -> codec.readInet(source)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Invalid address length: 3 ([127, 0, 1])"); - } - - @Test - public void should_read_inetaddr_v4() { - Buffer source = - factory.withBytes( - // length (as a byte) - 0x04, - // address - 0x7f, - 0x00, - 0x00, - 0x01); - InetAddress inetAddr = codec.readInetAddr(source); - assertThat(inetAddr.getHostAddress()).isEqualTo("127.0.0.1"); - } - - @Test - public void should_read_inetaddr_v6() { - Buffer source = factory.heap(17); - source.writeByte(16); - source.writeLong(0); - source.writeLong(1); - InetAddress inetAddr = codec.readInetAddr(source); - assertThat(inetAddr.getHostAddress()).isEqualTo("0:0:0:0:0:0:0:1"); - } - - @Test - public void should_fail_to_read_inetaddr_if_length_invalid() { - Buffer source = - factory.withBytes( - // length (as a byte) - 0x03, - // address - 0x7f, - 0x00, - 0x01); - assertThatThrownBy(() -> codec.readInetAddr(source)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Invalid address length: 3 ([127, 0, 1])"); - } - - @Test - public void should_read_bytes() { - Buffer source = - factory.withBytes( - // length (as an int) - 0x00, - 0x00, - 0x00, - 0x04, - // contents - 0xca, - 0xfe, - 0xba, - 0xbe); - ByteBuffer bytes = codec.readBytes(source); - assertThat(Bytes.toHexString(bytes)).isEqualTo("0xcafebabe"); - } - - @Test - public void should_read_null_bytes() { - Buffer source = factory.withBytes(0xFF, 0xFF, 0xFF, 0xFF); // -1 (as an int) - assertThat(codec.readBytes(source)).isNull(); - } - - @Test - public void should_read_short_bytes() { - Buffer source = - factory.withBytes( - // length (as an unsigned short) - 0x00, - 0x04, - // contents - 0xca, - 0xfe, - 0xba, - 0xbe); - assertThat(Bytes.toHexString(codec.readShortBytes(source))).isEqualTo("0xcafebabe"); - } - - @DataProvider - public static Object[][] bufferTypes() { - return new Object[][] { - {(Supplier) factory::heap}, - {(Supplier) factory::io}, - {(Supplier) factory::direct} - }; - } - - @Test - @UseDataProvider("bufferTypes") - public void should_read_string(Supplier supplier) { - Buffer source = - factory.withBytes( - supplier, - // length (as an unsigned short) - 0x00, - 0x05, - // UTF-8 contents - 0x68, - 0x65, - 0x6c, - 0x6c, - 0x6f); - assertThat(codec.readString(source)).isEqualTo("hello"); - } - - @Test - public void should_fail_to_read_string_if_not_enough_characters() { - Buffer source = factory.heap(); - source.writeShort(4); - - assertThatThrownBy(() -> codec.readString(source)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Not enough bytes to read an UTF-8 serialized string of size 4"); - } - - @Test - public void should_read_long_string() { - Buffer source = - factory.withBytes( - // length (as an int) - 0x00, - 0x00, - 0x00, - 0x05, - // UTF-8 contents - 0x68, - 0x65, - 0x6c, - 0x6c, - 0x6f); - assertThat(codec.readLongString(source)).isEqualTo("hello"); - } - - @Test - public void should_fail_to_read_long_string_if_not_enough_characters() { - Buffer source = factory.heap(4, 4); - source.writeInt(4); - - assertThatThrownBy(() -> codec.readLongString(source)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Not enough bytes to read an UTF-8 serialized string of size 4"); - } - - @Test - public void should_write_inet_v4() throws Exception { - Buffer dest = factory.heap(1 + 4 + 4); - InetSocketAddress inet = new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 9042); - codec.writeInet(inet, dest); - assertThat(dest) - .containsExactly( - "0x04" // size as a byte - + "7f000001" // address - + "00002352" // port - ); - } - - @Test - public void should_write_inet_v6() throws Exception { - Buffer dest = factory.heap(1 + 16 + 4); - InetSocketAddress inet = new InetSocketAddress(InetAddress.getByName("::1"), 9042); - codec.writeInet(inet, dest); - assertThat(dest) - .containsExactly( - "0x10" // size as a byte - + "00000000000000000000000000000001" // address - + "00002352" // port - ); - } - - @Test - public void should_write_inetaddr_v4() throws Exception { - Buffer dest = factory.heap(1 + 4); - InetAddress inetAddr = InetAddress.getByName("127.0.0.1"); - codec.writeInetAddr(inetAddr, dest); - assertThat(dest) - .containsExactly( - "0x04" // size as a byte - + "7f000001" // address - ); - } - - @Test - public void should_write_inetaddr_v6() throws Exception { - Buffer dest = factory.heap(1 + 16); - InetAddress inetAddr = InetAddress.getByName("::1"); - codec.writeInetAddr(inetAddr, dest); - Assertions.assertThat(dest) - .containsExactly( - "0x10" // size as a byte - + "00000000000000000000000000000001" // address - ); - } - - @Test - public void should_write_string() { - Buffer dest = factory.heap(); - codec.writeString("hello", dest); - assertThat(dest) - .containsExactly( - "0x0005" // size as an unsigned short - + "68656c6c6f" // UTF-8 contents - ); - } - - @Test - public void should_write_long_string() { - Buffer dest = factory.heap(9); - codec.writeLongString("hello", dest); - assertThat(dest) - .containsExactly( - "0x00000005" - + // size as an int - "68656c6c6f" // UTF-8 contents - ); - } - - @Test - public void should_write_bytes() { - Buffer dest = factory.heap(8); - codec.writeBytes(Bytes.fromHexString("0xcafebabe"), dest); - assertThat(dest) - .containsExactly( - "0x00000004" - + // size as an int - "cafebabe"); - } - - @Test - public void should_write_short_bytes() { - Buffer dest = factory.heap(6); - codec.writeShortBytes(new byte[] {(byte) 0xca, (byte) 0xfe, (byte) 0xba, (byte) 0xbe}, dest); - assertThat(dest) - .containsExactly( - "0x0004" - + // size as an unsigned short - "cafebabe"); - } - - @Test - public void should_write_null_bytes() { - Buffer dest = factory.heap(4); - codec.writeBytes((ByteBuffer) null, dest); - assertThat(dest).containsExactly("0xFFFFFFFF"); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/type/codec/geometry/GeometryCodecTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/type/codec/geometry/GeometryCodecTest.java deleted file mode 100644 index 9e4d019660c..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/type/codec/geometry/GeometryCodecTest.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.type.codec.geometry; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.dse.driver.api.core.data.geometry.Geometry; - -public abstract class GeometryCodecTest> { - - private C codec; - - protected GeometryCodecTest(C codec) { - this.codec = codec; - } - - public void should_format(G input, String expected) { - assertThat(codec.format(input)).isEqualTo(expected); - } - - public void should_parse(String input, G expected) { - assertThat(codec.parse(input)).isEqualTo(expected); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/type/codec/geometry/LineStringCodecTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/type/codec/geometry/LineStringCodecTest.java deleted file mode 100644 index ba71026ac2c..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/type/codec/geometry/LineStringCodecTest.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.type.codec.geometry; - -import com.datastax.dse.driver.api.core.data.geometry.LineString; -import com.datastax.dse.driver.internal.core.data.geometry.DefaultLineString; -import com.datastax.dse.driver.internal.core.data.geometry.DefaultPoint; -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(DataProviderRunner.class) -public class LineStringCodecTest extends GeometryCodecTest { - - private static DefaultLineString lineString = - new DefaultLineString( - new DefaultPoint(30, 10), new DefaultPoint(10, 30), new DefaultPoint(40, 40)); - - public LineStringCodecTest() { - super(new LineStringCodec()); - } - - @DataProvider - public static Object[][] serde() { - return new Object[][] {{null, null}, {lineString, lineString}}; - } - - @DataProvider - public static Object[][] format() { - return new Object[][] {{null, "NULL"}, {lineString, "'LINESTRING (30 10, 10 30, 40 40)'"}}; - } - - @DataProvider - public static Object[][] parse() { - return new Object[][] { - {null, null}, - {"", null}, - {" ", null}, - {"NULL", null}, - {" NULL ", null}, - {"'LINESTRING (30 10, 10 30, 40 40)'", lineString}, - {" ' LineString (30 10, 10 30, 40 40 ) ' ", lineString} - }; - } - - @Test - @UseDataProvider("format") - @Override - public void should_format(LineString input, String expected) { - super.should_format(input, expected); - } - - @Test - @UseDataProvider("parse") - @Override - public void should_parse(String input, LineString expected) { - super.should_parse(input, expected); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/type/codec/geometry/PointCodecTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/type/codec/geometry/PointCodecTest.java deleted file mode 100644 index 7948f4d758a..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/type/codec/geometry/PointCodecTest.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.type.codec.geometry; - -import com.datastax.dse.driver.api.core.data.geometry.Point; -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(DataProviderRunner.class) -public class PointCodecTest extends GeometryCodecTest { - - public PointCodecTest() { - super(new PointCodec()); - } - - @DataProvider - public static Object[][] serde() { - return new Object[][] { - {null, null}, - {Point.fromCoordinates(1, 2), Point.fromCoordinates(1, 2)}, - {Point.fromCoordinates(-1.1, -2.2), Point.fromCoordinates(-1.1, -2.2)} - }; - } - - @DataProvider - public static Object[][] format() { - return new Object[][] { - {null, "NULL"}, - {Point.fromCoordinates(1, 2), "'POINT (1 2)'"}, - {Point.fromCoordinates(-1.1, -2.2), "'POINT (-1.1 -2.2)'"} - }; - } - - @DataProvider - public static Object[][] parse() { - return new Object[][] { - {null, null}, - {"", null}, - {" ", null}, - {"NULL", null}, - {" NULL ", null}, - {"'POINT ( 1 2 )'", Point.fromCoordinates(1, 2)}, - {"'POINT ( 1.0 2.0 )'", Point.fromCoordinates(1, 2)}, - {"' point ( -1.1 -2.2 )'", Point.fromCoordinates(-1.1, -2.2)}, - {" ' Point ( -1.1 -2.2 ) ' ", Point.fromCoordinates(-1.1, -2.2)} - }; - } - - @Test - @UseDataProvider("format") - @Override - public void should_format(Point input, String expected) { - super.should_format(input, expected); - } - - @Test - @UseDataProvider("parse") - @Override - public void should_parse(String input, Point expected) { - super.should_parse(input, expected); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/type/codec/geometry/PolygonCodecTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/type/codec/geometry/PolygonCodecTest.java deleted file mode 100644 index 290dabe7519..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/type/codec/geometry/PolygonCodecTest.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.type.codec.geometry; - -import com.datastax.dse.driver.api.core.data.geometry.Polygon; -import com.datastax.dse.driver.internal.core.data.geometry.DefaultPoint; -import com.datastax.dse.driver.internal.core.data.geometry.DefaultPolygon; -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(DataProviderRunner.class) -public class PolygonCodecTest extends GeometryCodecTest { - private static Polygon polygon = - new DefaultPolygon( - new DefaultPoint(30, 10), - new DefaultPoint(10, 20), - new DefaultPoint(20, 40), - new DefaultPoint(40, 40)); - - public PolygonCodecTest() { - super(new PolygonCodec()); - } - - @DataProvider - public static Object[][] serde() { - return new Object[][] {{null, null}, {polygon, polygon}}; - } - - @DataProvider - public static Object[][] format() { - return new Object[][] { - {null, "NULL"}, {polygon, "'POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))'"} - }; - } - - @DataProvider - public static Object[][] parse() { - return new Object[][] { - {null, null}, - {"", null}, - {" ", null}, - {"NULL", null}, - {" NULL ", null}, - {"'POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))'", polygon}, - {" ' Polygon ( ( 30 10, 40 40, 20 40, 10 20, 30 10 ) ) ' ", polygon} - }; - } - - @Test - @UseDataProvider("format") - @Override - public void should_format(Polygon input, String expected) { - super.should_format(input, expected); - } - - @Test - @UseDataProvider("parse") - @Override - public void should_parse(String input, Polygon expected) { - super.should_parse(input, expected); - } -} diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/type/codec/time/DateRangeCodecTest.java b/core/src/test/java/com/datastax/dse/driver/internal/core/type/codec/time/DateRangeCodecTest.java deleted file mode 100644 index b9b618b8dd3..00000000000 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/type/codec/time/DateRangeCodecTest.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.core.type.codec.time; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.dse.driver.api.core.data.time.DateRange; -import com.datastax.dse.driver.api.core.type.codec.DseTypeCodecs; -import com.datastax.oss.driver.api.core.ProtocolVersion; -import com.datastax.oss.driver.api.core.type.codec.TypeCodec; -import com.datastax.oss.driver.shaded.guava.common.base.MoreObjects; -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import java.nio.ByteBuffer; -import java.text.ParseException; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(DataProviderRunner.class) -public class DateRangeCodecTest { - - @Test - @UseDataProvider("dateRanges") - public void should_encode_and_decode(DateRange dateRange) { - TypeCodec codec = DseTypeCodecs.DATE_RANGE; - DateRange decoded = - codec.decode(codec.encode(dateRange, ProtocolVersion.DEFAULT), ProtocolVersion.DEFAULT); - assertThat(decoded).isEqualTo(dateRange); - } - - @Test(expected = IllegalArgumentException.class) - public void should_fail_to_encode_unknown_date_range_type() { - DseTypeCodecs.DATE_RANGE.decode(ByteBuffer.wrap(new byte[] {127}), ProtocolVersion.DEFAULT); - } - - @Test - @UseDataProvider("dateRangeStrings") - public void should_format_and_parse(String dateRangeString) { - TypeCodec codec = DseTypeCodecs.DATE_RANGE; - String formatted = codec.format(codec.parse(dateRangeString)); - assertThat(formatted).isEqualTo(MoreObjects.firstNonNull(dateRangeString, "NULL")); - } - - @Test(expected = IllegalArgumentException.class) - public void should_fail_to_parse_invalid_string() { - DseTypeCodecs.DATE_RANGE.parse("foo"); - } - - @DataProvider - public static Object[][] dateRanges() throws ParseException { - return new Object[][] { - {null}, - {DateRange.parse("[2011-01 TO 2015]")}, - {DateRange.parse("[2010-01-02 TO 2015-05-05T13]")}, - {DateRange.parse("[1973-06-30T13:57:28.123Z TO 1999-05-05T14:14:59]")}, - {DateRange.parse("[2010-01-01T15 TO 2016-02]")}, - {DateRange.parse("[1500 TO 1501]")}, - {DateRange.parse("[0001-01-01 TO 0001-01-01]")}, - {DateRange.parse("[0001-01-01 TO 0001-01-02]")}, - {DateRange.parse("[0000-01-01 TO 0000-01-01]")}, - {DateRange.parse("[0000-01-01 TO 0000-01-02]")}, - {DateRange.parse("[-0001-01-01 TO -0001-01-01]")}, - {DateRange.parse("[-0001-01-01 TO -0001-01-02]")}, - {DateRange.parse("[* TO 2014-12-01]")}, - {DateRange.parse("[1999 TO *]")}, - {DateRange.parse("[* TO *]")}, - {DateRange.parse("-0009")}, - {DateRange.parse("2000-11")}, - {DateRange.parse("*")} - }; - } - - @DataProvider - public static Object[][] dateRangeStrings() { - return new Object[][] { - {null}, - {"NULL"}, - {"'[2011-01 TO 2015]'"}, - {"'[2010-01-02 TO 2015-05-05T13]'"}, - {"'[1973-06-30T13:57:28.123Z TO 1999-05-05T14:14:59]'"}, - {"'[2010-01-01T15 TO 2016-02]'"}, - {"'[1500 TO 1501]'"}, - {"'[0001-01-01 TO 0001-01-01]'"}, - {"'[0001-01-01 TO 0001-01-02]'"}, - {"'[0000-01-01 TO 0000-01-01]'"}, - {"'[0000-01-01 TO 0000-01-02]'"}, - {"'[-0001-01-01 TO -0001-01-01]'"}, - {"'[-0001-01-01 TO -0001-01-02]'"}, - {"'[* TO 2014-12-01]'"}, - {"'[1999 TO *]'"}, - {"'[* TO *]'"}, - {"'-0009'"}, - {"'2000-11'"}, - {"'*'"} - }; - } -} diff --git a/core/src/test/java/com/datastax/oss/driver/api/core/VersionAssert.java b/core/src/test/java/com/datastax/oss/driver/api/core/VersionAssert.java index 61beb5cea51..3bde86cd179 100644 --- a/core/src/test/java/com/datastax/oss/driver/api/core/VersionAssert.java +++ b/core/src/test/java/com/datastax/oss/driver/api/core/VersionAssert.java @@ -34,8 +34,8 @@ public VersionAssert hasMajorMinorPatch(int major, int minor, int patch) { return this; } - public VersionAssert hasDsePatch(int dsePatch) { - assertThat(actual.getDSEPatch()).isEqualTo(dsePatch); + public VersionAssert hasRevision(int revision) { + assertThat(actual.getRevision()).isEqualTo(revision); return this; } diff --git a/core/src/test/java/com/datastax/oss/driver/api/core/VersionTest.java b/core/src/test/java/com/datastax/oss/driver/api/core/VersionTest.java index ade7107fb49..e6f67bf9905 100644 --- a/core/src/test/java/com/datastax/oss/driver/api/core/VersionTest.java +++ b/core/src/test/java/com/datastax/oss/driver/api/core/VersionTest.java @@ -19,15 +19,28 @@ import static com.datastax.oss.driver.Assertions.assertThat; +import com.datastax.oss.driver.internal.SerializationHelper; +import java.util.Base64; import org.junit.Test; public class VersionTest { + // Serialized with java-driver-core 4.19.2.1. Keep these fixtures immutable so this test detects + // accidental changes to Version's serialized field names. + private static final String SERIALIZED_WITHOUT_REVISION = + "rO0ABXNyAChjb20uZGF0YXN0YXgub3NzLmRyaXZlci5hcGkuY29yZS5WZXJzaW9uAAAAAAAAAAECAAZJ" + + "AAhkc2VQYXRjaEkABW1ham9ySQAFbWlub3JJAAVwYXRjaEwABWJ1aWxkdAASTGphdmEvbGFuZy9TdHJp" + + "bmc7WwALcHJlUmVsZWFzZXN0ABNbTGphdmEvbGFuZy9TdHJpbmc7eHD/////AAAABAAAABMAAAACcHA="; + private static final String SERIALIZED_WITH_REVISION = + "rO0ABXNyAChjb20uZGF0YXN0YXgub3NzLmRyaXZlci5hcGkuY29yZS5WZXJzaW9uAAAAAAAAAAECAAZJ" + + "AAhkc2VQYXRjaEkABW1ham9ySQAFbWlub3JJAAVwYXRjaEwABWJ1aWxkdAASTGphdmEvbGFuZy9TdHJp" + + "bmc7WwALcHJlUmVsZWFzZXN0ABNbTGphdmEvbGFuZy9TdHJpbmc7eHAAAAABAAAABAAAABMAAAACcHA="; + @Test public void should_parse_release_version() { assertThat(Version.parse("1.2.19")) .hasMajorMinorPatch(1, 2, 19) - .hasDsePatch(-1) + .hasRevision(-1) .hasNoPreReleaseLabels() .hasBuildLabel(null) .hasNextStable("1.2.19") @@ -43,7 +56,7 @@ public void should_parse_release_without_patch() { public void should_parse_pre_release_version() { assertThat(Version.parse("1.2.0-beta1-SNAPSHOT")) .hasMajorMinorPatch(1, 2, 0) - .hasDsePatch(-1) + .hasRevision(-1) .hasPreReleaseLabels("beta1", "SNAPSHOT") .hasBuildLabel(null) .hasToString("1.2.0-beta1-SNAPSHOT") @@ -54,7 +67,7 @@ public void should_parse_pre_release_version() { public void should_allow_tilde_as_first_pre_release_delimiter() { assertThat(Version.parse("1.2.0~beta1-SNAPSHOT")) .hasMajorMinorPatch(1, 2, 0) - .hasDsePatch(-1) + .hasRevision(-1) .hasPreReleaseLabels("beta1", "SNAPSHOT") .hasBuildLabel(null) .hasToString("1.2.0-beta1-SNAPSHOT") @@ -62,12 +75,24 @@ public void should_allow_tilde_as_first_pre_release_delimiter() { } @Test - public void should_parse_dse_patch() { - assertThat(Version.parse("1.2.19.2-SNAPSHOT")) - .hasMajorMinorPatch(1, 2, 19) - .hasDsePatch(2) - .hasToString("1.2.19.2-SNAPSHOT") - .hasNextStable("1.2.19.2"); + public void should_parse_revision() { + assertThat(Version.parse("4.19.2.2-SNAPSHOT")) + .hasMajorMinorPatch(4, 19, 2) + .hasRevision(2) + .hasToString("4.19.2.2-SNAPSHOT") + .hasNextStable("4.19.2.2"); + } + + @Test + public void should_deserialize_versions_from_4_19_2_1() { + assertThat(deserializeFixture(SERIALIZED_WITHOUT_REVISION)) + .hasMajorMinorPatch(4, 19, 2) + .hasRevision(-1) + .hasToString("4.19.2"); + assertThat(deserializeFixture(SERIALIZED_WITH_REVISION)) + .hasMajorMinorPatch(4, 19, 2) + .hasRevision(1) + .hasToString("4.19.2.1"); } @Test @@ -90,7 +115,7 @@ public void should_order_versions() { assertOrder("2.0", "2.0.0", 0); assertOrder("2.0", "2.0.1", -1); - // any DSE version is higher than no DSE version + // absent revision vs. present revision assertOrder("2.0.0", "2.0.0.0", -1); assertOrder("2.0.0", "2.0.0.1", -1); @@ -110,4 +135,8 @@ public void should_order_versions() { private void assertOrder(String version1, String version2, int expected) { assertThat(Version.parse(version1).compareTo(Version.parse(version2))).isEqualTo(expected); } + + private Version deserializeFixture(String fixture) { + return SerializationHelper.deserialize(Base64.getDecoder().decode(fixture)); + } } diff --git a/core/src/test/java/com/datastax/oss/driver/api/core/auth/ProgrammaticPlainTextAuthProviderTest.java b/core/src/test/java/com/datastax/oss/driver/api/core/auth/ProgrammaticPlainTextAuthProviderTest.java index 44d2acfbb2e..04a87f7c44b 100644 --- a/core/src/test/java/com/datastax/oss/driver/api/core/auth/ProgrammaticPlainTextAuthProviderTest.java +++ b/core/src/test/java/com/datastax/oss/driver/api/core/auth/ProgrammaticPlainTextAuthProviderTest.java @@ -21,6 +21,7 @@ import com.datastax.oss.driver.api.core.auth.PlainTextAuthProviderBase.Credentials; import com.datastax.oss.driver.api.core.metadata.EndPoint; +import java.nio.ByteBuffer; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -32,29 +33,31 @@ public class ProgrammaticPlainTextAuthProviderTest { @Mock private EndPoint endpoint; @Test - public void should_return_correct_credentials_without_authorization_id() { - // given + public void should_encode_standard_sasl_plain_response() { ProgrammaticPlainTextAuthProvider provider = new ProgrammaticPlainTextAuthProvider("user", "pass"); - // when - Credentials credentials = provider.getCredentials(endpoint, "irrelevant"); - // then - assertThat(credentials.getUsername()).isEqualTo("user".toCharArray()); - assertThat(credentials.getPassword()).isEqualTo("pass".toCharArray()); - assertThat(credentials.getAuthorizationId()).isEqualTo(new char[0]); + + ByteBuffer response = + provider + .newAuthenticator(endpoint, "org.apache.cassandra.auth.PasswordAuthenticator") + .initialResponse() + .toCompletableFuture() + .join(); + + assertThat(response) + .isEqualTo(ByteBuffer.wrap(new byte[] {0, 'u', 's', 'e', 'r', 0, 'p', 'a', 's', 's'})); } @Test - public void should_return_correct_credentials_with_authorization_id() { + public void should_return_correct_credentials() { // given ProgrammaticPlainTextAuthProvider provider = - new ProgrammaticPlainTextAuthProvider("user", "pass", "proxy"); + new ProgrammaticPlainTextAuthProvider("user", "pass"); // when Credentials credentials = provider.getCredentials(endpoint, "irrelevant"); // then assertThat(credentials.getUsername()).isEqualTo("user".toCharArray()); assertThat(credentials.getPassword()).isEqualTo("pass".toCharArray()); - assertThat(credentials.getAuthorizationId()).isEqualTo("proxy".toCharArray()); } @Test @@ -68,7 +71,6 @@ public void should_change_username() { // then assertThat(credentials.getUsername()).isEqualTo("user2".toCharArray()); assertThat(credentials.getPassword()).isEqualTo("pass".toCharArray()); - assertThat(credentials.getAuthorizationId()).isEqualTo(new char[0]); } @Test @@ -82,20 +84,5 @@ public void should_change_password() { // then assertThat(credentials.getUsername()).isEqualTo("user".toCharArray()); assertThat(credentials.getPassword()).isEqualTo("pass2".toCharArray()); - assertThat(credentials.getAuthorizationId()).isEqualTo(new char[0]); - } - - @Test - public void should_change_authorization_id() { - // given - ProgrammaticPlainTextAuthProvider provider = - new ProgrammaticPlainTextAuthProvider("user", "pass", "proxy"); - // when - provider.setAuthorizationId("proxy2"); - Credentials credentials = provider.getCredentials(endpoint, "irrelevant"); - // then - assertThat(credentials.getUsername()).isEqualTo("user".toCharArray()); - assertThat(credentials.getPassword()).isEqualTo("pass".toCharArray()); - assertThat(credentials.getAuthorizationId()).isEqualTo("proxy2".toCharArray()); } } diff --git a/core/src/test/java/com/datastax/oss/driver/api/core/config/TypedDriverOptionTest.java b/core/src/test/java/com/datastax/oss/driver/api/core/config/TypedDriverOptionTest.java index aff83a59880..0e658a78bf6 100644 --- a/core/src/test/java/com/datastax/oss/driver/api/core/config/TypedDriverOptionTest.java +++ b/core/src/test/java/com/datastax/oss/driver/api/core/config/TypedDriverOptionTest.java @@ -19,7 +19,6 @@ import static org.assertj.core.api.Assertions.assertThat; -import com.datastax.dse.driver.api.core.config.DseDriverOption; import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableSet; import java.util.HashSet; import java.util.Set; @@ -50,10 +49,7 @@ public void should_have_equivalents_for_all_builtin_untyped_options() { DefaultDriverOption.CLIENT_ROUTES_ENDPOINTS); for (DriverOption option : - ImmutableSet.builder() - .add(DefaultDriverOption.values()) - .add(DseDriverOption.values()) - .build()) { + ImmutableSet.builder().add(DefaultDriverOption.values()).build()) { if (!exclusions.contains(option)) { assertThat(optionsThatHaveATypedEquivalent) .as( diff --git a/core/src/test/java/com/datastax/oss/driver/internal/core/DefaultProtocolVersionRegistryTest.java b/core/src/test/java/com/datastax/oss/driver/internal/core/DefaultProtocolVersionRegistryTest.java index 1d7cc65d1f2..15c0ee5327b 100644 --- a/core/src/test/java/com/datastax/oss/driver/internal/core/DefaultProtocolVersionRegistryTest.java +++ b/core/src/test/java/com/datastax/oss/driver/internal/core/DefaultProtocolVersionRegistryTest.java @@ -17,8 +17,6 @@ */ package com.datastax.oss.driver.internal.core; -import static com.datastax.dse.driver.api.core.DseProtocolVersion.DSE_V1; -import static com.datastax.dse.driver.api.core.DseProtocolVersion.DSE_V2; import static com.datastax.oss.driver.api.core.ProtocolVersion.V3; import static com.datastax.oss.driver.api.core.ProtocolVersion.V4; import static com.datastax.oss.driver.api.core.ProtocolVersion.V5; @@ -28,14 +26,11 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import com.datastax.dse.driver.api.core.DseProtocolVersion; -import com.datastax.dse.driver.api.core.metadata.DseNodeProperties; import com.datastax.oss.driver.api.core.ProtocolVersion; import com.datastax.oss.driver.api.core.UnsupportedProtocolVersionException; import com.datastax.oss.driver.api.core.Version; import com.datastax.oss.driver.api.core.metadata.Node; import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; import java.util.Optional; import org.junit.Test; import org.mockito.Mockito; @@ -51,17 +46,12 @@ public class DefaultProtocolVersionRegistryTest { @Test public void should_find_version_by_name() { assertThat(registry.fromName("V4")).isEqualTo(ProtocolVersion.V4); - assertThat(registry.fromName("DSE_V1")).isEqualTo(DseProtocolVersion.DSE_V1); } @Test public void should_fail_to_find_version_by_name_different_case() { assertThatThrownBy(() -> registry.fromName("v4")).isInstanceOf(IllegalArgumentException.class); - assertThatThrownBy(() -> registry.fromName("dse_v1")) - .isInstanceOf(IllegalArgumentException.class); - assertThatThrownBy(() -> registry.fromName("dDSE_v1")) - .isInstanceOf(IllegalArgumentException.class); - assertThatThrownBy(() -> registry.fromName("dse_v1")) + assertThatThrownBy(() -> registry.fromName("DSE_V1")) .isInstanceOf(IllegalArgumentException.class); } @@ -77,51 +67,6 @@ public void should_not_downgrade_if_no_lower_version() { assertThat(downgraded.isPresent()).isFalse(); } - @Test - public void should_downgrade_from_dse_to_oss() { - assertThat(registry.downgrade(DseProtocolVersion.DSE_V1).get()).isEqualTo(ProtocolVersion.V5); - } - - @Test - public void should_pick_dse_v2_as_highest_common_when_all_nodes_are_dse_7() { - assertThat(registry.highestCommon(ImmutableList.of(mockDseNode("7.0"), mockDseNode("7.1")))) - .isEqualTo(DseProtocolVersion.DSE_V2); - } - - @Test - public void should_pick_dse_v2_as_highest_common_when_all_nodes_are_dse_6() { - assertThat(registry.highestCommon(ImmutableList.of(mockDseNode("6.0"), mockDseNode("6.1")))) - .isEqualTo(DseProtocolVersion.DSE_V2); - } - - @Test - public void should_pick_dse_v1_as_highest_common_when_all_nodes_are_dse_5_1_or_more() { - assertThat(registry.highestCommon(ImmutableList.of(mockDseNode("5.1"), mockDseNode("6.1")))) - .isEqualTo(DseProtocolVersion.DSE_V1); - } - - @Test - public void should_pick_oss_v4_as_highest_common_when_all_nodes_are_dse_5_or_more() { - assertThat( - registry.highestCommon( - ImmutableList.of(mockDseNode("5.0"), mockDseNode("5.1"), mockDseNode("6.1")))) - .isEqualTo(ProtocolVersion.V4); - } - - @Test - public void should_pick_oss_v3_as_highest_common_when_all_nodes_are_dse_4_7_or_more() { - assertThat( - registry.highestCommon( - ImmutableList.of(mockDseNode("4.7"), mockDseNode("5.1"), mockDseNode("6.1")))) - .isEqualTo(ProtocolVersion.V3); - } - - @Test(expected = UnsupportedProtocolVersionException.class) - public void should_fail_to_pick_highest_common_when_one_node_is_dse_4_6() { - registry.highestCommon( - ImmutableList.of(mockDseNode("4.6"), mockDseNode("5.1"), mockDseNode("6.1"))); - } - @Test(expected = UnsupportedProtocolVersionException.class) public void should_fail_to_pick_highest_common_when_one_node_is_2_0() { registry.highestCommon( @@ -133,8 +78,8 @@ public void should_pick_oss_v3_as_highest_common_when_one_node_is_cassandra_2_1( assertThat( registry.highestCommon( ImmutableList.of( - mockDseNode("5.1"), // oss v4 - mockDseNode("6.1"), // oss v4 + mockCassandraNode("3.11"), // oss v4 + mockCassandraNode("4.0"), // oss v5 mockCassandraNode("2.1") // oss v3 ))) .isEqualTo(ProtocolVersion.V3); @@ -146,8 +91,6 @@ public void should_support_date_type_on_oss_v4_and_later() { assertThat(registry.supports(V4, DATE_TYPE)).isTrue(); assertThat(registry.supports(V5, DATE_TYPE)).isTrue(); assertThat(registry.supports(V6, DATE_TYPE)).isTrue(); - assertThat(registry.supports(DSE_V1, DATE_TYPE)).isTrue(); - assertThat(registry.supports(DSE_V2, DATE_TYPE)).isTrue(); } @Test @@ -156,8 +99,6 @@ public void should_support_smallint_and_tinyint_types_on_oss_v4_and_later() { assertThat(registry.supports(V4, SMALLINT_AND_TINYINT_TYPES)).isTrue(); assertThat(registry.supports(V5, SMALLINT_AND_TINYINT_TYPES)).isTrue(); assertThat(registry.supports(V6, SMALLINT_AND_TINYINT_TYPES)).isTrue(); - assertThat(registry.supports(DSE_V1, SMALLINT_AND_TINYINT_TYPES)).isTrue(); - assertThat(registry.supports(DSE_V2, SMALLINT_AND_TINYINT_TYPES)).isTrue(); } private Node mockCassandraNode(String rawVersion) { @@ -167,29 +108,4 @@ private Node mockCassandraNode(String rawVersion) { } return node; } - - private Node mockDseNode(String rawDseVersion) { - Node node = Mockito.mock(Node.class); - Version dseVersion = Version.parse(rawDseVersion); - Mockito.when(node.getExtras()) - .thenReturn(ImmutableMap.of(DseNodeProperties.DSE_VERSION, dseVersion)); - - Version cassandraVersion; - if (dseVersion.compareTo(DefaultProtocolVersionRegistry.DSE_7_0_0) >= 0) { - cassandraVersion = Version.parse("5.0"); - } else if (dseVersion.compareTo(DefaultProtocolVersionRegistry.DSE_6_0_0) >= 0) { - cassandraVersion = Version.parse("4.0"); - } else if (dseVersion.compareTo(DefaultProtocolVersionRegistry.DSE_5_1_0) >= 0) { - cassandraVersion = Version.parse("3.11"); - } else if (dseVersion.compareTo(DefaultProtocolVersionRegistry.DSE_5_0_0) >= 0) { - cassandraVersion = Version.parse("3.0"); - } else if (dseVersion.compareTo(DefaultProtocolVersionRegistry.DSE_4_7_0) >= 0) { - cassandraVersion = Version.parse("2.1"); - } else { - cassandraVersion = Version.parse("2.0"); - } - Mockito.when(node.getCassandraVersion()).thenReturn(cassandraVersion); - - return node; - } } diff --git a/core/src/test/java/com/datastax/oss/driver/internal/core/config/cloud/CloudConfigFactoryTest.java b/core/src/test/java/com/datastax/oss/driver/internal/core/config/cloud/CloudConfigFactoryTest.java deleted file mode 100644 index a0db82d298e..00000000000 --- a/core/src/test/java/com/datastax/oss/driver/internal/core/config/cloud/CloudConfigFactoryTest.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.oss.driver.internal.core.config.cloud; - -import static com.datastax.oss.driver.Assertions.assertThat; -import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; -import static com.github.tomakehurst.wiremock.client.WireMock.any; -import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; -import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; -import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo; -import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; -import static org.assertj.core.api.Assertions.catchThrowable; - -import com.datastax.oss.driver.internal.core.ssl.SniSslEngineFactory; -import com.fasterxml.jackson.core.JsonParseException; -import com.github.tomakehurst.wiremock.common.JettySettings; -import com.github.tomakehurst.wiremock.core.Options; -import com.github.tomakehurst.wiremock.http.AdminRequestHandler; -import com.github.tomakehurst.wiremock.http.HttpServer; -import com.github.tomakehurst.wiremock.http.HttpServerFactory; -import com.github.tomakehurst.wiremock.http.StubRequestHandler; -import com.github.tomakehurst.wiremock.jetty9.JettyHttpServer; -import com.github.tomakehurst.wiremock.junit.WireMockRule; -import com.google.common.base.Joiner; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.URISyntaxException; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import org.eclipse.jetty.io.NetworkTrafficListener; -import org.eclipse.jetty.server.ConnectionFactory; -import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.server.SslConnectionFactory; -import org.eclipse.jetty.util.ssl.SslContextFactory; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnitRunner; - -@RunWith(MockitoJUnitRunner.class) -public class CloudConfigFactoryTest { - - private static final String BUNDLE_PATH = "/config/cloud/creds.zip"; - - @Rule - public WireMockRule wireMockRule = - new WireMockRule( - wireMockConfig() - .httpsPort(30443) - .dynamicPort() - .httpServerFactory(new HttpsServerFactory()) - .needClientAuth(true) - .keystorePath(path("/config/cloud/identity.jks").toString()) - .keystorePassword("fakePasswordForTests") - .trustStorePath(path("/config/cloud/trustStore.jks").toString()) - .trustStorePassword("fakePasswordForTests2")); - - public CloudConfigFactoryTest() throws URISyntaxException {} - - @Test - public void should_load_config_from_local_filesystem() throws Exception { - // given - URL configFile = getClass().getResource(BUNDLE_PATH); - mockProxyMetadataService(jsonMetadata()); - // when - CloudConfigFactory cloudConfigFactory = new CloudConfigFactory(); - CloudConfig cloudConfig = cloudConfigFactory.createCloudConfig(configFile); - // then - assertCloudConfig(cloudConfig); - } - - @Test - public void should_load_config_from_external_location() throws Exception { - // given - mockHttpSecureBundle(secureBundle()); - mockProxyMetadataService(jsonMetadata()); - // when - URL configFile = new URL("http", "localhost", wireMockRule.port(), BUNDLE_PATH); - CloudConfigFactory cloudConfigFactory = new CloudConfigFactory(); - CloudConfig cloudConfig = cloudConfigFactory.createCloudConfig(configFile); - // then - assertCloudConfig(cloudConfig); - } - - @Test - public void should_throw_when_bundle_not_found() throws Exception { - // given - stubFor(any(urlEqualTo(BUNDLE_PATH)).willReturn(aResponse().withStatus(404))); - // when - URL configFile = new URL("http", "localhost", wireMockRule.port(), BUNDLE_PATH); - CloudConfigFactory cloudConfigFactory = new CloudConfigFactory(); - Throwable t = catchThrowable(() -> cloudConfigFactory.createCloudConfig(configFile)); - assertThat(t) - .isInstanceOf(FileNotFoundException.class) - .hasMessageContaining(configFile.toExternalForm()); - } - - @Test - public void should_throw_when_bundle_not_readable() throws Exception { - // given - mockHttpSecureBundle("not a zip file".getBytes(StandardCharsets.UTF_8)); - // when - URL configFile = new URL("http", "localhost", wireMockRule.port(), BUNDLE_PATH); - CloudConfigFactory cloudConfigFactory = new CloudConfigFactory(); - Throwable t = catchThrowable(() -> cloudConfigFactory.createCloudConfig(configFile)); - assertThat(t) - .isInstanceOf(IllegalStateException.class) - .hasMessageContaining("Invalid bundle: missing file config.json"); - } - - @Test - public void should_throw_when_metadata_not_found() throws Exception { - // given - mockHttpSecureBundle(secureBundle()); - stubFor(any(urlPathEqualTo("/metadata")).willReturn(aResponse().withStatus(404))); - // when - URL configFile = new URL("http", "localhost", wireMockRule.port(), BUNDLE_PATH); - CloudConfigFactory cloudConfigFactory = new CloudConfigFactory(); - Throwable t = catchThrowable(() -> cloudConfigFactory.createCloudConfig(configFile)); - assertThat(t).isInstanceOf(FileNotFoundException.class).hasMessageContaining("metadata"); - } - - @Test - public void should_throw_when_metadata_not_readable() throws Exception { - // given - mockHttpSecureBundle(secureBundle()); - mockProxyMetadataService("not a valid json payload"); - // when - URL configFile = new URL("http", "localhost", wireMockRule.port(), BUNDLE_PATH); - CloudConfigFactory cloudConfigFactory = new CloudConfigFactory(); - Throwable t = catchThrowable(() -> cloudConfigFactory.createCloudConfig(configFile)); - assertThat(t).isInstanceOf(JsonParseException.class).hasMessageContaining("Unrecognized token"); - } - - private void mockHttpSecureBundle(byte[] body) { - stubFor( - any(urlEqualTo(BUNDLE_PATH)) - .willReturn( - aResponse() - .withStatus(200) - .withHeader("Content-Type", "application/octet-stream") - .withBody(body))); - } - - private void mockProxyMetadataService(String jsonMetadata) { - stubFor( - any(urlPathEqualTo("/metadata")) - .willReturn( - aResponse() - .withStatus(200) - .withHeader("Content-Type", "application/json") - .withBody(jsonMetadata))); - } - - private byte[] secureBundle() throws IOException, URISyntaxException { - return Files.readAllBytes(path(BUNDLE_PATH)); - } - - private String jsonMetadata() throws IOException, URISyntaxException { - return Joiner.on('\n') - .join(Files.readAllLines(path("/config/cloud/metadata.json"), StandardCharsets.UTF_8)); - } - - private Path path(String resource) throws URISyntaxException { - return Paths.get(getClass().getResource(resource).toURI()); - } - - private void assertCloudConfig(CloudConfig config) { - InetSocketAddress expectedProxyAddress = InetSocketAddress.createUnresolved("localhost", 30002); - assertThat(config.getLocalDatacenter()).isEqualTo("dc1"); - assertThat(config.getProxyAddress()).isEqualTo(expectedProxyAddress); - assertThat(config.getEndPoints()).extracting("proxyAddress").containsOnly(expectedProxyAddress); - assertThat(config.getEndPoints()) - .extracting("serverName") - .containsExactly( - "4ac06655-f861-49f9-881e-3fee22e69b94", - "2af7c253-3394-4a0d-bfac-f1ad81b5154d", - "b17b6e2a-3f48-4d6a-81c1-20a0a1f3192a"); - assertThat(config.getSslEngineFactory()).isNotNull().isInstanceOf(SniSslEngineFactory.class); - } - - static { - javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier( - (hostname, sslSession) -> hostname.equals("localhost")); - } - - // see https://github.com/tomakehurst/wiremock/issues/874 - private static class HttpsServerFactory implements HttpServerFactory { - @Override - public HttpServer buildHttpServer( - Options options, - AdminRequestHandler adminRequestHandler, - StubRequestHandler stubRequestHandler) { - return new JettyHttpServer(options, adminRequestHandler, stubRequestHandler) { - @Override - protected ServerConnector createServerConnector( - String bindAddress, - JettySettings jettySettings, - int port, - NetworkTrafficListener listener, - ConnectionFactory... connectionFactories) { - if (port == options.httpsSettings().port()) { - SslConnectionFactory sslConnectionFactory = - (SslConnectionFactory) connectionFactories[0]; - SslContextFactory sslContextFactory = sslConnectionFactory.getSslContextFactory(); - sslContextFactory.setKeyStorePassword(options.httpsSettings().keyStorePassword()); - connectionFactories = - new ConnectionFactory[] {sslConnectionFactory, connectionFactories[1]}; - } - return super.createServerConnector( - bindAddress, jettySettings, port, listener, connectionFactories); - } - }; - } - } -} diff --git a/core/src/test/java/com/datastax/oss/driver/internal/core/config/composite/CompositeDriverConfigTest.java b/core/src/test/java/com/datastax/oss/driver/internal/core/config/composite/CompositeDriverConfigTest.java index e5d5ffcdf83..e138b33f58b 100644 --- a/core/src/test/java/com/datastax/oss/driver/internal/core/config/composite/CompositeDriverConfigTest.java +++ b/core/src/test/java/com/datastax/oss/driver/internal/core/config/composite/CompositeDriverConfigTest.java @@ -20,7 +20,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.entry; -import com.datastax.dse.driver.api.core.config.DseDriverOption; import com.datastax.oss.driver.api.core.config.DefaultDriverOption; import com.datastax.oss.driver.api.core.config.DriverConfig; import com.datastax.oss.driver.api.core.config.DriverConfigLoader; @@ -43,10 +42,10 @@ public void setup() { // We need at least one option so that the default profile exists. Do it now to avoid having to // do it in every test. We use an option that we won't reuse in the tests so that there are no // unwanted interactions. - primaryMap.put(TypedDriverOption.CONTINUOUS_PAGING_MAX_PAGES, 1); + primaryMap.put(TypedDriverOption.REQUEST_PAGE_SIZE, 1); fallbackMap = new OptionsMap(); - fallbackMap.put(TypedDriverOption.CONTINUOUS_PAGING_MAX_PAGES, 1); + fallbackMap.put(TypedDriverOption.REQUEST_PAGE_SIZE, 1); DriverConfigLoader compositeLoader = DriverConfigLoader.compose( @@ -66,7 +65,7 @@ public void should_use_value_from_primary_config() { assertThat(compositeDefaultProfile.entrySet()) .containsExactly( entry(DefaultDriverOption.CONNECTION_POOL_LOCAL_SIZE.getPath(), 1), - entry(DseDriverOption.CONTINUOUS_PAGING_MAX_PAGES.getPath(), 1)); + entry(DefaultDriverOption.REQUEST_PAGE_SIZE.getPath(), 1)); } @Test @@ -81,7 +80,7 @@ public void should_ignore_value_from_fallback_config_if_defined_in_both() { assertThat(compositeDefaultProfile.entrySet()) .containsExactly( entry(DefaultDriverOption.CONNECTION_POOL_LOCAL_SIZE.getPath(), 1), - entry(DseDriverOption.CONTINUOUS_PAGING_MAX_PAGES.getPath(), 1)); + entry(DefaultDriverOption.REQUEST_PAGE_SIZE.getPath(), 1)); } @Test @@ -95,7 +94,7 @@ public void should_use_value_from_fallback_config_if_not_defined_in_primary() { assertThat(compositeDefaultProfile.entrySet()) .containsExactly( entry(DefaultDriverOption.CONNECTION_POOL_LOCAL_SIZE.getPath(), 1), - entry(DseDriverOption.CONTINUOUS_PAGING_MAX_PAGES.getPath(), 1)); + entry(DefaultDriverOption.REQUEST_PAGE_SIZE.getPath(), 1)); } @Test @@ -132,16 +131,16 @@ public void should_merge_profiles() { assertThat(compositeConfig.getProfile("onlyInPrimary").entrySet()) .containsExactly( entry(DefaultDriverOption.CONNECTION_POOL_LOCAL_SIZE.getPath(), 1), - entry(DseDriverOption.CONTINUOUS_PAGING_MAX_PAGES.getPath(), 1)); + entry(DefaultDriverOption.REQUEST_PAGE_SIZE.getPath(), 1)); assertThat(compositeConfig.getProfile("inBoth").entrySet()) .containsExactly( entry(DefaultDriverOption.CONNECTION_POOL_LOCAL_SIZE.getPath(), 2), - entry(DseDriverOption.CONTINUOUS_PAGING_MAX_PAGES.getPath(), 1)); + entry(DefaultDriverOption.REQUEST_PAGE_SIZE.getPath(), 1)); assertThat(compositeConfig.getProfile("onlyInFallback").entrySet()) .containsExactly( entry(DefaultDriverOption.CONNECTION_POOL_LOCAL_SIZE.getPath(), 4), - entry(DseDriverOption.CONTINUOUS_PAGING_MAX_PAGES.getPath(), 1)); + entry(DefaultDriverOption.REQUEST_PAGE_SIZE.getPath(), 1)); } } diff --git a/core/src/test/java/com/datastax/oss/driver/internal/core/context/ClientRoutesConfigFromFileTest.java b/core/src/test/java/com/datastax/oss/driver/internal/core/context/ClientRoutesConfigFromFileTest.java index 083302494aa..0c1c570ebee 100644 --- a/core/src/test/java/com/datastax/oss/driver/internal/core/context/ClientRoutesConfigFromFileTest.java +++ b/core/src/test/java/com/datastax/oss/driver/internal/core/context/ClientRoutesConfigFromFileTest.java @@ -27,7 +27,6 @@ import com.datastax.oss.driver.internal.core.config.typesafe.DefaultDriverConfigLoader; import com.datastax.oss.driver.internal.core.metadata.ClientRoutesTopologyMonitor; import com.typesafe.config.ConfigFactory; -import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.List; import org.junit.After; @@ -238,25 +237,6 @@ public void should_allow_client_routes_with_qualified_passthrough_address_transl assertThat(ctx.getTopologyMonitor()).isInstanceOf(ClientRoutesTopologyMonitor.class); } - @Test - public void should_throw_when_secure_connect_bundle_and_client_routes_both_configured() { - ProgrammaticArguments args = - ProgrammaticArguments.builder() - .withCloudProxyAddress(new InetSocketAddress("127.0.0.1", 9042)) - .build(); - DefaultDriverContext ctx = - contextFromHocon( - "advanced.client-routes.endpoints = [" - + " { connection-id = \"11111111-1111-1111-1111-111111111111\" }" - + "]", - args); - - assertThatThrownBy(ctx::getTopologyMonitor) - .isInstanceOf(IllegalStateException.class) - .hasMessageContaining("secure connect bundle") - .hasMessageContaining("client routes"); - } - @Test public void should_throw_when_client_routes_and_unloadable_address_translator_class() { DefaultDriverContext ctx = diff --git a/core/src/test/java/com/datastax/oss/driver/internal/core/context/DefaultDriverConfigReporterTest.java b/core/src/test/java/com/datastax/oss/driver/internal/core/context/DefaultDriverConfigReporterTest.java index 4122f82a399..aa459d1c30d 100644 --- a/core/src/test/java/com/datastax/oss/driver/internal/core/context/DefaultDriverConfigReporterTest.java +++ b/core/src/test/java/com/datastax/oss/driver/internal/core/context/DefaultDriverConfigReporterTest.java @@ -21,8 +21,6 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import com.datastax.dse.driver.internal.core.loadbalancing.DseDcInferringLoadBalancingPolicy; -import com.datastax.dse.driver.internal.core.loadbalancing.DseLoadBalancingPolicy; import com.datastax.oss.driver.api.core.CqlIdentifier; import com.datastax.oss.driver.api.core.config.DefaultDriverOption; import com.datastax.oss.driver.api.core.config.DriverConfig; @@ -51,7 +49,6 @@ import com.datastax.oss.driver.internal.core.specex.NoSpeculativeExecutionPolicy; import com.datastax.oss.driver.internal.core.ssl.DefaultSslEngineFactory; import com.datastax.oss.driver.internal.core.ssl.JdkSslHandlerFactory; -import com.datastax.oss.driver.internal.core.ssl.SniSslEngineFactory; import com.datastax.oss.driver.internal.core.ssl.SslHandlerFactory; import com.datastax.oss.driver.internal.core.time.AtomicTimestampGenerator; import com.datastax.oss.driver.internal.core.time.ServerSideTimestampGenerator; @@ -699,45 +696,6 @@ public void should_report_dc_inferring_load_balancing_policy() throws Exception report(r).get("query").get("load-balancing").get("policy"), /* adaptiveOrdering= */ true); } - @Test - public void should_report_dse_load_balancing_policy_as_a_built_in() throws Exception { - // DseLoadBalancingPolicy is a deprecated, behavior-identical alias of - // DefaultLoadBalancingPolicy; must not fall through to "custom". Note: a real (non-mocked) - // instance of this class requires a resolvable local DC (it uses MandatoryLocalDcHelper) and - // would fail to construct with no DC configured, unlike DcInferringLoadBalancingPolicy above; - // the mock here bypasses that constructor validation, same as - // should_report_default_configuration. - DefaultDriverConfigReporter r = - reporterWith( - defaults(map -> {}), - exponentialReconnection(), - mock(DefaultRetryPolicy.class), - mock(NoSpeculativeExecutionPolicy.class), - loadBalancing(DseLoadBalancingPolicy.class), - clientSideGenerator(), - Optional.empty()); - assertBuiltInLoadBalancingPolicy( - report(r).get("query").get("load-balancing").get("policy"), /* adaptiveOrdering= */ true); - } - - @Test - public void should_report_dse_dc_inferring_load_balancing_policy_as_a_built_in() - throws Exception { - // DseDcInferringLoadBalancingPolicy is a deprecated, behavior-identical alias of - // DcInferringLoadBalancingPolicy; must not fall through to "custom". - DefaultDriverConfigReporter r = - reporterWith( - defaults(map -> {}), - exponentialReconnection(), - mock(DefaultRetryPolicy.class), - mock(NoSpeculativeExecutionPolicy.class), - loadBalancing(DseDcInferringLoadBalancingPolicy.class), - clientSideGenerator(), - Optional.empty()); - assertBuiltInLoadBalancingPolicy( - report(r).get("query").get("load-balancing").get("policy"), /* adaptiveOrdering= */ true); - } - @Test public void should_report_basic_load_balancing_policy_without_adaptive_ordering() throws Exception { @@ -1534,7 +1492,6 @@ public void should_report_every_built_in_engine_factory() throws Exception { // configured one, to the whole option-to-field-to-report chain. assertThat(hostnameVerificationOf(new DefaultSslEngineFactory(policyConstructionContext()))) .isTrue(); - assertThat(hostnameVerificationOf(new SniSslEngineFactory(SSLContext.getDefault()))).isTrue(); assertThat(hostnameVerificationOf(new ProgrammaticSslEngineFactory(SSLContext.getDefault()))) .isFalse(); assertThat( diff --git a/core/src/test/java/com/datastax/dse/driver/internal/core/context/DseStartupOptionsBuilderTest.java b/core/src/test/java/com/datastax/oss/driver/internal/core/context/StartupOptionsBuilderApplicationTest.java similarity index 92% rename from core/src/test/java/com/datastax/dse/driver/internal/core/context/DseStartupOptionsBuilderTest.java rename to core/src/test/java/com/datastax/oss/driver/internal/core/context/StartupOptionsBuilderApplicationTest.java index 81df53af9a3..a27aea15bb7 100644 --- a/core/src/test/java/com/datastax/dse/driver/internal/core/context/DseStartupOptionsBuilderTest.java +++ b/core/src/test/java/com/datastax/oss/driver/internal/core/context/StartupOptionsBuilderApplicationTest.java @@ -15,14 +15,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.datastax.dse.driver.internal.core.context; +package com.datastax.oss.driver.internal.core.context; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; -import com.datastax.dse.driver.api.core.config.DseDriverOption; import com.datastax.oss.driver.api.core.Version; import com.datastax.oss.driver.api.core.config.DefaultDriverOption; import com.datastax.oss.driver.api.core.config.DriverConfig; @@ -31,8 +30,6 @@ import com.datastax.oss.driver.api.core.session.ProgrammaticArguments; import com.datastax.oss.driver.api.core.session.Session; import com.datastax.oss.driver.api.core.uuid.Uuids; -import com.datastax.oss.driver.internal.core.context.DefaultDriverContext; -import com.datastax.oss.driver.internal.core.context.StartupOptionsBuilder; import com.datastax.oss.protocol.internal.request.Startup; import com.tngtech.java.junit.dataprovider.DataProvider; import com.tngtech.java.junit.dataprovider.DataProviderRunner; @@ -43,11 +40,11 @@ import org.mockito.Mock; @RunWith(DataProviderRunner.class) -public class DseStartupOptionsBuilderTest { +public class StartupOptionsBuilderApplicationTest { private DefaultDriverContext driverContext; - // Mocks for instantiating the DSE driver context + // Mocks for instantiating the driver context @Mock private DriverConfigLoader configLoader; @Mock private DriverConfig driverConfig; @Mock private DriverExecutionProfile defaultProfile; @@ -57,7 +54,6 @@ public void before() { initMocks(this); when(configLoader.getInitialConfig()).thenReturn(driverConfig); when(driverConfig.getDefaultProfile()).thenReturn(defaultProfile); - when(defaultProfile.isDefined(DseDriverOption.CONTINUOUS_PAGING_PAGE_SIZE)).thenReturn(true); } private void buildContext(UUID clientId, String applicationName, String applicationVersion) { @@ -80,7 +76,7 @@ private void assertDefaultStartupOptions(Startup startup) { Version version = Version.parse(startup.options.get(StartupOptionsBuilder.DRIVER_VERSION_KEY)); assertThat(version).isEqualTo(Session.OSS_DRIVER_COORDINATES.getVersion()); assertThat(startup.options).containsKey(StartupOptionsBuilder.CLIENT_ID_KEY); - // SESSION_ID is innate and must survive on the DSE path too. + // SESSION_ID is innate and must survive when application metadata is omitted. assertThat(startup.options).containsKey(StartupOptionsBuilder.SESSION_ID_KEY); } @@ -168,9 +164,9 @@ public void should_build_startup_options_with_all_options() { @Test public void should_use_configuration_when_no_programmatic_values_provided() { - when(defaultProfile.getString(DseDriverOption.APPLICATION_NAME, null)) + when(defaultProfile.getString(DefaultDriverOption.APPLICATION_NAME, null)) .thenReturn("Config_App_Name"); - when(defaultProfile.getString(DseDriverOption.APPLICATION_VERSION, null)) + when(defaultProfile.getString(DefaultDriverOption.APPLICATION_VERSION, null)) .thenReturn("Config_App_Version"); when(defaultProfile.getString(DefaultDriverOption.PROTOCOL_COMPRESSION, "none")) .thenReturn("none"); diff --git a/core/src/test/java/com/datastax/oss/driver/internal/core/loadbalancing/DefaultLoadBalancingPolicyQueryPlanTest.java b/core/src/test/java/com/datastax/oss/driver/internal/core/loadbalancing/DefaultLoadBalancingPolicyQueryPlanTest.java index 0bf7469dfc4..00a888c1a80 100644 --- a/core/src/test/java/com/datastax/oss/driver/internal/core/loadbalancing/DefaultLoadBalancingPolicyQueryPlanTest.java +++ b/core/src/test/java/com/datastax/oss/driver/internal/core/loadbalancing/DefaultLoadBalancingPolicyQueryPlanTest.java @@ -66,7 +66,7 @@ public class DefaultLoadBalancingPolicyQueryPlanTest extends BasicLoadBalancingP long nanoTime; int diceRoll; - private DefaultLoadBalancingPolicy dsePolicy; + private DefaultLoadBalancingPolicy defaultPolicy; @Before @Override @@ -88,10 +88,11 @@ public void setup() { given(metadataManager.getContactPoints()).willReturn(ImmutableSet.of(node1)); given(metadata.getTokenMap()).willAnswer(invocation -> Optional.of(tokenMap)); super.setup(); - dsePolicy = (DefaultLoadBalancingPolicy) policy; - // Note: this assertion relies on the fact that policy.getLiveNodes() implementation preserves + defaultPolicy = (DefaultLoadBalancingPolicy) super.policy; + // Note: this assertion relies on the fact that defaultPolicy.getLiveNodes() implementation + // preserves // insertion order. - assertThat(dsePolicy.getLiveNodes().dc("dc1")) + assertThat(defaultPolicy.getLiveNodes().dc("dc1")) .containsExactly(node1, node2, node3, node4, node5); } @@ -104,9 +105,9 @@ public void should_prioritize_and_shuffle_2_replicas() { .willReturn(ImmutableList.of(node3, node5)); // When - Queue plan1 = dsePolicy.newQueryPlan(request, session); - Queue plan2 = dsePolicy.newQueryPlan(request, session); - Queue plan3 = dsePolicy.newQueryPlan(request, session); + Queue plan1 = defaultPolicy.newQueryPlan(request, session); + Queue plan2 = defaultPolicy.newQueryPlan(request, session); + Queue plan3 = defaultPolicy.newQueryPlan(request, session); // Then // node3 and node5 always first, round-robin on the rest @@ -114,9 +115,9 @@ public void should_prioritize_and_shuffle_2_replicas() { assertThat(plan2).containsExactly(node3, node5, node2, node4, node1); assertThat(plan3).containsExactly(node3, node5, node4, node1, node2); - then(dsePolicy).should(times(3)).shuffleHead(any(), anyInt()); - then(dsePolicy).should(never()).nanoTime(); - then(dsePolicy).should(never()).randomNextInt(4); + then(defaultPolicy).should(times(3)).shuffleHead(any(), anyInt()); + then(defaultPolicy).should(never()).nanoTime(); + then(defaultPolicy).should(never()).randomNextInt(4); } @Test @@ -126,15 +127,15 @@ public void should_prioritize_and_shuffle_3_or_more_replicas_when_all_healthy_an given(request.getRoutingKey()).willReturn(ROUTING_KEY); given(tokenMap.getReplicasList(KEYSPACE, null, ROUTING_KEY)) .willReturn(ImmutableList.of(node1, node3, node5)); - dsePolicy.upTimes.put(node1, T1); - dsePolicy.upTimes.put(node3, T2); - dsePolicy.upTimes.put(node5, T3); // newest up replica + defaultPolicy.upTimes.put(node1, T1); + defaultPolicy.upTimes.put(node3, T2); + defaultPolicy.upTimes.put(node5, T3); // newest up replica given(pool1.getInFlight()).willReturn(0); given(pool3.getInFlight()).willReturn(0); // When - Queue plan1 = dsePolicy.newQueryPlan(request, session); - Queue plan2 = dsePolicy.newQueryPlan(request, session); + Queue plan1 = defaultPolicy.newQueryPlan(request, session); + Queue plan2 = defaultPolicy.newQueryPlan(request, session); // Then // nodes 1, 3 and 5 always first, round-robin on the rest @@ -142,9 +143,9 @@ public void should_prioritize_and_shuffle_3_or_more_replicas_when_all_healthy_an assertThat(plan1).containsExactly(node1, node3, node5, node2, node4); assertThat(plan2).containsExactly(node1, node3, node5, node4, node2); - then(dsePolicy).should(times(2)).shuffleHead(any(), anyInt()); - then(dsePolicy).should(times(2)).nanoTime(); - then(dsePolicy).should(never()).randomNextInt(4); + then(defaultPolicy).should(times(2)).shuffleHead(any(), anyInt()); + then(defaultPolicy).should(times(2)).nanoTime(); + then(defaultPolicy).should(never()).randomNextInt(4); } @Test @@ -155,14 +156,14 @@ public void should_prioritize_and_shuffle_3_or_more_replicas_when_all_healthy_an given(request.getRoutingKey()).willReturn(ROUTING_KEY); given(tokenMap.getReplicasList(KEYSPACE, null, ROUTING_KEY)) .willReturn(ImmutableList.of(node1, node3, node5)); - dsePolicy.upTimes.put(node1, T2); // newest up replica - dsePolicy.upTimes.put(node3, T1); + defaultPolicy.upTimes.put(node1, T2); // newest up replica + defaultPolicy.upTimes.put(node3, T1); given(pool3.getInFlight()).willReturn(0); given(pool5.getInFlight()).willReturn(0); // When - Queue plan1 = dsePolicy.newQueryPlan(request, session); - Queue plan2 = dsePolicy.newQueryPlan(request, session); + Queue plan1 = defaultPolicy.newQueryPlan(request, session); + Queue plan2 = defaultPolicy.newQueryPlan(request, session); // Then // nodes 1, 3 and 5 always first, round-robin on the rest @@ -170,9 +171,9 @@ public void should_prioritize_and_shuffle_3_or_more_replicas_when_all_healthy_an assertThat(plan1).containsExactly(node3, node5, node1, node2, node4); assertThat(plan2).containsExactly(node3, node5, node1, node4, node2); - then(dsePolicy).should(times(2)).shuffleHead(any(), anyInt()); - then(dsePolicy).should(times(2)).nanoTime(); - then(dsePolicy).should(times(2)).randomNextInt(4); + then(defaultPolicy).should(times(2)).shuffleHead(any(), anyInt()); + then(defaultPolicy).should(times(2)).nanoTime(); + then(defaultPolicy).should(times(2)).randomNextInt(4); } @Test @@ -183,15 +184,15 @@ public void should_prioritize_and_shuffle_3_or_more_replicas_when_all_healthy_an given(request.getRoutingKey()).willReturn(ROUTING_KEY); given(tokenMap.getReplicasList(KEYSPACE, null, ROUTING_KEY)) .willReturn(ImmutableList.of(node1, node3, node5)); - dsePolicy.upTimes.put(node1, T2); // newest up replica - dsePolicy.upTimes.put(node3, T1); + defaultPolicy.upTimes.put(node1, T2); // newest up replica + defaultPolicy.upTimes.put(node3, T1); given(pool1.getInFlight()).willReturn(0); given(pool3.getInFlight()).willReturn(0); diceRoll = 1; // When - Queue plan1 = dsePolicy.newQueryPlan(request, session); - Queue plan2 = dsePolicy.newQueryPlan(request, session); + Queue plan1 = defaultPolicy.newQueryPlan(request, session); + Queue plan2 = defaultPolicy.newQueryPlan(request, session); // Then // nodes 1, 3 and 5 always first, round-robin on the rest @@ -199,9 +200,9 @@ public void should_prioritize_and_shuffle_3_or_more_replicas_when_all_healthy_an assertThat(plan1).containsExactly(node1, node3, node5, node2, node4); assertThat(plan2).containsExactly(node1, node3, node5, node4, node2); - then(dsePolicy).should(times(2)).shuffleHead(any(), anyInt()); - then(dsePolicy).should(times(2)).nanoTime(); - then(dsePolicy).should(times(2)).randomNextInt(4); + then(defaultPolicy).should(times(2)).shuffleHead(any(), anyInt()); + then(defaultPolicy).should(times(2)).nanoTime(); + then(defaultPolicy).should(times(2)).randomNextInt(4); } @Test @@ -215,14 +216,14 @@ public void should_prioritize_and_shuffle_3_or_more_replicas_when_first_unhealth given(pool3.getInFlight()).willReturn(0); given(pool5.getInFlight()).willReturn(0); - dsePolicy.responseTimes.put( + defaultPolicy.responseTimes.put( node1, - dsePolicy + defaultPolicy .new NodeResponseRateSample(new AtomicLongArray(new long[] {T0, T0}))); // unhealthy // When - Queue plan1 = dsePolicy.newQueryPlan(request, session); - Queue plan2 = dsePolicy.newQueryPlan(request, session); + Queue plan1 = defaultPolicy.newQueryPlan(request, session); + Queue plan2 = defaultPolicy.newQueryPlan(request, session); // Then // nodes 1, 3 and 5 always first, round-robin on the rest @@ -230,9 +231,9 @@ public void should_prioritize_and_shuffle_3_or_more_replicas_when_first_unhealth assertThat(plan1).containsExactly(node3, node5, node1, node2, node4); assertThat(plan2).containsExactly(node3, node5, node1, node4, node2); - then(dsePolicy).should(times(2)).shuffleHead(any(), anyInt()); - then(dsePolicy).should(times(2)).nanoTime(); - then(dsePolicy).should(never()).randomNextInt(4); + then(defaultPolicy).should(times(2)).shuffleHead(any(), anyInt()); + then(defaultPolicy).should(times(2)).nanoTime(); + then(defaultPolicy).should(never()).randomNextInt(4); } @Test @@ -247,13 +248,14 @@ public void should_prioritize_and_shuffle_3_or_more_replicas_when_first_unhealth given(pool3.getInFlight()).willReturn(0); given(pool5.getInFlight()).willReturn(0); - dsePolicy.responseTimes.put( + defaultPolicy.responseTimes.put( node1, - dsePolicy.new NodeResponseRateSample(new AtomicLongArray(new long[] {T1, T1}))); // healthy + defaultPolicy + .new NodeResponseRateSample(new AtomicLongArray(new long[] {T1, T1}))); // healthy // When - Queue plan1 = dsePolicy.newQueryPlan(request, session); - Queue plan2 = dsePolicy.newQueryPlan(request, session); + Queue plan1 = defaultPolicy.newQueryPlan(request, session); + Queue plan2 = defaultPolicy.newQueryPlan(request, session); // Then // nodes 1, 3 and 5 always first, round-robin on the rest @@ -261,9 +263,9 @@ public void should_prioritize_and_shuffle_3_or_more_replicas_when_first_unhealth assertThat(plan1).containsExactly(node3, node1, node5, node2, node4); assertThat(plan2).containsExactly(node3, node1, node5, node4, node2); - then(dsePolicy).should(times(2)).shuffleHead(any(), anyInt()); - then(dsePolicy).should(times(2)).nanoTime(); - then(dsePolicy).should(never()).randomNextInt(4); + then(defaultPolicy).should(times(2)).shuffleHead(any(), anyInt()); + then(defaultPolicy).should(times(2)).nanoTime(); + then(defaultPolicy).should(never()).randomNextInt(4); } @Test @@ -278,8 +280,8 @@ public void should_prioritize_and_shuffle_3_or_more_replicas_when_last_unhealthy given(pool5.getInFlight()).willReturn(100); // unhealthy // When - Queue plan1 = dsePolicy.newQueryPlan(request, session); - Queue plan2 = dsePolicy.newQueryPlan(request, session); + Queue plan1 = defaultPolicy.newQueryPlan(request, session); + Queue plan2 = defaultPolicy.newQueryPlan(request, session); // Then // nodes 1, 3 and 5 always first, round-robin on the rest @@ -287,9 +289,9 @@ public void should_prioritize_and_shuffle_3_or_more_replicas_when_last_unhealthy assertThat(plan1).containsExactly(node1, node3, node5, node2, node4); assertThat(plan2).containsExactly(node1, node3, node5, node4, node2); - then(dsePolicy).should(times(2)).shuffleHead(any(), anyInt()); - then(dsePolicy).should(times(2)).nanoTime(); - then(dsePolicy).should(never()).randomNextInt(4); + then(defaultPolicy).should(times(2)).shuffleHead(any(), anyInt()); + then(defaultPolicy).should(times(2)).nanoTime(); + then(defaultPolicy).should(never()).randomNextInt(4); } @Test @@ -304,8 +306,8 @@ public void should_prioritize_and_shuffle_3_or_more_replicas_when_majority_unhea given(pool5.getInFlight()).willReturn(0); // When - Queue plan1 = dsePolicy.newQueryPlan(request, session); - Queue plan2 = dsePolicy.newQueryPlan(request, session); + Queue plan1 = defaultPolicy.newQueryPlan(request, session); + Queue plan2 = defaultPolicy.newQueryPlan(request, session); // Then // nodes 1, 3 and 5 always first, round-robin on the rest @@ -313,9 +315,9 @@ public void should_prioritize_and_shuffle_3_or_more_replicas_when_majority_unhea assertThat(plan1).containsExactly(node1, node3, node5, node2, node4); assertThat(plan2).containsExactly(node1, node3, node5, node4, node2); - then(dsePolicy).should(times(2)).shuffleHead(any(), anyInt()); - then(dsePolicy).should(times(2)).nanoTime(); - then(dsePolicy).should(never()).randomNextInt(4); + then(defaultPolicy).should(times(2)).shuffleHead(any(), anyInt()); + then(defaultPolicy).should(times(2)).nanoTime(); + then(defaultPolicy).should(never()).randomNextInt(4); } @Test @@ -329,8 +331,8 @@ public void should_reorder_first_two_replicas_when_first_has_more_in_flight_than given(pool3.getInFlight()).willReturn(100); // When - Queue plan1 = dsePolicy.newQueryPlan(request, session); - Queue plan2 = dsePolicy.newQueryPlan(request, session); + Queue plan1 = defaultPolicy.newQueryPlan(request, session); + Queue plan2 = defaultPolicy.newQueryPlan(request, session); // Then // nodes 1, 3 and 5 always first, round-robin on the rest @@ -338,9 +340,9 @@ public void should_reorder_first_two_replicas_when_first_has_more_in_flight_than assertThat(plan1).containsExactly(node3, node1, node5, node2, node4); assertThat(plan2).containsExactly(node3, node1, node5, node4, node2); - then(dsePolicy).should(times(2)).shuffleHead(any(), anyInt()); - then(dsePolicy).should(times(2)).nanoTime(); - then(dsePolicy).should(never()).randomNextInt(4); + then(defaultPolicy).should(times(2)).shuffleHead(any(), anyInt()); + then(defaultPolicy).should(times(2)).nanoTime(); + then(defaultPolicy).should(never()).randomNextInt(4); } @Test @@ -351,15 +353,15 @@ public void should_not_shuffle_local_rack_replica_with_all_replicas_healthy() { given(tokenMap.getReplicasList(KEYSPACE, null, ROUTING_KEY)) .willReturn(ImmutableList.of(node1, node3, node5)); String localRack = "rack1"; - given(dsePolicy.getLocalRack()).willReturn(localRack); + given(defaultPolicy.getLocalRack()).willReturn(localRack); given(node1.getRack()).willReturn(localRack); given(pool1.getInFlight()).willReturn(0); given(pool3.getInFlight()).willReturn(0); given(pool5.getInFlight()).willReturn(0); // When - Queue plan1 = dsePolicy.newQueryPlan(request, session); - Queue plan2 = dsePolicy.newQueryPlan(request, session); + Queue plan1 = defaultPolicy.newQueryPlan(request, session); + Queue plan2 = defaultPolicy.newQueryPlan(request, session); // Then // nodes 1, 3 and 5 always first, round-robin on the rest @@ -375,7 +377,7 @@ public void should_prefer_local_rack_replica_with_less_inflight_requests() { given(tokenMap.getReplicasList(KEYSPACE, null, ROUTING_KEY)) .willReturn(ImmutableList.of(node1, node3, node5)); String localRack = "rack1"; - given(dsePolicy.getLocalRack()).willReturn(localRack); + given(defaultPolicy.getLocalRack()).willReturn(localRack); given(node3.getRack()).willReturn(localRack); given(node5.getRack()).willReturn(localRack); given(pool1.getInFlight()).willReturn(0); @@ -383,8 +385,8 @@ public void should_prefer_local_rack_replica_with_less_inflight_requests() { given(pool5.getInFlight()).willReturn(10); // When - Queue plan1 = dsePolicy.newQueryPlan(request, session); - Queue plan2 = dsePolicy.newQueryPlan(request, session); + Queue plan1 = defaultPolicy.newQueryPlan(request, session); + Queue plan2 = defaultPolicy.newQueryPlan(request, session); // Then assertThat(plan1).containsExactly(node5, node3, node1, node2, node4); @@ -401,7 +403,7 @@ public void should_ignore_local_rack_prioritization_for_lwt_requests() { .willReturn(ImmutableList.of(node1, node3, node5)); String localRack = "rack1"; - given(dsePolicy.getLocalRack()).willReturn(localRack); + given(defaultPolicy.getLocalRack()).willReturn(localRack); // Only node1 is in the local rack given(node1.getRack()).willReturn(localRack); given(node3.getRack()).willReturn("rack2"); @@ -412,15 +414,15 @@ public void should_ignore_local_rack_prioritization_for_lwt_requests() { given(pool5.getInFlight()).willReturn(0); // When - Queue plan1 = dsePolicy.newQueryPlan(request, session); - Queue plan2 = dsePolicy.newQueryPlan(request, session); + Queue plan1 = defaultPolicy.newQueryPlan(request, session); + Queue plan2 = defaultPolicy.newQueryPlan(request, session); - // Then - for LWT requests (RequestRoutingType.LWT) the policy should ignore local rack + // Then - for LWT requests (RequestRoutingType.LWT) the defaultPolicy should ignore local rack // prioritization and preserve the replica order returned by the token map. // The shuffle methods are still invoked for the non-replica range, so only the non-replica // nodes (node2 and node4) are permuted between successive plans. - then(dsePolicy).should(times(2)).shuffleHead(any(), anyInt()); - then(dsePolicy).should(times(2)).shuffleInRange(any(), anyInt(), anyInt()); + then(defaultPolicy).should(times(2)).shuffleHead(any(), anyInt()); + then(defaultPolicy).should(times(2)).shuffleInRange(any(), anyInt(), anyInt()); assertThat(plan1).containsExactly(node1, node3, node5, node2, node4); assertThat(plan2).containsExactly(node1, node3, node5, node4, node2); } @@ -436,7 +438,7 @@ public void should_respect_local_rack_prioritization_for_regular_requests() { .willReturn(ImmutableList.of(node1, node3, node5)); String localRack = "rack1"; - given(dsePolicy.getLocalRack()).willReturn(localRack); + given(defaultPolicy.getLocalRack()).willReturn(localRack); // node1 is in the local rack given(node1.getRack()).willReturn(localRack); given(node3.getRack()).willReturn("rack2"); @@ -447,20 +449,20 @@ public void should_respect_local_rack_prioritization_for_regular_requests() { given(pool5.getInFlight()).willReturn(0); // When - Queue plan1 = dsePolicy.newQueryPlan(request, session); - Queue plan2 = dsePolicy.newQueryPlan(request, session); + Queue plan1 = defaultPolicy.newQueryPlan(request, session); + Queue plan2 = defaultPolicy.newQueryPlan(request, session); // Then - local rack replica prioritized and shuffled separately from others // Verify that local rack replicas and non-local-rack replicas are shuffled separately - then(dsePolicy).should(times(2)).shuffleHead(any(), anyInt()); - then(dsePolicy).should(times(2)).shuffleInRange(any(), anyInt(), anyInt()); + then(defaultPolicy).should(times(2)).shuffleHead(any(), anyInt()); + then(defaultPolicy).should(times(2)).shuffleInRange(any(), anyInt(), anyInt()); assertThat(plan1).containsExactly(node1, node3, node5, node2, node4); assertThat(plan2).containsExactly(node1, node3, node5, node4, node2); } @Override protected DefaultLoadBalancingPolicy createAndInitPolicy() { - DefaultLoadBalancingPolicy policy = + DefaultLoadBalancingPolicy defaultPolicy = spy( new DefaultLoadBalancingPolicy(context, DEFAULT_NAME) { @Override @@ -479,7 +481,7 @@ protected int randomNextInt(int bound) { return diceRoll; } }); - policy.init( + defaultPolicy.init( ImmutableMap.of( UUID.randomUUID(), node1, UUID.randomUUID(), node2, @@ -487,6 +489,6 @@ protected int randomNextInt(int bound) { UUID.randomUUID(), node4, UUID.randomUUID(), node5), distanceReporter); - return policy; + return defaultPolicy; } } diff --git a/core/src/test/java/com/datastax/oss/driver/internal/core/metadata/DefaultTopologyMonitorTest.java b/core/src/test/java/com/datastax/oss/driver/internal/core/metadata/DefaultTopologyMonitorTest.java index 892715a47c3..adf3bc82d62 100644 --- a/core/src/test/java/com/datastax/oss/driver/internal/core/metadata/DefaultTopologyMonitorTest.java +++ b/core/src/test/java/com/datastax/oss/driver/internal/core/metadata/DefaultTopologyMonitorTest.java @@ -51,7 +51,6 @@ import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableSet; -import com.datastax.oss.driver.shaded.guava.common.collect.Maps; import com.datastax.oss.protocol.internal.Message; import com.datastax.oss.protocol.internal.ProtocolConstants; import com.datastax.oss.protocol.internal.response.Error; @@ -549,72 +548,6 @@ public void should_get_peer_address_info_peers_v2() { }); } - // Confirm the base case of extracting peer info from DSE peers table, no SSL involved - @Test - public void should_get_peer_address_info_peers_dse() { - // Given - AdminRow local = mockLocalRow(1, node1.getHostId()); - AdminRow peer2 = mockPeersRowDse(3, node2.getHostId()); - AdminRow peer1 = mockPeersRowDse(2, node1.getHostId()); - topologyMonitor.isSchemaV2 = true; - topologyMonitor.stubQueries( - new StubbedQuery("SELECT * FROM system.local WHERE key='local'", mockResult(local)), - new StubbedQuery("SELECT * FROM system.peers_v2", Maps.newHashMap(), null, true), - new StubbedQuery("SELECT * FROM system.peers", mockResult(peer2, peer1))); - when(context.getSslEngineFactory()).thenReturn(Optional.empty()); - - // When - CompletionStage> futureInfos = topologyMonitor.refreshNodeList(); - - // Then - assertThatStage(futureInfos) - .isSuccess( - infos -> { - Iterator iterator = infos.iterator(); - // First NodeInfo is for local, skip past that - iterator.next(); - NodeInfo peer2nodeInfo = iterator.next(); - assertThat(peer2nodeInfo.getEndPoint().resolve()) - .isEqualTo(new InetSocketAddress("127.0.0.3", 9042)); - NodeInfo peer1nodeInfo = iterator.next(); - assertThat(peer1nodeInfo.getEndPoint().resolve()) - .isEqualTo(new InetSocketAddress("127.0.0.2", 9042)); - }); - } - - // Confirm the base case of extracting peer info from DSE peers table, this time with SSL - @Test - public void should_get_peer_address_info_peers_dse_with_ssl() { - // Given - AdminRow local = mockLocalRow(1, node1.getHostId()); - AdminRow peer2 = mockPeersRowDseWithSsl(3, node2.getHostId()); - AdminRow peer1 = mockPeersRowDseWithSsl(2, node1.getHostId()); - topologyMonitor.isSchemaV2 = true; - topologyMonitor.stubQueries( - new StubbedQuery("SELECT * FROM system.local WHERE key='local'", mockResult(local)), - new StubbedQuery("SELECT * FROM system.peers_v2", Maps.newHashMap(), null, true), - new StubbedQuery("SELECT * FROM system.peers", mockResult(peer2, peer1))); - when(context.getSslEngineFactory()).thenReturn(Optional.of(sslEngineFactory)); - - // When - CompletionStage> futureInfos = topologyMonitor.refreshNodeList(); - - // Then - assertThatStage(futureInfos) - .isSuccess( - infos -> { - Iterator iterator = infos.iterator(); - // First NodeInfo is for local, skip past that - iterator.next(); - NodeInfo peer2nodeInfo = iterator.next(); - assertThat(peer2nodeInfo.getEndPoint().resolve()) - .isEqualTo(new InetSocketAddress("127.0.0.3", 9043)); - NodeInfo peer1nodeInfo = iterator.next(); - assertThat(peer1nodeInfo.getEndPoint().resolve()) - .isEqualTo(new InetSocketAddress("127.0.0.2", 9043)); - }); - } - @Test public void should_use_projected_query_on_second_refresh_node_list_call() { // Given — first call uses SELECT * and teaches the monitor the available columns @@ -763,9 +696,7 @@ protected CompletionStage query( assertThat(nextQuery.parameters).isEqualTo(parameters); if (nextQuery.error) { Message error = - new Error( - ProtocolConstants.ErrorCode.SERVER_ERROR, - "Unknown keyspace/cf pair (system.peers_v2)"); + new Error(ProtocolConstants.ErrorCode.INVALID, "Unknown table system.peers_v2"); return CompletableFutures.failedFuture(new UnexpectedResponseException(queryString, error)); } return CompletableFuture.completedFuture(nextQuery.result); @@ -881,43 +812,6 @@ private AdminRow mockPeersV2Row(int i, UUID hostId) { } } - // Mock row for DSE ~6.8 - private AdminRow mockPeersRowDse(int i, UUID hostId) { - try { - AdminRow row = mock(AdminRow.class); - when(row.contains("peer")).thenReturn(true); - when(row.isNull("data_center")).thenReturn(false); - when(row.getString("data_center")).thenReturn("dc" + i); - when(row.getString("dse_version")).thenReturn("6.8.30"); - when(row.contains("graph")).thenReturn(true); - when(row.isNull("host_id")).thenReturn(hostId == null); - when(row.getUuid("host_id")).thenReturn(hostId); - when(row.getInetAddress("peer")).thenReturn(InetAddress.getByName("127.0.0." + i)); - when(row.isNull("rack")).thenReturn(false); - when(row.getString("rack")).thenReturn("rack" + i); - when(row.isNull("native_transport_address")).thenReturn(false); - when(row.getInetAddress("native_transport_address")) - .thenReturn(InetAddress.getByName("127.0.0." + i)); - when(row.isNull("native_transport_port")).thenReturn(false); - when(row.getInteger("native_transport_port")).thenReturn(9042); - when(row.isNull("tokens")).thenReturn(false); - when(row.getSetOfString("tokens")).thenReturn(ImmutableSet.of("token" + i)); - when(row.isNull("rpc_address")).thenReturn(false); - - return row; - } catch (UnknownHostException e) { - fail("unexpected", e); - return null; - } - } - - private AdminRow mockPeersRowDseWithSsl(int i, UUID hostId) { - AdminRow row = mockPeersRowDse(i, hostId); - when(row.isNull("native_transport_port_ssl")).thenReturn(false); - when(row.getInteger("native_transport_port_ssl")).thenReturn(9043); - return row; - } - private AdminResult mockResult(AdminRow... rows) { return AdminResultTestHelper.mockResult(rows); } diff --git a/core/src/test/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/DefaultSchemaQueriesFactoryTest.java b/core/src/test/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/DefaultSchemaQueriesFactoryTest.java index dbe7003ae46..d0d021cd45b 100644 --- a/core/src/test/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/DefaultSchemaQueriesFactoryTest.java +++ b/core/src/test/java/com/datastax/oss/driver/internal/core/metadata/schema/queries/DefaultSchemaQueriesFactoryTest.java @@ -26,7 +26,6 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import com.datastax.dse.driver.api.core.metadata.DseNodeProperties; import com.datastax.oss.driver.api.core.Version; import com.datastax.oss.driver.api.core.config.DefaultDriverOption; import com.datastax.oss.driver.api.core.config.DriverConfig; @@ -35,7 +34,6 @@ import com.datastax.oss.driver.internal.core.channel.DriverChannel; import com.datastax.oss.driver.internal.core.context.InternalDriverContext; import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; import com.tngtech.java.junit.dataprovider.DataProvider; import com.tngtech.java.junit.dataprovider.DataProviderRunner; import com.tngtech.java.junit.dataprovider.UseDataProvider; @@ -52,8 +50,7 @@ enum Expected { CASS_21(Cassandra21SchemaQueries.class), CASS_22(Cassandra22SchemaQueries.class), CASS_3(Cassandra3SchemaQueries.class), - CASS_4(Cassandra4SchemaQueries.class), - DSE_6_8(Dse68SchemaQueries.class); + CASS_4(Cassandra4SchemaQueries.class); final Class clz; @@ -82,47 +79,19 @@ public Class getClz() { .add(ImmutableList.of("4.1.0", Optional.empty(), Expected.CASS_4)) .build(); - private static ImmutableList> dseVersions = - ImmutableList.>builder() - // DSE 6.0.0 - .add(ImmutableList.of("4.0.0.2284", Optional.of("6.0.0"), Expected.CASS_3)) - // DSE 6.0.1 - .add(ImmutableList.of("4.0.0.2349", Optional.of("6.0.1"), Expected.CASS_3)) - // DSE 6.0.2 moved to DSE version (minus dots) in an extra element - .add(ImmutableList.of("4.0.0.602", Optional.of("6.0.2"), Expected.CASS_3)) - // DSE 6.7.0 continued with the same idea - .add(ImmutableList.of("4.0.0.670", Optional.of("6.7.0"), Expected.CASS_4)) - // DSE 6.8.0 does the same - .add(ImmutableList.of("4.0.0.680", Optional.of("6.8.0"), Expected.DSE_6_8)) - .build(); - - private static ImmutableList> allVersions = - ImmutableList.>builder() - .addAll(cassandraVersions) - .addAll(dseVersions) - .build(); - @DataProvider(format = "%m %p[1] => %p[0]") public static Iterable expected() { - return allVersions; + return cassandraVersions; } @Test @UseDataProvider("expected") public void should_return_correct_schema_queries_impl( - String cassandraVersion, Optional dseVersion, Expected expected) { + String cassandraVersion, Optional ignored, Expected expected) { final Node mockNode = mock(Node.class); when(mockNode.getCassandraVersion()).thenReturn(Version.parse(cassandraVersion)); - dseVersion.ifPresent( - versionStr -> { - when(mockNode.getExtras()) - .thenReturn( - ImmutableMap.of( - DseNodeProperties.DSE_VERSION, Version.parse(versionStr))); - }); - DefaultSchemaQueriesFactory factory = buildFactory(); @SuppressWarnings("unchecked") diff --git a/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/extras/enums/EnumNameCodecTest.java b/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/extras/enums/EnumNameCodecTest.java index 093ec8a0be8..a66dde9c107 100644 --- a/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/extras/enums/EnumNameCodecTest.java +++ b/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/extras/enums/EnumNameCodecTest.java @@ -19,7 +19,7 @@ import static org.assertj.core.api.Assertions.assertThat; -import com.datastax.dse.driver.api.core.DseProtocolVersion; +import com.datastax.oss.driver.api.core.DefaultConsistencyLevel; import com.datastax.oss.driver.api.core.DefaultProtocolVersion; import com.datastax.oss.driver.api.core.type.codec.ExtraTypeCodecs; import com.datastax.oss.driver.api.core.type.reflect.GenericType; @@ -87,6 +87,6 @@ public void should_accept_raw_type() { @Test public void should_accept_object() { assertThat(codec.accepts(DefaultProtocolVersion.V3)).isTrue(); - assertThat(codec.accepts(DseProtocolVersion.DSE_V1)).isFalse(); + assertThat(codec.accepts(DefaultConsistencyLevel.ONE)).isFalse(); } } diff --git a/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/extras/enums/EnumOrdinalCodecTest.java b/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/extras/enums/EnumOrdinalCodecTest.java index 7162bc51ff2..a45b4bed458 100644 --- a/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/extras/enums/EnumOrdinalCodecTest.java +++ b/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/extras/enums/EnumOrdinalCodecTest.java @@ -19,7 +19,7 @@ import static org.assertj.core.api.Assertions.assertThat; -import com.datastax.dse.driver.api.core.DseProtocolVersion; +import com.datastax.oss.driver.api.core.DefaultConsistencyLevel; import com.datastax.oss.driver.api.core.DefaultProtocolVersion; import com.datastax.oss.driver.api.core.type.codec.ExtraTypeCodecs; import com.datastax.oss.driver.api.core.type.reflect.GenericType; @@ -92,6 +92,6 @@ public void should_accept_raw_type() { @Test public void should_accept_object() { assertThat(codec.accepts(DefaultProtocolVersion.V3)).isTrue(); - assertThat(codec.accepts(DseProtocolVersion.DSE_V1)).isFalse(); + assertThat(codec.accepts(DefaultConsistencyLevel.ONE)).isFalse(); } } diff --git a/core/src/test/resources/config/cloud/creds.zip b/core/src/test/resources/config/cloud/creds.zip deleted file mode 100644 index 3b5d1cb1cbd..00000000000 Binary files a/core/src/test/resources/config/cloud/creds.zip and /dev/null differ diff --git a/core/src/test/resources/config/cloud/identity.jks b/core/src/test/resources/config/cloud/identity.jks deleted file mode 100644 index bac5bbaa965..00000000000 Binary files a/core/src/test/resources/config/cloud/identity.jks and /dev/null differ diff --git a/core/src/test/resources/config/cloud/metadata.json b/core/src/test/resources/config/cloud/metadata.json deleted file mode 100644 index 35aa26f67f1..00000000000 --- a/core/src/test/resources/config/cloud/metadata.json +++ /dev/null @@ -1 +0,0 @@ -{"region":"local","contact_info":{"type":"sni_proxy","local_dc":"dc1","contact_points":["4ac06655-f861-49f9-881e-3fee22e69b94","2af7c253-3394-4a0d-bfac-f1ad81b5154d","b17b6e2a-3f48-4d6a-81c1-20a0a1f3192a"],"sni_proxy_address":"localhost:30002"}} diff --git a/core/src/test/resources/config/cloud/trustStore.jks b/core/src/test/resources/config/cloud/trustStore.jks deleted file mode 100644 index 8ee03f97da0..00000000000 Binary files a/core/src/test/resources/config/cloud/trustStore.jks and /dev/null differ diff --git a/core/src/test/resources/config/customApplication.conf b/core/src/test/resources/config/customApplication.conf index c3e3dc7b468..a9681d79563 100644 --- a/core/src/test/resources/config/customApplication.conf +++ b/core/src/test/resources/config/customApplication.conf @@ -18,6 +18,4 @@ datastax-java-driver { // Check that references to other options in `reference.conf` are correctly resolved basic.request.timeout = ${datastax-java-driver.advanced.connection.init-query-timeout} - - advanced.continuous-paging.max-pages = 10 } diff --git a/core/src/test/resources/config/customApplication.json b/core/src/test/resources/config/customApplication.json index 4988a72cd9a..2527d9908d8 100644 --- a/core/src/test/resources/config/customApplication.json +++ b/core/src/test/resources/config/customApplication.json @@ -4,11 +4,6 @@ "request": { "page-size": "2000" } - }, - "advanced": { - "continuous-paging": { - "page-size": 2000 - } } } } diff --git a/core/src/test/resources/config/customApplication.properties b/core/src/test/resources/config/customApplication.properties index 4c1d1ea0647..25fcc5cd058 100644 --- a/core/src/test/resources/config/customApplication.properties +++ b/core/src/test/resources/config/customApplication.properties @@ -17,4 +17,3 @@ # datastax-java-driver.basic.request.consistency=ONE -datastax-java-driver.advanced.continuous-paging.max-enqueued-pages = 8 \ No newline at end of file diff --git a/core/src/test/resources/insights/duplicate-dependencies.txt b/core/src/test/resources/insights/duplicate-dependencies.txt deleted file mode 100644 index a808dff3f57..00000000000 --- a/core/src/test/resources/insights/duplicate-dependencies.txt +++ /dev/null @@ -1,2 +0,0 @@ -io.netty:netty-handler:jar:4.0.56.Final:compile -io.netty:netty-handler:jar:4.1.2.Final:compile \ No newline at end of file diff --git a/core/src/test/resources/insights/malformed-pom.properties b/core/src/test/resources/insights/malformed-pom.properties deleted file mode 100644 index 0a503062fbd..00000000000 --- a/core/src/test/resources/insights/malformed-pom.properties +++ /dev/null @@ -1,22 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -#Created by Apache Maven 3.5.0 -#no version -groupId=io.netty -artifactId=netty-handler \ No newline at end of file diff --git a/core/src/test/resources/insights/netty-dependency-optional.txt b/core/src/test/resources/insights/netty-dependency-optional.txt deleted file mode 100644 index 2bd0cd21a0c..00000000000 --- a/core/src/test/resources/insights/netty-dependency-optional.txt +++ /dev/null @@ -1 +0,0 @@ -io.netty:netty-handler:jar:4.0.0.Final:compile (optional) \ No newline at end of file diff --git a/core/src/test/resources/insights/netty-dependency.txt b/core/src/test/resources/insights/netty-dependency.txt deleted file mode 100644 index 69c350c30e8..00000000000 --- a/core/src/test/resources/insights/netty-dependency.txt +++ /dev/null @@ -1 +0,0 @@ -io.netty:netty-handler:jar:4.0.0.Final:runtime \ No newline at end of file diff --git a/core/src/test/resources/insights/ordered-dependencies.txt b/core/src/test/resources/insights/ordered-dependencies.txt deleted file mode 100644 index a5518f89736..00000000000 --- a/core/src/test/resources/insights/ordered-dependencies.txt +++ /dev/null @@ -1,3 +0,0 @@ -b-org.com:art1:jar:1.0:compile -a-org.com:art1:jar:2.0:compile -c-org.com:art1:jar:3.0:compile \ No newline at end of file diff --git a/core/src/test/resources/insights/pom.properties b/core/src/test/resources/insights/pom.properties deleted file mode 100644 index e68a31c8fc7..00000000000 --- a/core/src/test/resources/insights/pom.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -#Created by Apache Maven 3.5.0 -version=4.0.56.Final -groupId=io.netty -artifactId=netty-handler - diff --git a/core/src/test/resources/insights/test-dependencies.txt b/core/src/test/resources/insights/test-dependencies.txt deleted file mode 100644 index e7158ef055e..00000000000 --- a/core/src/test/resources/insights/test-dependencies.txt +++ /dev/null @@ -1,31 +0,0 @@ - -The following files have been resolved: - com.github.jnr:jffi:jar:1.2.16:compile - org.ow2.asm:asm:jar:5.0.3:compile - com.github.jnr:jnr-constants:jar:0.9.9:compile - com.esri.geometry:esri-geometry-api:jar:1.2.1:compile - com.google.guava:guava:jar:19.0:compile - com.fasterxml.jackson.core:jackson-annotations:jar:2.8.11:compile - com.github.jnr:jnr-posix:jar:3.0.44:compile - org.codehaus.jackson:jackson-core-asl:jar:1.9.12:compile - io.netty:netty-handler:jar:4.0.56.Final:compile - org.ow2.asm:asm-commons:jar:5.0.3:compile - org.ow2.asm:asm-util:jar:5.0.3:compile - org.xerial.snappy:snappy-java:jar:1.1.2.6:compile (optional) - io.netty:netty-buffer:jar:4.0.56.Final:compile - com.github.jnr:jnr-ffi:jar:2.1.7:compile - com.fasterxml.jackson.core:jackson-core:jar:2.8.11:compile - org.hdrhistogram:HdrHistogram:jar:2.1.10:compile (optional) - org.ow2.asm:asm-tree:jar:5.0.3:compile - at.yawk.lz4:lz4-java:jar:1.8.1:compile (optional) - io.netty:netty-transport:jar:4.0.56.Final:compile - io.dropwizard.metrics:metrics-core:jar:3.2.2:compile - io.netty:netty-common:jar:4.0.56.Final:compile - com.fasterxml.jackson.core:jackson-databind:jar:2.7.9.3:compile - org.slf4j:slf4j-api:jar:1.7.25:compile - io.netty:netty-transport-native-epoll:jar:4.0.56.Final:compile (optional) - org.ow2.asm:asm-analysis:jar:5.0.3:compile - com.github.jnr:jnr-x86asm:jar:1.0.2:compile - io.netty:netty-codec:jar:4.0.56.Final:compile - org.json:json:jar:20090211:compile - com.github.jnr:jffi:jar:native:1.2.16:runtime \ No newline at end of file diff --git a/core/src/test/resources/logback-test.xml b/core/src/test/resources/logback-test.xml index 1424331a31d..b85b991f2d7 100644 --- a/core/src/test/resources/logback-test.xml +++ b/core/src/test/resources/logback-test.xml @@ -28,5 +28,6 @@ - + + diff --git a/distribution/pom.xml b/distribution/pom.xml index e3787c136d5..e6421639ac0 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -130,11 +130,6 @@ jsr305 3.0.2 - - com.esri.geometry - esri-geometry-api - ${esri.version} - at.yawk.lz4 lz4-java @@ -145,21 +140,6 @@ snappy-java ${snappy.version} - - org.apache.tinkerpop - gremlin-core - ${tinkerpop.version} - - - org.apache.tinkerpop - tinkergraph-gremlin - ${tinkerpop.version} - - - org.javatuples - javatuples - 1.2 - diff --git a/examples/src/main/java/com/datastax/oss/driver/examples/astra/AstraReadCassandraVersion.java b/examples/src/main/java/com/datastax/oss/driver/examples/astra/AstraReadCassandraVersion.java deleted file mode 100644 index 7f4833c46d8..00000000000 --- a/examples/src/main/java/com/datastax/oss/driver/examples/astra/AstraReadCassandraVersion.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.oss.driver.examples.astra; - -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.cql.ResultSet; -import com.datastax.oss.driver.api.core.cql.Row; -import java.nio.file.Paths; - -/** - * Connects to a DataStax Astra cluster and extracts basic information from it. - * - *

Preconditions: - * - *

    - *
  • A DataStax Astra cluster is running and accessible. - *
  • A DataStax Astra secure connect bundle for the running cluster. - *
- * - *

Side effects: none. - * - * @see - * Creating an Astra Database (GCP) - * @see - * Providing access to Astra databases (GCP) - * @see - * Obtaining Astra secure connect bundle (GCP) - * @see Java Driver online - * manual - */ -public class AstraReadCassandraVersion { - - public static void main(String[] args) { - - // The Session is what you use to execute queries. It is thread-safe and should be - // reused. - try (CqlSession session = - CqlSession.builder() - // Change the path here to the secure connect bundle location (see javadocs above) - .withCloudSecureConnectBundle(Paths.get("/path/to/secure-connect-database_name.zip")) - // Change the user_name and password here for the Astra instance - .withAuthCredentials("user_name", "fakePasswordForTests") - // Uncomment the next line to use a specific keyspace - // .withKeyspace("keyspace_name") - .build()) { - - // We use execute to send a query to Cassandra. This returns a ResultSet, which - // is essentially a collection of Row objects. - ResultSet rs = session.execute("select release_version from system.local WHERE key='local'"); - // Extract the first row (which is the only one in this case). - Row row = rs.one(); - - // Extract the value of the first (and only) column from the row. - assert row != null; - String releaseVersion = row.getString("release_version"); - System.out.printf("Cassandra version is: %s%n", releaseVersion); - } - // The try-with-resources block automatically close the session after we’re done with it. - // This step is important because it frees underlying resources (TCP connections, thread - // pools...). In a real application, you would typically do this at shutdown - // (for example, when undeploying your webapp). - } -} diff --git a/examples/src/main/java/com/datastax/oss/driver/examples/mapper/KillrVideoMapperExample.java b/examples/src/main/java/com/datastax/oss/driver/examples/mapper/KillrVideoMapperExample.java index 6284b16eac1..1cd39edd496 100644 --- a/examples/src/main/java/com/datastax/oss/driver/examples/mapper/KillrVideoMapperExample.java +++ b/examples/src/main/java/com/datastax/oss/driver/examples/mapper/KillrVideoMapperExample.java @@ -112,8 +112,7 @@ public static void main(String[] args) { Video video = new Video(); video.setUserid(user.getUserid()); - video.setName( - "Getting Started with DataStax Apache Cassandra as a Service on DataStax Astra"); + video.setName("Getting Started with ScyllaDB"); video.setLocation("https://www.youtube.com/watch?v=68xzKpcZURA"); Set tags = new HashSet<>(); tags.add("apachecassandra"); @@ -146,8 +145,7 @@ public static void main(String[] args) { // Update the existing video: Video template = new Video(); template.setVideoid(video.getVideoid()); - template.setName( - "Getting Started with DataStax Apache Cassandra® as a Service on DataStax Astra"); + template.setName("Getting Started with ScyllaDB using the Java driver"); videoDao.update(template); // Reload the whole entity and check the fields video = videoDao.get(video.getVideoid()); diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index 7f481242fce..1b95a84d6db 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -133,51 +133,6 @@ rxjava test - - org.apache.tinkerpop - gremlin-core - test - - - org.apache.tinkerpop - tinkergraph-gremlin - test - - - org.apache.directory.server - apacheds-core - test - - - org.apache.directory.server - apacheds-protocol-kerberos - test - - - org.apache.directory.server - apacheds-interceptor-kerberos - test - - - org.apache.directory.server - apacheds-protocol-ldap - test - - - org.apache.directory.server - apacheds-ldif-partition - test - - - org.apache.directory.server - apacheds-jdbm-partition - test - - - org.apache.directory.api - api-ldap-codec-standalone - test - com.github.tomakehurst wiremock @@ -213,11 +168,6 @@ blockhound-junit-platform test - - com.esri.geometry - esri-geometry-api - test - org.burningwave tools @@ -236,7 +186,7 @@ -processor - com.datastax.oss.driver.internal.mapper.processor.MapperProcessor,com.datastax.oss.driver.internal.gremlin.PatchedGremlinDslProcessor + com.datastax.oss.driver.internal.mapper.processor.MapperProcessor @@ -244,11 +194,6 @@ error_prone_core 2.31.0 - - com.scylladb - java-driver-test-infra - ${project.version} - com.scylladb java-driver-mapper-processor @@ -259,11 +204,6 @@ java-driver-mapper-runtime ${project.version} - - org.apache.tinkerpop - gremlin-core - ${tinkerpop.version} - diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/auth/DseGssApiAuthProviderAlternateIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/auth/DseGssApiAuthProviderAlternateIT.java deleted file mode 100644 index 77edb6c7c3e..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/auth/DseGssApiAuthProviderAlternateIT.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.auth; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.dse.driver.internal.core.auth.DseGssApiAuthProvider; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.config.DefaultDriverOption; -import com.datastax.oss.driver.api.core.cql.Row; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionUtils; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.runner.RunWith; - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "5.0", - description = "Required for DseAuthenticator") -@RunWith(DataProviderRunner.class) -public class DseGssApiAuthProviderAlternateIT { - @ClassRule public static EmbeddedAdsRule ads = new EmbeddedAdsRule(true); - - @DataProvider - public static Object[][] saslSystemProperties() { - return new Object[][] {{"dse.sasl.service"}, {"dse.sasl.protocol"}}; - } - - @Test - @UseDataProvider("saslSystemProperties") - public void - should_authenticate_using_kerberos_with_keytab_and_alternate_service_principal_using_system_property( - String saslSystemProperty) { - System.setProperty(saslSystemProperty, "alternate"); - try (CqlSession session = - SessionUtils.newSession( - ads.getCcm(), - SessionUtils.configLoaderBuilder() - .withClass(DefaultDriverOption.AUTH_PROVIDER_CLASS, DseGssApiAuthProvider.class) - .withStringMap( - DseDriverOption.AUTH_PROVIDER_SASL_PROPERTIES, - ImmutableMap.of("javax.security.sasl.qop", "auth-conf")) - .withStringMap( - DseDriverOption.AUTH_PROVIDER_LOGIN_CONFIGURATION, - ImmutableMap.of( - "principal", - ads.getUserPrincipal(), - "useKeyTab", - "true", - "refreshKrb5Config", - "true", - "keyTab", - ads.getUserKeytab().getAbsolutePath())) - .build())) { - Row row = session.execute("select * from system.local where key='local'").one(); - assertThat(row).isNotNull(); - } finally { - System.clearProperty(saslSystemProperty); - } - } - - @Test - public void should_authenticate_using_kerberos_with_keytab_and_alternate_service_principal() { - try (CqlSession session = - SessionUtils.newSession( - ads.getCcm(), - SessionUtils.configLoaderBuilder() - .withClass(DefaultDriverOption.AUTH_PROVIDER_CLASS, DseGssApiAuthProvider.class) - .withString(DseDriverOption.AUTH_PROVIDER_SERVICE, "alternate") - .withStringMap( - DseDriverOption.AUTH_PROVIDER_SASL_PROPERTIES, - ImmutableMap.of("javax.security.sasl.qop", "auth-conf")) - .withStringMap( - DseDriverOption.AUTH_PROVIDER_LOGIN_CONFIGURATION, - ImmutableMap.of( - "principal", - ads.getUserPrincipal(), - "useKeyTab", - "true", - "refreshKrb5Config", - "true", - "keyTab", - ads.getUserKeytab().getAbsolutePath())) - .build())) { - Row row = session.execute("select * from system.local where key='local'").one(); - assertThat(row).isNotNull(); - } - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/auth/DseGssApiAuthProviderIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/auth/DseGssApiAuthProviderIT.java deleted file mode 100644 index 01e1e704198..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/auth/DseGssApiAuthProviderIT.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.auth; - -import static com.datastax.dse.driver.api.core.auth.KerberosUtils.acquireTicket; -import static com.datastax.dse.driver.api.core.auth.KerberosUtils.destroyTicket; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; - -import com.datastax.oss.driver.api.core.AllNodesFailedException; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.auth.AuthenticationException; -import com.datastax.oss.driver.api.core.cql.ResultSet; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import java.util.List; -import java.util.Map; -import org.junit.Assume; -import org.junit.ClassRule; -import org.junit.Test; - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "5.0", - description = "Required for DseAuthenticator") -public class DseGssApiAuthProviderIT { - - @ClassRule public static EmbeddedAdsRule ads = new EmbeddedAdsRule(); - - /** - * Ensures that a Session can be established to a DSE server secured with Kerberos and that simple - * queries can be made using a client configuration that provides a keytab file. - */ - @Test - public void should_authenticate_using_kerberos_with_keytab() { - try (CqlSession session = ads.newKeyTabSession()) { - ResultSet set = session.execute("select * from system.local where key='local'"); - assertThat(set).isNotNull(); - } - } - - /** - * Ensures that a Session can be established to a DSE server secured with Kerberos and that simple - * queries can be made using a client configuration that uses the ticket cache. This test will - * only run on unix platforms since it uses kinit to acquire tickets and kdestroy to destroy them. - */ - @Test - public void should_authenticate_using_kerberos_with_ticket() throws Exception { - String osName = System.getProperty("os.name", "").toLowerCase(); - boolean isUnix = osName.contains("mac") || osName.contains("darwin") || osName.contains("nux"); - Assume.assumeTrue(isUnix); - acquireTicket(ads.getUserPrincipal(), ads.getUserKeytab(), ads.getAdsServer()); - try (CqlSession session = ads.newTicketSession()) { - ResultSet set = session.execute("select * from system.local where key='local'"); - assertThat(set).isNotNull(); - } finally { - destroyTicket(ads); - } - } - - /** - * Validates that an AllNodesFailedException is thrown when using a ticket-based configuration and - * no such ticket exists in the user's cache. This is expected because we shouldn't be able to - * establish connection to a cassandra node if we cannot authenticate. - * - * @test_category dse:authentication - */ - @SuppressWarnings("unused") - @Test - public void should_not_authenticate_if_no_ticket_in_cache() { - try (CqlSession session = ads.newTicketSession()) { - fail("Expected an AllNodesFailedException"); - } catch (AllNodesFailedException e) { - verifyException(e); - } - } - - /** - * Validates that an AllNodesFailedException is thrown when using a keytab-based configuration and - * no such user exists for the given principal. This is expected because we shouldn't be able to - * establish connection to a cassandra node if we cannot authenticate. - * - * @test_category dse:authentication - */ - @SuppressWarnings("unused") - @Test - public void should_not_authenticate_if_keytab_does_not_map_to_valid_principal() { - try (CqlSession session = - ads.newKeyTabSession(ads.getUnknownPrincipal(), ads.getUnknownKeytab().getAbsolutePath())) { - fail("Expected an AllNodesFailedException"); - } catch (AllNodesFailedException e) { - verifyException(e); - } - } - /** - * Ensures that a Session can be established to a DSE server secured with Kerberos and that simple - * queries can be made using a client configuration that is provided via programatic interface - */ - @Test - public void should_authenticate_using_kerberos_with_keytab_programmatically() { - DseGssApiAuthProviderBase.GssApiOptions.Builder builder = - DseGssApiAuthProviderBase.GssApiOptions.builder(); - Map loginConfig = - ImmutableMap.of( - "principal", - ads.getUserPrincipal(), - "useKeyTab", - "true", - "refreshKrb5Config", - "true", - "keyTab", - ads.getUserKeytab().getAbsolutePath()); - - builder.withLoginConfiguration(loginConfig); - try (CqlSession session = - CqlSession.builder() - .withAuthProvider(new ProgrammaticDseGssApiAuthProvider(builder.build())) - .build()) { - - ResultSet set = session.execute("select * from system.local where key='local'"); - assertThat(set).isNotNull(); - } - } - - private void verifyException(AllNodesFailedException anfe) { - assertThat(anfe.getAllErrors()).hasSize(1); - List errors = anfe.getAllErrors().values().iterator().next(); - assertThat(errors).hasSize(1); - Throwable firstError = errors.get(0); - assertThat(firstError) - .isInstanceOf(AuthenticationException.class) - .hasMessageContaining("Authentication error on node /127.0.0.1:9042"); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/auth/DsePlainTextAuthProviderIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/auth/DsePlainTextAuthProviderIT.java deleted file mode 100644 index af785b4b372..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/auth/DsePlainTextAuthProviderIT.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.auth; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Fail.fail; - -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.oss.driver.api.core.AllNodesFailedException; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.Version; -import com.datastax.oss.driver.api.core.auth.AuthenticationException; -import com.datastax.oss.driver.api.core.config.DefaultDriverOption; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionUtils; -import com.datastax.oss.driver.internal.core.auth.PlainTextAuthProvider; -import com.datastax.oss.driver.shaded.guava.common.util.concurrent.Uninterruptibles; -import java.util.List; -import java.util.concurrent.TimeUnit; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Test; - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "5.0", - description = "Required for DseAuthenticator") -public class DsePlainTextAuthProviderIT { - - @ClassRule - public static CustomCcmRule ccm = - CustomCcmRule.builder() - .withCassandraConfiguration( - "authenticator", "com.datastax.bdp.cassandra.auth.DseAuthenticator") - .withDseConfiguration("authentication_options.enabled", true) - .withDseConfiguration("authentication_options.default_scheme", "internal") - .withJvmArgs("-Dcassandra.superuser_setup_delay_ms=0") - .build(); - - @BeforeClass - public static void sleepForAuth() { - if (ccm.getCassandraVersion().compareTo(Version.V2_2_0) < 0) { - // Sleep for 1 second to allow C* auth to do its work. This is only needed for 2.1 - Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS); - } - } - - @Test - public void should_connect_dse_plaintext_auth() { - try (CqlSession session = - SessionUtils.newSession( - ccm, - SessionUtils.configLoaderBuilder() - .withString(DseDriverOption.AUTH_PROVIDER_AUTHORIZATION_ID, "") - .withString(DefaultDriverOption.AUTH_PROVIDER_USER_NAME, "cassandra") - .withString(DefaultDriverOption.AUTH_PROVIDER_PASSWORD, "cassandra") - .withClass(DefaultDriverOption.AUTH_PROVIDER_CLASS, PlainTextAuthProvider.class) - .build())) { - session.execute("select * from system.local where key='local'"); - } - } - - @Test - public void should_connect_dse_plaintext_auth_programmatically() { - try (CqlSession session = - CqlSession.builder() - .addContactEndPoints(ccm.getContactPoints()) - .withAuthCredentials("cassandra", "cassandra") - .build()) { - session.execute("select * from system.local where key='local'"); - } - } - - @SuppressWarnings("unused") - @Test - public void should_not_connect_with_invalid_credentials() { - try (CqlSession session = - SessionUtils.newSession( - ccm, - SessionUtils.configLoaderBuilder() - .withString(DseDriverOption.AUTH_PROVIDER_AUTHORIZATION_ID, "") - .withString(DefaultDriverOption.AUTH_PROVIDER_USER_NAME, "cassandra") - .withString(DefaultDriverOption.AUTH_PROVIDER_PASSWORD, "NotARealPassword") - .withClass(DefaultDriverOption.AUTH_PROVIDER_CLASS, PlainTextAuthProvider.class) - .build())) { - fail("Expected an AllNodesFailedException"); - } catch (AllNodesFailedException e) { - verifyException(e); - } - } - - @SuppressWarnings("unused") - @Test - public void should_not_connect_without_credentials() { - try (CqlSession session = - SessionUtils.newSession( - ccm, - SessionUtils.configLoaderBuilder() - .withString(DseDriverOption.AUTH_PROVIDER_AUTHORIZATION_ID, "") - .withClass(DefaultDriverOption.AUTH_PROVIDER_CLASS, PlainTextAuthProvider.class) - .build())) { - fail("Expected AllNodesFailedException"); - } catch (AllNodesFailedException e) { - verifyException(e); - } - } - - private void verifyException(AllNodesFailedException anfe) { - assertThat(anfe.getAllErrors()).hasSize(1); - List errors = anfe.getAllErrors().values().iterator().next(); - assertThat(errors).hasSize(1); - Throwable firstError = errors.get(0); - assertThat(firstError) - .isInstanceOf(AuthenticationException.class) - .hasMessageContaining("Authentication error on node /127.0.0.1:9042"); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/auth/DseProxyAuthenticationIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/auth/DseProxyAuthenticationIT.java deleted file mode 100644 index 4d43c75ed28..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/auth/DseProxyAuthenticationIT.java +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.auth; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; - -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.dse.driver.internal.core.auth.DseGssApiAuthProvider; -import com.datastax.oss.driver.api.core.AllNodesFailedException; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.auth.AuthenticationException; -import com.datastax.oss.driver.api.core.config.DefaultDriverOption; -import com.datastax.oss.driver.api.core.cql.ResultSet; -import com.datastax.oss.driver.api.core.cql.SimpleStatement; -import com.datastax.oss.driver.api.core.servererrors.UnauthorizedException; -import com.datastax.oss.driver.api.testinfra.ccm.SchemaChangeSynchronizer; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionUtils; -import com.datastax.oss.driver.internal.core.auth.PlainTextAuthProvider; -import java.util.List; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Test; - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "5.1", - description = "Required for DseAuthenticator with proxy") -public class DseProxyAuthenticationIT { - private static String bobPrincipal; - private static String charliePrincipal; - @ClassRule public static EmbeddedAdsRule ads = new EmbeddedAdsRule(); - - @BeforeClass - public static void addUsers() { - bobPrincipal = ads.addUserAndCreateKeyTab("bob", "fakePasswordForBob"); - charliePrincipal = ads.addUserAndCreateKeyTab("charlie", "fakePasswordForCharlie"); - } - - @Before - public void setupRoles() { - - SchemaChangeSynchronizer.withLock( - () -> { - try (CqlSession session = ads.newKeyTabSession()) { - session.execute( - "CREATE ROLE IF NOT EXISTS alice WITH PASSWORD = 'fakePasswordForAlice' AND LOGIN = FALSE"); - session.execute( - "CREATE ROLE IF NOT EXISTS ben WITH PASSWORD = 'fakePasswordForBen' AND LOGIN = TRUE"); - session.execute("CREATE ROLE IF NOT EXISTS 'bob@DATASTAX.COM' WITH LOGIN = TRUE"); - session.execute( - "CREATE ROLE IF NOT EXISTS 'charlie@DATASTAX.COM' WITH PASSWORD = 'fakePasswordForCharlie' AND LOGIN = TRUE"); - session.execute( - "CREATE ROLE IF NOT EXISTS steve WITH PASSWORD = 'fakePasswordForSteve' AND LOGIN = TRUE"); - session.execute( - "CREATE KEYSPACE IF NOT EXISTS aliceks WITH REPLICATION = {'class':'NetworkTopologyStrategy', 'dc1':'1'}"); - session.execute( - "CREATE TABLE IF NOT EXISTS aliceks.alicetable (key text PRIMARY KEY, value text)"); - session.execute( - "INSERT INTO aliceks.alicetable (key, value) VALUES ('hello', 'world')"); - session.execute("GRANT ALL ON KEYSPACE aliceks TO alice"); - session.execute("GRANT EXECUTE ON ALL AUTHENTICATION SCHEMES TO 'ben'"); - session.execute("GRANT EXECUTE ON ALL AUTHENTICATION SCHEMES TO 'bob@DATASTAX.COM'"); - session.execute("GRANT EXECUTE ON ALL AUTHENTICATION SCHEMES TO 'steve'"); - session.execute( - "GRANT EXECUTE ON ALL AUTHENTICATION SCHEMES TO 'charlie@DATASTAX.COM'"); - session.execute("GRANT PROXY.LOGIN ON ROLE 'alice' TO 'ben'"); - session.execute("GRANT PROXY.LOGIN ON ROLE 'alice' TO 'bob@DATASTAX.COM'"); - session.execute("GRANT PROXY.EXECUTE ON ROLE 'alice' TO 'steve'"); - session.execute("GRANT PROXY.EXECUTE ON ROLE 'alice' TO 'charlie@DATASTAX.COM'"); - // ben and bob are allowed to login as alice, but not execute as alice. - // charlie and steve are allowed to execute as alice, but not login as alice. - } - }); - } - /** - * Validates that a connection may be successfully made as user 'alice' using the credentials of a - * user 'ben' using {@link PlainTextAuthProvider} assuming ben has PROXY.LOGIN authorization on - * alice. - */ - @Test - public void should_allow_plain_text_authorized_user_to_login_as() { - try (CqlSession session = - SessionUtils.newSession( - ads.ccm, - SessionUtils.configLoaderBuilder() - .withString(DseDriverOption.AUTH_PROVIDER_AUTHORIZATION_ID, "alice") - .withString(DefaultDriverOption.AUTH_PROVIDER_USER_NAME, "ben") - .withString(DefaultDriverOption.AUTH_PROVIDER_PASSWORD, "fakePasswordForBen") - .withClass(DefaultDriverOption.AUTH_PROVIDER_CLASS, PlainTextAuthProvider.class) - .build())) { - SimpleStatement select = SimpleStatement.builder("select * from aliceks.alicetable").build(); - ResultSet set = session.execute(select); - assertThat(set).isNotNull(); - } - } - - @Test - public void should_allow_plain_text_authorized_user_to_login_as_programmatically() { - try (CqlSession session = - CqlSession.builder() - .addContactEndPoints(ads.ccm.getContactPoints()) - .withAuthCredentials("ben", "fakePasswordForBen", "alice") - .build()) { - session.execute("select * from system.local where key='local'"); - } - } - - /** - * Validates that a connection may successfully made as user 'alice' using the credentials of a - * principal 'bob@DATASTAX.COM' using {@link DseGssApiAuthProvider} assuming 'bob@DATASTAX.COM' - * has PROXY.LOGIN authorization on alice. - */ - @Test - public void should_allow_kerberos_authorized_user_to_login_as() { - try (CqlSession session = - ads.newKeyTabSession( - bobPrincipal, ads.getKeytabForPrincipal(bobPrincipal).getAbsolutePath(), "alice")) { - SimpleStatement select = SimpleStatement.builder("select * from aliceks.alicetable").build(); - ResultSet set = session.execute(select); - assertThat(set).isNotNull(); - } - } - - /** - * Validates that a connection does not succeed as user 'alice' using the credentials of a user - * 'steve' assuming 'steve' does not have PROXY.LOGIN authorization on alice. - */ - @Test - public void should_not_allow_plain_text_unauthorized_user_to_login_as() { - try (CqlSession session = - SessionUtils.newSession( - ads.ccm, - SessionUtils.configLoaderBuilder() - .withString(DseDriverOption.AUTH_PROVIDER_AUTHORIZATION_ID, "alice") - .withString(DefaultDriverOption.AUTH_PROVIDER_USER_NAME, "steve") - .withString(DefaultDriverOption.AUTH_PROVIDER_PASSWORD, "fakePasswordForSteve") - .withClass(DefaultDriverOption.AUTH_PROVIDER_CLASS, PlainTextAuthProvider.class) - .build())) { - SimpleStatement select = SimpleStatement.builder("select * from aliceks.alicetable").build(); - session.execute(select); - fail("Should have thrown AllNodesFailedException on login."); - } catch (AllNodesFailedException anfe) { - verifyException(anfe); - } - } - /** - * Validates that a connection does not succeed as user 'alice' using the credentials of a - * principal 'charlie@DATASTAX.COM' assuming 'charlie@DATASTAX.COM' does not have PROXY.LOGIN - * authorization on alice. - */ - @Test - public void should_not_allow_kerberos_unauthorized_user_to_login_as() throws Exception { - try (CqlSession session = - ads.newKeyTabSession( - charliePrincipal, - ads.getKeytabForPrincipal(charliePrincipal).getAbsolutePath(), - "alice")) { - SimpleStatement select = SimpleStatement.builder("select * from aliceks.alicetable").build(); - session.execute(select); - fail("Should have thrown AllNodesFailedException on login."); - } catch (AllNodesFailedException anfe) { - verifyException(anfe); - } - } - /** - * Validates that a query may be successfully made as user 'alice' using a {@link CqlSession} that - * is authenticated to user 'steve' using {@link PlainTextAuthProvider} assuming steve has - * PROXY.EXECUTE authorization on alice. - */ - @Test - public void should_allow_plain_text_authorized_user_to_execute_as() { - try (CqlSession session = - SessionUtils.newSession( - ads.ccm, - SessionUtils.configLoaderBuilder() - .withString(DefaultDriverOption.AUTH_PROVIDER_USER_NAME, "steve") - .withString(DefaultDriverOption.AUTH_PROVIDER_PASSWORD, "fakePasswordForSteve") - .withClass(DefaultDriverOption.AUTH_PROVIDER_CLASS, PlainTextAuthProvider.class) - .build())) { - SimpleStatement select = SimpleStatement.builder("select * from aliceks.alicetable").build(); - SimpleStatement statementAsAlice = ProxyAuthentication.executeAs("alice", select); - ResultSet set = session.execute(statementAsAlice); - assertThat(set).isNotNull(); - } - } - /** - * Validates that a query may be successfully made as user 'alice' using a {@link CqlSession} that - * is authenticated to principal 'charlie@DATASTAX.COM' using {@link DseGssApiAuthProvider} - * assuming charlie@DATASTAX.COM has PROXY.EXECUTE authorization on alice. - */ - @Test - public void should_allow_kerberos_authorized_user_to_execute_as() { - try (CqlSession session = - ads.newKeyTabSession( - charliePrincipal, ads.getKeytabForPrincipal(charliePrincipal).getAbsolutePath())) { - SimpleStatement select = SimpleStatement.builder("select * from aliceks.alicetable").build(); - SimpleStatement statementAsAlice = ProxyAuthentication.executeAs("alice", select); - ResultSet set = session.execute(statementAsAlice); - assertThat(set).isNotNull(); - } - } - /** - * Validates that a query may not be made as user 'alice' using a {@link CqlSession} that is - * authenticated to user 'ben' if ben does not have PROXY.EXECUTE authorization on alice. - */ - @Test - public void should_not_allow_plain_text_unauthorized_user_to_execute_as() { - try (CqlSession session = - SessionUtils.newSession( - ads.ccm, - SessionUtils.configLoaderBuilder() - .withString(DefaultDriverOption.AUTH_PROVIDER_USER_NAME, "ben") - .withString(DefaultDriverOption.AUTH_PROVIDER_PASSWORD, "fakePasswordForBen") - .withClass(DefaultDriverOption.AUTH_PROVIDER_CLASS, PlainTextAuthProvider.class) - .build())) { - SimpleStatement select = SimpleStatement.builder("select * from aliceks.alicetable").build(); - SimpleStatement statementAsAlice = ProxyAuthentication.executeAs("alice", select); - session.execute(statementAsAlice); - fail("Should have thrown UnauthorizedException on executeAs."); - } catch (UnauthorizedException ue) { - verifyException(ue, "ben"); - } - } - /** - * Validates that a query may not be made as user 'alice' using a {@link CqlSession} that is - * authenticated to principal 'bob@DATASTAX.COM' using {@link DseGssApiAuthProvider} if - * bob@DATASTAX.COM does not have PROXY.EXECUTE authorization on alice. - */ - @Test - public void should_not_allow_kerberos_unauthorized_user_to_execute_as() { - try (CqlSession session = - ads.newKeyTabSession( - bobPrincipal, ads.getKeytabForPrincipal(bobPrincipal).getAbsolutePath())) { - SimpleStatement select = SimpleStatement.builder("select * from aliceks.alicetable").build(); - SimpleStatement statementAsAlice = ProxyAuthentication.executeAs("alice", select); - session.execute(statementAsAlice); - fail("Should have thrown UnauthorizedException on executeAs."); - } catch (UnauthorizedException ue) { - verifyException(ue, "bob@DATASTAX.COM"); - } - } - - private void verifyException(AllNodesFailedException anfe) { - assertThat(anfe.getAllErrors()).hasSize(1); - List errors = anfe.getAllErrors().values().iterator().next(); - assertThat(errors).hasSize(1); - Throwable firstError = errors.get(0); - assertThat(firstError) - .isInstanceOf(AuthenticationException.class) - .hasMessageContaining( - "Authentication error on node /127.0.0.1:9042: " - + "server replied with 'Failed to login. Please re-try.' to AuthResponse request"); - } - - private void verifyException(UnauthorizedException ue, String user) { - assertThat(ue.getMessage()) - .contains( - String.format( - "Either '%s' does not have permission to execute queries as 'alice' " - + "or that role does not exist.", - user)); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/auth/EmbeddedAds.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/auth/EmbeddedAds.java deleted file mode 100644 index 5ca751e9151..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/auth/EmbeddedAds.java +++ /dev/null @@ -1,607 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.auth; - -import com.datastax.oss.driver.shaded.guava.common.base.Preconditions; -import com.datastax.oss.driver.shaded.guava.common.collect.Maps; -import com.datastax.oss.driver.shaded.guava.common.collect.Sets; -import com.datastax.oss.driver.shaded.guava.common.io.Files; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.UnknownHostException; -import java.nio.charset.Charset; -import java.util.Collections; -import java.util.Map; -import java.util.UUID; -import org.apache.directory.api.ldap.model.constants.SchemaConstants; -import org.apache.directory.api.ldap.model.constants.SupportedSaslMechanisms; -import org.apache.directory.api.ldap.model.csn.CsnFactory; -import org.apache.directory.api.ldap.model.entry.Entry; -import org.apache.directory.api.ldap.model.exception.LdapException; -import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException; -import org.apache.directory.api.ldap.model.name.Dn; -import org.apache.directory.api.ldap.model.schema.SchemaManager; -import org.apache.directory.api.ldap.schemamanager.impl.DefaultSchemaManager; -import org.apache.directory.server.constants.ServerDNConstants; -import org.apache.directory.server.core.DefaultDirectoryService; -import org.apache.directory.server.core.api.CacheService; -import org.apache.directory.server.core.api.DirectoryService; -import org.apache.directory.server.core.api.DnFactory; -import org.apache.directory.server.core.api.InstanceLayout; -import org.apache.directory.server.core.api.schema.SchemaPartition; -import org.apache.directory.server.core.kerberos.KeyDerivationInterceptor; -import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmPartition; -import org.apache.directory.server.core.partition.ldif.LdifPartition; -import org.apache.directory.server.core.shared.DefaultDnFactory; -import org.apache.directory.server.kerberos.KerberosConfig; -import org.apache.directory.server.kerberos.kdc.KdcServer; -import org.apache.directory.server.kerberos.shared.crypto.encryption.KerberosKeyFactory; -import org.apache.directory.server.kerberos.shared.keytab.Keytab; -import org.apache.directory.server.kerberos.shared.keytab.KeytabEntry; -import org.apache.directory.server.ldap.LdapServer; -import org.apache.directory.server.ldap.handlers.sasl.MechanismHandler; -import org.apache.directory.server.ldap.handlers.sasl.cramMD5.CramMd5MechanismHandler; -import org.apache.directory.server.ldap.handlers.sasl.digestMD5.DigestMd5MechanismHandler; -import org.apache.directory.server.ldap.handlers.sasl.gssapi.GssapiMechanismHandler; -import org.apache.directory.server.ldap.handlers.sasl.plain.PlainMechanismHandler; -import org.apache.directory.server.protocol.shared.transport.TcpTransport; -import org.apache.directory.server.protocol.shared.transport.UdpTransport; -import org.apache.directory.shared.kerberos.KerberosTime; -import org.apache.directory.shared.kerberos.codec.types.EncryptionType; -import org.apache.directory.shared.kerberos.components.EncryptionKey; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * A convenience utility for running an Embedded Apache Directory Service with LDAP and optionally a - * Kerberos Key Distribution Server. By default listens for LDAP on 10389 and Kerberos on 60088. You - * can use something like Apache Directory Studio - * to verify the server is configured and running correctly by connecting to localhost:10389 with - * username 'uid=admin,ou=system' and password 'secret'. - * - *

Note: This should only be used for development and testing purposes. - */ -public class EmbeddedAds { - - private static final Logger LOG = LoggerFactory.getLogger(EmbeddedAds.class); - - private final String dn; - - private final String realm; - - private int kdcPort; - - private int ldapPort; - - private final boolean kerberos; - - private InetAddress address; - - private String hostname; - - private File confDir; - - private volatile boolean isInit = false; - - private DirectoryService service; - - private LdapServer ldapServer; - - private KdcServer kdcServer; - - private Dn usersDN; - - private File krb5Conf; - - private EmbeddedAds( - String dn, - String realm, - String address, - int ldapPort, - boolean kerberos, - int kdcPort, - File confDir) { - this.dn = dn; - this.realm = realm; - try { - this.address = InetAddress.getByName(address); - } catch (UnknownHostException e) { - LOG.error("Failure resolving address '{}', falling back to loopback.", address, e); - this.address = InetAddress.getLoopbackAddress(); - } - this.hostname = this.address.getHostName().toLowerCase(); - this.ldapPort = ldapPort; - this.kerberos = kerberos; - this.kdcPort = kdcPort; - this.confDir = confDir; - } - - public void start() throws Exception { - if (isInit) { - return; - } - isInit = true; - File workDir = Files.createTempDir(); - // Set confDir = workDir if not defined. - if (confDir == null) { - confDir = workDir; - } - - if (kerberos) { - kdcPort = kdcPort != -1 ? kdcPort : findAvailablePort(60088); - - // Set system properties required for kerberos auth to work. Unfortunately admin_server - // cannot be expressed via System properties (like realm and kdc can), thus we must create a - // config file. - krb5Conf = createKrb5Conf(); - - System.setProperty("java.security.krb5.conf", krb5Conf.getAbsolutePath()); - // Useful options for debugging. - // System.setProperty("sun.security.krb5.debug", "true"); - // System.setProperty("java.security.debug", "configfile,configparser,gssloginconfig"); - } - - // Initialize service and set its filesystem layout. - service = new DefaultDirectoryService(); - InstanceLayout layout = new InstanceLayout(workDir); - service.setInstanceLayout(layout); - - // Disable ChangeLog as we don't need change tracking. - service.getChangeLog().setEnabled(false); - // Denormalizes attribute DNs to be human readable, i.e uid=admin,ou=system instead of - // 0.9.2.3=admin,2.5=system) - service.setDenormalizeOpAttrsEnabled(true); - - // Create and init cache service which will be used for caching DNs, among other things. - CacheService cacheService = new CacheService(); - cacheService.initialize(layout); - - // Create and load SchemaManager which will create the default schema partition. - SchemaManager schemaManager = new DefaultSchemaManager(); - service.setSchemaManager(schemaManager); - schemaManager.loadAllEnabled(); - - // Create SchemaPartition from schema manager and load ldif from schema directory. - SchemaPartition schemaPartition = new SchemaPartition(schemaManager); - LdifPartition ldifPartition = new LdifPartition(schemaManager, service.getDnFactory()); - ldifPartition.setPartitionPath(new File(layout.getPartitionsDirectory(), "schema").toURI()); - schemaPartition.setWrappedPartition(ldifPartition); - service.setSchemaPartition(schemaPartition); - - // Create a DN factory which can be used to create and cache DNs. - DnFactory dnFactory = new DefaultDnFactory(schemaManager, cacheService.getCache("dnCache")); - service.setDnFactory(dnFactory); - - // Create mandatory system partition. This is used for storing server configuration. - JdbmPartition systemPartition = - createPartition("system", dnFactory.create(ServerDNConstants.SYSTEM_DN)); - service.setSystemPartition(systemPartition); - - // Now that we have a schema and system partition, start up the directory service. - service.startup(); - - // Create partition where user, tgt and ldap principals will live. - Dn partitionDn = dnFactory.create(dn); - String dnName = partitionDn.getRdn().getValue().getString(); - JdbmPartition partition = createPartition(dnName, partitionDn); - - // Add a context entry so the partition can be referenced by entries. - Entry context = service.newEntry(partitionDn); - context.add("objectClass", "top", "domain", "extensibleObject"); - context.add(partitionDn.getRdn().getType(), dnName); - partition.setContextEntry(context); - service.addPartition(partition); - - // Create users domain. - usersDN = partitionDn.add(dnFactory.create("ou=users")); - Entry usersEntry = service.newEntry(usersDN); - usersEntry.add("objectClass", "organizationalUnit", "top"); - usersEntry.add("ou", "users"); - if (kerberos) { - usersEntry = kerberize(usersEntry); - } - service.getAdminSession().add(usersEntry); - - // Uncomment to allow to connect to ldap server without credentials for convenience. - // service.setAllowAnonymousAccess(true); - - startLdap(); - - // Create sasl and krbtgt principals and start KDC if kerberos is enabled. - if (kerberos) { - // Ticket Granting Ticket entry. - Dn tgtDN = usersDN.add(dnFactory.create("uid=krbtgt")); - String servicePrincipal = "krbtgt/" + realm + "@" + realm; - Entry tgtEntry = service.newEntry(tgtDN); - tgtEntry.add( - "objectClass", - "person", - "inetOrgPerson", - "top", - "krb5KDCEntry", - "uidObject", - "krb5Principal"); - tgtEntry.add("krb5KeyVersionNumber", "0"); - tgtEntry.add("krb5PrincipalName", servicePrincipal); - tgtEntry.add("uid", "krbtgt"); - tgtEntry.add("userPassword", "secret"); - tgtEntry.add("sn", "Service"); - tgtEntry.add("cn", "KDC Service"); - service.getAdminSession().add(kerberize(tgtEntry)); - - // LDAP SASL principal. - String saslPrincipal = "ldap/" + hostname + "@" + realm; - ldapServer.setSaslPrincipal(saslPrincipal); - Dn ldapDN = usersDN.add(dnFactory.create("uid=ldap")); - Entry ldapEntry = service.newEntry(ldapDN); - ldapEntry.add( - "objectClass", - "top", - "person", - "inetOrgPerson", - "krb5KDCEntry", - "uidObject", - "krb5Principal"); - ldapEntry.add("krb5KeyVersionNumber", "0"); - ldapEntry.add("krb5PrincipalName", saslPrincipal); - ldapEntry.add("uid", "ldap"); - ldapEntry.add("userPassword", "secret"); - ldapEntry.add("sn", "Service"); - ldapEntry.add("cn", "LDAP Service"); - service.getAdminSession().add(kerberize(ldapEntry)); - - startKDC(servicePrincipal); - } - } - - public boolean isStarted() { - return this.isInit; - } - - private File createKrb5Conf() throws IOException { - File krb5Conf = new File(confDir, "krb5.conf"); - String config = - String.format( - "[libdefaults]%n" - + "default_realm = %s%n" - + "default_tgs_enctypes = aes128-cts-hmac-sha1-96 aes256-cts-hmac-sha1-96%n%n" - + "[realms]%n" - + "%s = {%n" - + " kdc = %s:%d%n" - + " admin_server = %s:%d%n" - + "}%n", - realm, realm, hostname, kdcPort, hostname, kdcPort); - - try (FileOutputStream fios = new FileOutputStream(krb5Conf)) { - PrintWriter pw = - new PrintWriter( - new BufferedWriter(new OutputStreamWriter(fios, Charset.defaultCharset()))); - pw.write(config); - pw.close(); - } - return krb5Conf; - } - - /** - * @return A specialized krb5.conf file that defines and defaults to the domain expressed by this - * server. - */ - public File getKrb5Conf() { - return krb5Conf; - } - - /** - * Adds a user with the given password and principal name and creates a keytab file for - * authenticating with that user's principal. - * - * @param user Username to login with (i.e. cassandra). - * @param password Password to authenticate with. - * @param principal Principal representing the server (i.e. cassandra@DATASTAX.COM). - * @return Generated keytab file for this user. - */ - public File addUserAndCreateKeytab(String user, String password, String principal) - throws IOException, LdapException { - addUser(user, password, principal); - return createKeytab(user, password, principal); - } - - /** - * Creates a keytab file for authenticating with a given principal. - * - * @param user Username to login with (i.e. cassandra). - * @param password Password to authenticate with. - * @param principal Principal representing the server (i.e. cassandra@DATASTAX.COM). - * @return Generated keytab file for this user. - */ - public File createKeytab(String user, String password, String principal) throws IOException { - File keytabFile = new File(confDir, user + ".keytab"); - Keytab keytab = Keytab.getInstance(); - - KerberosTime timeStamp = new KerberosTime(System.currentTimeMillis()); - - Map keys = - KerberosKeyFactory.getKerberosKeys(principal, password); - - KeytabEntry keytabEntry = - new KeytabEntry( - principal, 0, timeStamp, (byte) 0, keys.get(EncryptionType.AES128_CTS_HMAC_SHA1_96)); - - keytab.setEntries(Collections.singletonList(keytabEntry)); - keytab.write(keytabFile); - return keytabFile; - } - - /** - * Adds a user with the given password, does not create necessary kerberos attributes. - * - * @param user Username to login with (i.e. cassandra). - * @param password Password to authenticate with. - */ - public void addUser(String user, String password) throws LdapException { - addUser(user, password, null); - } - - /** - * Adds a user with the given password and principal. If principal is specified and kerberos is - * enabled, user is created with the necessary attributes to authenticate with kerberos (entryCsn, - * entryUuid, etc.). - * - * @param user Username to login with (i.e. cassandra). - * @param password Password to authenticate with. - * @param principal Principal representing the server (i.e. cassandra@DATASTAX.COM). - */ - public void addUser(String user, String password, String principal) throws LdapException { - Preconditions.checkState(isInit); - Dn userDN = usersDN.add("uid=" + user); - Entry userEntry = service.newEntry(userDN); - if (kerberos && principal != null) { - userEntry.add( - "objectClass", - "organizationalPerson", - "person", - "extensibleObject", - "inetOrgPerson", - "top", - "krb5KDCEntry", - "uidObject", - "krb5Principal"); - userEntry.add("krb5KeyVersionNumber", "0"); - userEntry.add("krb5PrincipalName", principal); - userEntry = kerberize(userEntry); - } else { - userEntry.add( - "objectClass", - "organizationalPerson", - "person", - "extensibleObject", - "inetOrgPerson", - "top", - "uidObject"); - } - userEntry.add("uid", user); - userEntry.add("sn", user); - userEntry.add("cn", user); - userEntry.add("userPassword", password); - service.getAdminSession().add(userEntry); - } - - /** Stops the server(s) if running. */ - public void stop() { - if (ldapServer != null) { - ldapServer.stop(); - } - if (kdcServer != null) { - kdcServer.stop(); - } - } - - /** @return The evaluated hostname that the server is listening with. */ - public String getHostname() { - return this.hostname; - } - - /** - * Adds attributes to the given Entry which will enable krb5key attributes to be added to them. - * - * @param entry Entry to add attributes to. - * @return The provided entry. - */ - private Entry kerberize(Entry entry) throws LdapException { - // Add csn and uuids for kerberos, this is needed to generate krb5keys. - entry.add(SchemaConstants.ENTRY_CSN_AT, new CsnFactory(0).newInstance().toString()); - entry.add(SchemaConstants.ENTRY_UUID_AT, UUID.randomUUID().toString()); - return entry; - } - - /** - * Creates a {@link JdbmPartition} with the given id and DN. - * - * @param id Id to create partition with. - * @param dn Distinguished Name to use to create partition. - * @return Created partition. - */ - private JdbmPartition createPartition(String id, Dn dn) throws LdapInvalidDnException { - JdbmPartition partition = new JdbmPartition(service.getSchemaManager(), service.getDnFactory()); - partition.setId(id); - partition.setPartitionPath( - new File(service.getInstanceLayout().getPartitionsDirectory(), id).toURI()); - partition.setSuffixDn(dn); - partition.setSchemaManager(service.getSchemaManager()); - return partition; - } - - /** Starts the LDAP Server with SASL enabled. */ - private void startLdap() throws Exception { - // Create and start LDAP server. - ldapServer = new LdapServer(); - - // Enable SASL layer, this is useful with or without kerberos. - Map mechanismHandlerMap = Maps.newHashMap(); - mechanismHandlerMap.put(SupportedSaslMechanisms.PLAIN, new PlainMechanismHandler()); - mechanismHandlerMap.put(SupportedSaslMechanisms.CRAM_MD5, new CramMd5MechanismHandler()); - mechanismHandlerMap.put(SupportedSaslMechanisms.DIGEST_MD5, new DigestMd5MechanismHandler()); - // GSSAPI is required for kerberos. - mechanismHandlerMap.put(SupportedSaslMechanisms.GSSAPI, new GssapiMechanismHandler()); - ldapServer.setSaslMechanismHandlers(mechanismHandlerMap); - ldapServer.setSaslHost(hostname); - // Realms only used by DIGEST_MD5 and GSSAPI. - ldapServer.setSaslRealms(Collections.singletonList(realm)); - ldapServer.setSearchBaseDn(dn); - - ldapPort = ldapPort != -1 ? ldapPort : findAvailablePort(10389); - ldapServer.setTransports(new TcpTransport(address.getHostAddress(), ldapPort)); - ldapServer.setDirectoryService(service); - if (kerberos) { - // Add an interceptor to attach krb5keys to created principals. - KeyDerivationInterceptor interceptor = new KeyDerivationInterceptor(); - interceptor.init(service); - service.addLast(interceptor); - } - ldapServer.start(); - } - - /** - * Starts the Kerberos Key Distribution Server supporting AES128 using the given principal for the - * Ticket-granting ticket. - * - * @param servicePrincipal TGT principcal service. - */ - private void startKDC(String servicePrincipal) throws Exception { - KerberosConfig config = new KerberosConfig(); - // We choose AES128_CTS_HMAC_SHA1_96 for our generated keytabs so we don't need JCE. - config.setEncryptionTypes(Sets.newHashSet(EncryptionType.AES128_CTS_HMAC_SHA1_96)); - config.setSearchBaseDn(dn); - config.setServicePrincipal(servicePrincipal); - - kdcServer = new KdcServer(config); - kdcServer.setDirectoryService(service); - - kdcServer.setTransports( - new TcpTransport(address.getHostAddress(), kdcPort), - new UdpTransport(address.getHostAddress(), kdcPort)); - kdcServer.start(); - } - - public static Builder builder() { - return new Builder(); - } - - public static class Builder { - - private String dn = "dc=datastax,dc=com"; - - private String realm = "DATASTAX.COM"; - - private boolean kerberos = false; - - private int kdcPort = -1; - - private int ldapPort = -1; - - private String address = "127.0.0.1"; - - private File confDir = null; - - private Builder() {} - - public EmbeddedAds build() { - return new EmbeddedAds(dn, realm, address, ldapPort, kerberos, kdcPort, confDir); - } - - /** - * Configures the base DN to create users under. Defaults to dc=datastax,dc=com. - */ - public Builder withBaseDn(String dn) { - this.dn = dn; - return this; - } - - /** Configures the realm to use for SASL and Kerberos. Defaults to DATASTAX.COM. */ - public Builder withRealm(String realm) { - this.realm = realm; - return this; - } - - /** - * Sets the directory where krb5.conf and generated keytabs are created. Defaults to current - * directory. - */ - public Builder withConfDir(File confDir) { - this.confDir = confDir; - return this; - } - - /** - * Configures the port to use for LDAP. Defaults to the first available port from 10389+. Must - * be greater than 0. - */ - public Builder withLdapPort(int port) { - Preconditions.checkArgument(port > 0); - this.ldapPort = port; - return this; - } - - /** - * Configures the port to use for Kerberos KDC. Defaults to the first available port for 60088+. - * Must be greater than 0. - */ - public Builder withKerberos(int port) { - Preconditions.checkArgument(port > 0); - this.kdcPort = port; - return withKerberos(); - } - - /** - * Configures the server to run with a Kerberos KDC using the first available port for 60088+. - */ - public Builder withKerberos() { - this.kerberos = true; - return this; - } - - /** - * Configures the server to be configured to listen with the given address. Defaults to - * 127.0.0.1. You shouldn't need to change this. - */ - public Builder withAddress(String address) { - this.address = address; - return this; - } - } - - private static int findAvailablePort(int startingWith) { - IOException last = null; - for (int port = startingWith; port < startingWith + 100; port++) { - try { - ServerSocket s = new ServerSocket(port); - s.close(); - return port; - } catch (IOException e) { - last = e; - } - } - // If for whatever reason a port could not be acquired throw the last encountered exception. - throw new RuntimeException("Could not acquire an available port", last); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/auth/EmbeddedAdsRule.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/auth/EmbeddedAdsRule.java deleted file mode 100644 index a57e349a51b..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/auth/EmbeddedAdsRule.java +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.auth; - -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.dse.driver.internal.core.auth.DseGssApiAuthProvider; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.config.DefaultDriverOption; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirementRule; -import com.datastax.oss.driver.api.testinfra.session.SessionUtils; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import java.io.File; -import java.util.HashMap; -import java.util.Map; -import org.junit.AssumptionViolatedException; -import org.junit.rules.ExternalResource; -import org.junit.runner.Description; -import org.junit.runners.model.Statement; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * A testing rule that wraps the EmbeddedAds server, and ccmRule into one rule This is needed - * because ccm needs to be aware of the kerberos server settings prior to it's initialization. - */ -public class EmbeddedAdsRule extends ExternalResource { - - private static final Logger LOG = LoggerFactory.getLogger(EmbeddedAdsRule.class); - - public CustomCcmRule ccm; - // Realm for the KDC. - private final String realm = "DATASTAX.COM"; - private final String address = "127.0.0.1"; - - private final EmbeddedAds adsServer = - EmbeddedAds.builder().withKerberos().withRealm(realm).withAddress(address).build(); - - // Principal for DSE service ( = kerberos_options.service_principal) - private final String servicePrincipal = "dse/" + adsServer.getHostname() + "@" + realm; - - // A non-standard principal for DSE service, to test SASL protocol names - private final String alternateServicePrincipal = - "alternate/" + adsServer.getHostname() + "@" + realm; - - // Principal for the default cassandra user. - private final String userPrincipal = "cassandra@" + realm; - - // Principal for a user that doesn't exist. - private final String unknownPrincipal = "unknown@" + realm; - - // Keytabs to use for auth. - private static File userKeytab; - private static File unknownKeytab; - private static File dseKeytab; - private static File alternateKeytab; - private static Map customKeytabs = new HashMap<>(); - - private boolean alternate = false; - - public EmbeddedAdsRule(boolean alternate) { - this.alternate = alternate; - } - - public EmbeddedAdsRule() { - this(false); - } - - @Override - protected void before() { - try { - if (adsServer.isStarted()) { - return; - } - // Start ldap/kdc server. - adsServer.start(); - - // Create users and keytabs for the DSE principal and cassandra user. - dseKeytab = adsServer.addUserAndCreateKeytab("dse", "fakePasswordForTests", servicePrincipal); - alternateKeytab = - adsServer.addUserAndCreateKeytab( - "alternate", "fakePasswordForTests", alternateServicePrincipal); - userKeytab = - adsServer.addUserAndCreateKeytab("cassandra", "fakePasswordForTests", userPrincipal); - unknownKeytab = adsServer.createKeytab("unknown", "fakePasswordForTests", unknownPrincipal); - - String authenticationOptions = - "" - + "authentication_options:\n" - + " enabled: true\n" - + " default_scheme: kerberos\n" - + " other_schemes:\n" - + " - internal"; - - if (alternate) { - ccm = - CustomCcmRule.builder() - .withCassandraConfiguration( - "authorizer", "com.datastax.bdp.cassandra.auth.DseAuthorizer") - .withCassandraConfiguration( - "authenticator", "com.datastax.bdp.cassandra.auth.DseAuthenticator") - .withDseConfiguration("authorization_options.enabled", true) - .withDseConfiguration(authenticationOptions) - .withDseConfiguration("kerberos_options.qop", "auth-conf") - .withDseConfiguration( - "kerberos_options.keytab", getAlternateKeytab().getAbsolutePath()) - .withDseConfiguration( - "kerberos_options.service_principal", "alternate/_HOST@" + getRealm()) - .withJvmArgs( - "-Dcassandra.superuser_setup_delay_ms=0", - "-Djava.security.krb5.conf=" + getAdsServer().getKrb5Conf().getAbsolutePath()) - .build(); - } else { - ccm = - CustomCcmRule.builder() - .withCassandraConfiguration( - "authorizer", "com.datastax.bdp.cassandra.auth.DseAuthorizer") - .withCassandraConfiguration( - "authenticator", "com.datastax.bdp.cassandra.auth.DseAuthenticator") - .withDseConfiguration("authorization_options.enabled", true) - .withDseConfiguration(authenticationOptions) - .withDseConfiguration("kerberos_options.qop", "auth") - .withDseConfiguration("kerberos_options.keytab", getDseKeytab().getAbsolutePath()) - .withDseConfiguration( - "kerberos_options.service_principal", "dse/_HOST@" + getRealm()) - .withJvmArgs( - "-Dcassandra.superuser_setup_delay_ms=0", - "-Djava.security.krb5.conf=" + getAdsServer().getKrb5Conf().getAbsolutePath()) - .build(); - } - ccm.getCcmBridge().create(); - ccm.getCcmBridge().start(); - - } catch (Exception e) { - LOG.error("Unable to start ads server ", e); - } - } - - @Override - public Statement apply(Statement base, Description description) { - if (BackendRequirementRule.meetsDescriptionRequirements(description)) { - return super.apply(base, description); - } else { - // requirements not met, throw reasoning assumption to skip test - return new Statement() { - @Override - public void evaluate() { - throw new AssumptionViolatedException( - BackendRequirementRule.buildReasonString(description)); - } - }; - } - } - - @Override - protected void after() { - adsServer.stop(); - ccm.getCcmBridge().stop(); - } - - public CqlSession newKeyTabSession(String userPrincipal, String keytabPath) { - return SessionUtils.newSession( - getCcm(), - SessionUtils.configLoaderBuilder() - .withClass(DefaultDriverOption.AUTH_PROVIDER_CLASS, DseGssApiAuthProvider.class) - .withStringMap( - DseDriverOption.AUTH_PROVIDER_LOGIN_CONFIGURATION, - ImmutableMap.of( - "principal", - userPrincipal, - "useKeyTab", - "true", - "refreshKrb5Config", - "true", - "keyTab", - keytabPath)) - .build()); - } - - public CqlSession newKeyTabSession(String userPrincipal, String keytabPath, String authId) { - return SessionUtils.newSession( - getCcm(), - SessionUtils.configLoaderBuilder() - .withClass(DefaultDriverOption.AUTH_PROVIDER_CLASS, DseGssApiAuthProvider.class) - .withStringMap( - DseDriverOption.AUTH_PROVIDER_LOGIN_CONFIGURATION, - ImmutableMap.of( - "principal", - userPrincipal, - "useKeyTab", - "true", - "refreshKrb5Config", - "true", - "keyTab", - keytabPath)) - .withString(DseDriverOption.AUTH_PROVIDER_AUTHORIZATION_ID, authId) - .build()); - } - - public CqlSession newKeyTabSession() { - return newKeyTabSession(getUserPrincipal(), getUserKeytab().getAbsolutePath()); - } - - public CqlSession newTicketSession() { - return SessionUtils.newSession( - getCcm(), - SessionUtils.configLoaderBuilder() - .withClass(DefaultDriverOption.AUTH_PROVIDER_CLASS, DseGssApiAuthProvider.class) - .withStringMap( - DseDriverOption.AUTH_PROVIDER_LOGIN_CONFIGURATION, - ImmutableMap.of( - "principal", - userPrincipal, - "useTicketCache", - "true", - "refreshKrb5Config", - "true", - "renewTGT", - "true")) - .build()); - } - - public CustomCcmRule getCcm() { - return ccm; - } - - public String getRealm() { - return realm; - } - - public String getAddress() { - return address; - } - - public EmbeddedAds getAdsServer() { - return adsServer; - } - - public String getServicePrincipal() { - return servicePrincipal; - } - - public String getAlternateServicePrincipal() { - return alternateServicePrincipal; - } - - public String getUserPrincipal() { - return userPrincipal; - } - - public String getUnknownPrincipal() { - return unknownPrincipal; - } - - public File getUserKeytab() { - return userKeytab; - } - - public File getUnknownKeytab() { - return unknownKeytab; - } - - public File getDseKeytab() { - return dseKeytab; - } - - public File getAlternateKeytab() { - return alternateKeytab; - } - - public String addUserAndCreateKeyTab(String user, String password) { - String principal = user + "@" + realm; - try { - File keytabFile = adsServer.addUserAndCreateKeytab(user, password, principal); - customKeytabs.put(principal, keytabFile); - } catch (Exception e) { - LOG.error("Unable to add user and create keytab for " + user + " ", e); - } - return principal; - } - - public File getKeytabForPrincipal(String prinicipal) { - return customKeytabs.get(prinicipal); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/auth/KerberosUtils.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/auth/KerberosUtils.java deleted file mode 100644 index 5d385b51c92..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/auth/KerberosUtils.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.auth; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import java.io.File; -import java.io.IOException; -import java.util.Map; -import org.apache.commons.exec.CommandLine; -import org.apache.commons.exec.DefaultExecutor; -import org.apache.commons.exec.Executor; - -public class KerberosUtils { - /** - * Executes the given command with KRB5_CONFIG environment variable pointing to the specialized - * config file for the embedded KDC server. - */ - public static void executeCommand(String command, EmbeddedAds adsServer) throws IOException { - Map environmentMap = - ImmutableMap.builder() - .put("KRB5_CONFIG", adsServer.getKrb5Conf().getAbsolutePath()) - .build(); - CommandLine cli = CommandLine.parse(command); - Executor executor = new DefaultExecutor(); - int retValue = executor.execute(cli, environmentMap); - assertThat(retValue).isZero(); - } - - /** - * Acquires a ticket into the cache with the tgt using kinit command with the given principal and - * keytab file. - */ - public static void acquireTicket(String principal, File keytab, EmbeddedAds adsServer) - throws IOException { - executeCommand( - String.format("kinit -t %s -k %s", keytab.getAbsolutePath(), principal), adsServer); - } - - /** Destroys all tickets in the cache with given principal. */ - public static void destroyTicket(EmbeddedAdsRule ads) throws IOException { - executeCommand("kdestroy", ads.getAdsServer()); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/cql/continuous/ContinuousPagingIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/cql/continuous/ContinuousPagingIT.java deleted file mode 100644 index 45cc84f0719..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/cql/continuous/ContinuousPagingIT.java +++ /dev/null @@ -1,699 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.cql.continuous; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Fail.fail; - -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.dse.driver.api.core.metrics.DseSessionMetric; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.DriverTimeoutException; -import com.datastax.oss.driver.api.core.Version; -import com.datastax.oss.driver.api.core.config.DefaultDriverOption; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.cql.PreparedStatement; -import com.datastax.oss.driver.api.core.cql.Row; -import com.datastax.oss.driver.api.core.cql.SimpleStatement; -import com.datastax.oss.driver.api.core.cql.Statement; -import com.datastax.oss.driver.api.core.metrics.DefaultNodeMetric; -import com.datastax.oss.driver.api.testinfra.ccm.CcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import com.datastax.oss.driver.api.testinfra.session.SessionUtils; -import com.datastax.oss.driver.categories.ParallelizableTests; -import com.datastax.oss.driver.internal.core.util.concurrent.CompletableFutures; -import com.datastax.oss.driver.shaded.guava.common.util.concurrent.Uninterruptibles; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import java.nio.ByteBuffer; -import java.time.Duration; -import java.util.Collections; -import java.util.Iterator; -import java.util.concurrent.CancellationException; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.function.Function; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; -import org.junit.runner.RunWith; - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "5.1.0", - description = "Continuous paging is only available from 5.1.0 onwards") -@Category(ParallelizableTests.class) -@RunWith(DataProviderRunner.class) -public class ContinuousPagingIT extends ContinuousPagingITBase { - - private static CcmRule ccmRule = CcmRule.getInstance(); - - private static SessionRule sessionRule = - SessionRule.builder(ccmRule) - .withConfigLoader( - SessionUtils.configLoaderBuilder() - .withStringList( - DefaultDriverOption.METRICS_SESSION_ENABLED, - Collections.singletonList(DseSessionMetric.CONTINUOUS_CQL_REQUESTS.getPath())) - .withStringList( - DefaultDriverOption.METRICS_NODE_ENABLED, - Collections.singletonList(DefaultNodeMetric.CQL_MESSAGES.getPath())) - .build()) - .build(); - - @ClassRule public static TestRule chain = RuleChain.outerRule(ccmRule).around(sessionRule); - - @BeforeClass - public static void setUp() { - initialize(sessionRule.session(), sessionRule.slowProfile()); - } - - /** - * Validates {@link ContinuousSession#executeContinuously(Statement)} with a variety of paging - * options and ensures in all cases the expected number of rows come back. - * - * @test_category queries - * @jira_ticket JAVA-1322 - * @since 1.2.0 - */ - @Test - @UseDataProvider("pagingOptions") - public void should_execute_synchronously(Options options) { - CqlSession session = sessionRule.session(); - SimpleStatement statement = SimpleStatement.newInstance("SELECT v from test where k=?", KEY); - DriverExecutionProfile profile = options.asProfile(session); - ContinuousResultSet result = - session.executeContinuously(statement.setExecutionProfile(profile)); - int i = 0; - for (Row row : result) { - assertThat(row.getInt("v")).isEqualTo(i); - i++; - } - assertThat(i).isEqualTo(options.expectedRows); - validateMetrics(session); - } - - /** - * Validates {@link ContinuousSession#executeContinuously(Statement)} with a variety of paging - * options using a prepared statement and ensures in all cases the expected number of rows come - * back. - * - * @test_category queries - * @jira_ticket JAVA-1322 - * @since 1.2.0 - */ - @Test - @UseDataProvider("pagingOptions") - public void should_execute_prepared_statement_synchronously(Options options) { - CqlSession session = sessionRule.session(); - DriverExecutionProfile profile = options.asProfile(session); - ContinuousResultSet result = - session.executeContinuously(prepared.bind(KEY).setExecutionProfile(profile)); - int i = 0; - for (Row row : result) { - assertThat(row.getInt("v")).isEqualTo(i); - i++; - } - assertThat(i).isEqualTo(options.expectedRows); - validateMetrics(session); - } - - /** - * Validates {@link ContinuousSession#executeContinuouslyAsync(Statement)} with a variety of - * paging options and ensures in all cases the expected number of rows come back and the expected - * number of pages are received. - * - * @test_category queries - * @jira_ticket JAVA-1322 - * @since 1.2.0 - */ - @Test - @UseDataProvider("pagingOptions") - public void should_execute_asynchronously(Options options) { - CqlSession session = sessionRule.session(); - SimpleStatement statement = SimpleStatement.newInstance("SELECT v from test where k=?", KEY); - DriverExecutionProfile profile = options.asProfile(session); - PageStatistics stats = - CompletableFutures.getUninterruptibly( - session - .executeContinuouslyAsync(statement.setExecutionProfile(profile)) - .thenCompose(new AsyncContinuousPagingFunction())); - assertThat(stats.rows).isEqualTo(options.expectedRows); - assertThat(stats.pages).isEqualTo(options.expectedPages); - validateMetrics(session); - } - - /** - * Validates that continuous paging is resilient to a schema change being made in the middle of - * producing pages for the driver if the query was a simple statement. - * - *

Adds a column 'b' after paging the first row in. This column should not be present in the - * in-flight queries' rows, but should be present for subsequent queries. - * - * @test_category queries - * @jira_ticket JAVA-1653 - * @since 1.2.0 - */ - @Test - public void simple_statement_paging_should_be_resilient_to_schema_change() { - CqlSession session = sessionRule.session(); - SimpleStatement simple = SimpleStatement.newInstance("select * from test_prepare"); - DriverExecutionProfile profile = - session - .getContext() - .getConfig() - .getDefaultProfile() - .withInt(DseDriverOption.CONTINUOUS_PAGING_MAX_ENQUEUED_PAGES, 1) - .withInt(DseDriverOption.CONTINUOUS_PAGING_PAGE_SIZE, 1) - .withDuration( - DseDriverOption.CONTINUOUS_PAGING_TIMEOUT_FIRST_PAGE, Duration.ofSeconds(30)) - .withDuration( - DseDriverOption.CONTINUOUS_PAGING_TIMEOUT_OTHER_PAGES, Duration.ofSeconds(30)); - ContinuousResultSet result = session.executeContinuously(simple.setExecutionProfile(profile)); - Iterator it = result.iterator(); - // First row should have a non-null values. - Row row0 = it.next(); - assertThat(row0.getString("k")).isNotNull(); - assertThat(row0.isNull("v")).isFalse(); - // Make schema change to add b, its metadata should NOT be present in subsequent rows. - CqlSession schemaChangeSession = - SessionUtils.newSession( - ccmRule, session.getKeyspace().orElseThrow(IllegalStateException::new)); - SimpleStatement statement = - SimpleStatement.newInstance("ALTER TABLE test_prepare add b int") - .setExecutionProfile(sessionRule.slowProfile()); - schemaChangeSession.execute(statement); - schemaChangeSession.checkSchemaAgreement(); - while (it.hasNext()) { - // Each row should have a value for k and v, but b should not be present as it was not part - // of the original metadata. - Row row = it.next(); - assertThat(row.getString("k")).isNotNull(); - assertThat(row.isNull("v")).isFalse(); - assertThat(row.getColumnDefinitions().contains("b")).isFalse(); - } - // Subsequent queries should contain b in metadata since its a new query. - result = session.executeContinuously(simple); - it = result.iterator(); - while (it.hasNext()) { - Row row = it.next(); - assertThat(row.getString("k")).isNotNull(); - assertThat(row.isNull("v")).isFalse(); - // b should be null, but present in metadata. - assertThat(row.isNull("b")).isTrue(); - assertThat(row.getColumnDefinitions().contains("b")).isTrue(); - } - } - - /** - * Validates that continuous paging is resilient to a schema change being made in the middle of - * producing pages for the driver if the query was prepared. - * - *

Drops column 'v' after paging the first row in. This column should still be present in the - * in-flight queries' rows, but it's value should be null. The column should not be present in - * subsequent queries. - * - * @test_category queries - * @jira_ticket JAVA-1653 - * @since 1.2.0 - */ - @Test - public void prepared_statement_paging_should_be_resilient_to_schema_change() { - CqlSession session = sessionRule.session(); - // Create table and prepare select * query against it. - session.execute( - SimpleStatement.newInstance("CREATE TABLE test_prep (k text PRIMARY KEY, v int)") - .setExecutionProfile(SessionUtils.slowProfile(session))); - for (int i = 0; i < 100; i++) { - session.execute(String.format("INSERT INTO test_prep (k, v) VALUES ('foo', %d)", i)); - } - PreparedStatement prepared = session.prepare("SELECT * FROM test_prep WHERE k = ?"); - DriverExecutionProfile profile = - session - .getContext() - .getConfig() - .getDefaultProfile() - .withInt(DseDriverOption.CONTINUOUS_PAGING_MAX_ENQUEUED_PAGES, 1) - .withInt(DseDriverOption.CONTINUOUS_PAGING_PAGE_SIZE, 1) - .withDuration( - DseDriverOption.CONTINUOUS_PAGING_TIMEOUT_FIRST_PAGE, Duration.ofSeconds(30)) - .withDuration( - DseDriverOption.CONTINUOUS_PAGING_TIMEOUT_OTHER_PAGES, Duration.ofSeconds(30)); - ContinuousResultSet result = - session.executeContinuously(prepared.bind("foo").setExecutionProfile(profile)); - Iterator it = result.iterator(); - // First row should have a non-null value for v. - Row row0 = it.next(); - assertThat(row0.getString("k")).isNotNull(); - assertThat(row0.isNull("v")).isFalse(); - // Make schema change to drop v, its metadata should be present, values will be null. - CqlSession schemaChangeSession = - SessionUtils.newSession( - ccmRule, session.getKeyspace().orElseThrow(IllegalStateException::new)); - schemaChangeSession.execute( - SimpleStatement.newInstance("ALTER TABLE test_prep DROP v;") - .setExecutionProfile(SessionUtils.slowProfile(schemaChangeSession))); - while (it.hasNext()) { - // Each row should have a value for k, v should still be present, but null since column was - // dropped. - Row row = it.next(); - assertThat(row.getString("k")).isNotNull(); - if (ccmRule.isDistributionOf( - BackendType.DSE, (dist, cass) -> dist.compareTo(Version.parse("6.0.0")) >= 0)) { - // DSE 6 only, v should be null here since dropped. - // Not reliable for 5.1 since we may have gotten page queued before schema changed. - assertThat(row.isNull("v")).isTrue(); - } - assertThat(row.getColumnDefinitions().contains("v")).isTrue(); - } - // Subsequent queries should lack v from metadata as it was dropped. - prepared = session.prepare("SELECT * FROM test_prep WHERE k = ?"); - result = session.executeContinuously(prepared.bind("foo").setExecutionProfile(profile)); - it = result.iterator(); - while (it.hasNext()) { - Row row = it.next(); - assertThat(row.getString("k")).isNotNull(); - assertThat(row.getColumnDefinitions().contains("v")).isFalse(); - } - } - - /** - * Validates that {@link ContinuousResultSet#cancel()} will cancel a continuous paging session by - * setting maxPagesPerSecond to 1 and sending a cancel immediately and ensuring the total number - * of rows iterated over is equal to the size of pageSize. - * - *

Also validates that it is possible to resume the operation using the paging state, as - * described in the javadocs of {@link ContinuousResultSet#cancel()}. - * - * @test_category queries - * @jira_ticket JAVA-1322 - * @since 1.2.0 - */ - @Test - public void should_cancel_with_synchronous_paging() { - CqlSession session = sessionRule.session(); - SimpleStatement statement = SimpleStatement.newInstance("SELECT v from test where k=?", KEY); - // create options and throttle at a page per second so - // cancel can go out before the next page is sent. - // Note that this might not be perfect if there are pauses - // in the JVM and cancel isn't sent soon enough. - DriverExecutionProfile profile = - session - .getContext() - .getConfig() - .getDefaultProfile() - .withInt(DseDriverOption.CONTINUOUS_PAGING_MAX_ENQUEUED_PAGES, 1) - .withInt(DseDriverOption.CONTINUOUS_PAGING_PAGE_SIZE, 10) - .withInt(DseDriverOption.CONTINUOUS_PAGING_MAX_PAGES_PER_SECOND, 1); - ContinuousResultSet pagingResult = - session.executeContinuously(statement.setExecutionProfile(profile)); - pagingResult.cancel(); - int i = 0; - for (Row row : pagingResult) { - assertThat(row.getInt("v")).isEqualTo(i); - i++; - } - // Expect only 10 rows as paging was cancelled immediately. - assertThat(i).isEqualTo(10); - // attempt to resume the operation from where we left - ByteBuffer pagingState = pagingResult.getExecutionInfo().getPagingState(); - ContinuousResultSet pagingResultResumed = - session.executeContinuously( - statement - .setExecutionProfile( - profile.withInt(DseDriverOption.CONTINUOUS_PAGING_MAX_PAGES_PER_SECOND, 0)) - .setPagingState(pagingState)); - for (Row row : pagingResultResumed) { - assertThat(row.getInt("v")).isEqualTo(i); - i++; - } - assertThat(i).isEqualTo(100); - } - - /** - * Validates that {@link ContinuousAsyncResultSet#cancel()} will cancel a continuous paging - * session by setting maxPagesPerSecond to 1 and sending a cancel after the first page is received - * and then ensuring that the future returned from {@link - * ContinuousAsyncResultSet#fetchNextPage()} fails. - * - *

Also validates that it is possible to resume the operation using the paging state, as - * described in the javadocs of {@link ContinuousAsyncResultSet#cancel()}. - * - * @test_category queries - * @jira_ticket JAVA-1322 - * @since 1.2.0 - */ - @Test - public void should_cancel_with_asynchronous_paging() { - CqlSession session = sessionRule.session(); - SimpleStatement statement = SimpleStatement.newInstance("SELECT v from test where k=?", KEY); - // create options and throttle at a page per second so - // cancel can go out before the next page is sent. - // Note that this might not be perfect if there are pauses - // in the JVM and cancel isn't sent soon enough. - DriverExecutionProfile profile = - session - .getContext() - .getConfig() - .getDefaultProfile() - .withInt(DseDriverOption.CONTINUOUS_PAGING_PAGE_SIZE, 10) - .withInt(DseDriverOption.CONTINUOUS_PAGING_MAX_PAGES_PER_SECOND, 1); - CompletionStage future = - session.executeContinuouslyAsync(statement.setExecutionProfile(profile)); - ContinuousAsyncResultSet pagingResult = CompletableFutures.getUninterruptibly(future); - // Calling cancel on the previous result should cause the next future to timeout. - pagingResult.cancel(); - CompletionStage fetchNextPageFuture = pagingResult.fetchNextPage(); - try { - // Expect future to fail since it was cancelled. - CompletableFutures.getUninterruptibly(fetchNextPageFuture); - fail("Expected an execution exception since paging was cancelled."); - } catch (CancellationException e) { - assertThat(e) - .hasMessageContaining("Can't get more results") - .hasMessageContaining("query was cancelled"); - } - int i = 0; - for (Row row : pagingResult.currentPage()) { - assertThat(row.getInt("v")).isEqualTo(i); - i++; - } - // Expect only 10 rows as this is the defined page size. - assertThat(i).isEqualTo(10); - // attempt to resume the operation from where we left - ByteBuffer pagingState = pagingResult.getExecutionInfo().getPagingState(); - future = - session.executeContinuouslyAsync( - statement - .setExecutionProfile( - profile.withInt(DseDriverOption.CONTINUOUS_PAGING_MAX_PAGES_PER_SECOND, 0)) - .setPagingState(pagingState)); - ContinuousAsyncResultSet pagingResultResumed; - do { - pagingResultResumed = CompletableFutures.getUninterruptibly(future); - for (Row row : pagingResultResumed.currentPage()) { - assertThat(row.getInt("v")).isEqualTo(i); - i++; - } - if (pagingResultResumed.hasMorePages()) { - future = pagingResultResumed.fetchNextPage(); - } - } while (pagingResultResumed.hasMorePages()); - // expect 10 more rows - assertThat(i).isEqualTo(100); - } - - /** - * Validates that {@link ContinuousAsyncResultSet#cancel()} will cancel a continuous paging - * session and current tracked {@link CompletionStage} tied to the paging session. - * - *

Also validates that it is possible to resume the operation using the paging state, as - * described in the javadocs of {@link ContinuousAsyncResultSet#cancel()}. - * - * @test_category queries - * @jira_ticket JAVA-1322 - * @since 1.2.0 - */ - @Test - public void should_cancel_future_when_cancelling_previous_result() { - CqlSession session = sessionRule.session(); - SimpleStatement statement = SimpleStatement.newInstance("SELECT v from test where k=?", KEY); - // create options and throttle at a page per second so - // cancel can go out before the next page is sent. - // Note that this might not be perfect if there are pauses - // in the JVM and cancel isn't sent soon enough. - DriverExecutionProfile profile = - session - .getContext() - .getConfig() - .getDefaultProfile() - .withInt(DseDriverOption.CONTINUOUS_PAGING_PAGE_SIZE, 10) - .withInt(DseDriverOption.CONTINUOUS_PAGING_MAX_PAGES_PER_SECOND, 1); - CompletionStage future = - session.executeContinuouslyAsync(statement.setExecutionProfile(profile)); - ContinuousAsyncResultSet pagingResult = CompletableFutures.getUninterruptibly(future); - CompletionStage fetchNextPageFuture = pagingResult.fetchNextPage(); - // Calling cancel on the previous result should cause the current future to be cancelled. - pagingResult.cancel(); - assertThat(fetchNextPageFuture.toCompletableFuture().isCancelled()).isTrue(); - try { - // Expect future to be cancelled since the previous result was cancelled. - CompletableFutures.getUninterruptibly(fetchNextPageFuture); - fail("Expected a cancellation exception since previous result was cancelled."); - } catch (CancellationException ce) { - // expected - } - int i = 0; - for (Row row : pagingResult.currentPage()) { - assertThat(row.getInt("v")).isEqualTo(i); - i++; - } - // Expect only 10 rows as this is the defined page size. - assertThat(i).isEqualTo(10); - // attempt to resume the operation from where we left - ByteBuffer pagingState = pagingResult.getExecutionInfo().getPagingState(); - future = - session.executeContinuouslyAsync( - statement - .setExecutionProfile( - profile.withInt(DseDriverOption.CONTINUOUS_PAGING_MAX_PAGES_PER_SECOND, 0)) - .setPagingState(pagingState)); - ContinuousAsyncResultSet pagingResultResumed; - do { - pagingResultResumed = CompletableFutures.getUninterruptibly(future); - for (Row row : pagingResultResumed.currentPage()) { - assertThat(row.getInt("v")).isEqualTo(i); - i++; - } - if (pagingResultResumed.hasMorePages()) { - future = pagingResultResumed.fetchNextPage(); - } - } while (pagingResultResumed.hasMorePages()); - // expect 10 more rows - assertThat(i).isEqualTo(100); - } - - /** - * Validates that {@link CompletableFuture#cancel(boolean)} will cancel a continuous paging - * session by setting maxPagesPerSecond to 1 and sending a cancel after the first page is received - * and then ensuring that the future returned from {@link - * ContinuousAsyncResultSet#fetchNextPage()} is cancelled. - * - *

Also validates that it is possible to resume the operation using the paging state, as - * described in the javadocs of {@link ContinuousAsyncResultSet#cancel()}. - * - * @test_category queries - * @jira_ticket JAVA-1322 - * @since 1.2.0 - */ - @Test - public void should_cancel_when_future_is_cancelled() { - CqlSession session = sessionRule.session(); - SimpleStatement statement = SimpleStatement.newInstance("SELECT v from test where k=?", KEY); - // create options and throttle at a page per second so - // cancel can go out before the next page is sent. - // Note that this might not be perfect if there are pauses - // in the JVM and cancel isn't sent soon enough. - DriverExecutionProfile profile = - session - .getContext() - .getConfig() - .getDefaultProfile() - .withInt(DseDriverOption.CONTINUOUS_PAGING_PAGE_SIZE, 10) - .withInt(DseDriverOption.CONTINUOUS_PAGING_MAX_PAGES_PER_SECOND, 1); - CompletionStage future = - session.executeContinuouslyAsync(statement.setExecutionProfile(profile)); - ContinuousAsyncResultSet pagingResult = CompletableFutures.getUninterruptibly(future); - CompletableFuture fetchNextPageFuture = pagingResult.fetchNextPage().toCompletableFuture(); - fetchNextPageFuture.cancel(false); - assertThat(fetchNextPageFuture.isCancelled()).isTrue(); - try { - // Expect cancellation. - CompletableFutures.getUninterruptibly(fetchNextPageFuture); - fail("Expected a cancellation exception since future was cancelled."); - } catch (CancellationException ce) { - // expected - } - int i = 0; - for (Row row : pagingResult.currentPage()) { - assertThat(row.getInt("v")).isEqualTo(i); - i++; - } - // Expect only 10 rows as this is the defined page size. - assertThat(i).isEqualTo(10); - // attempt to resume the operation from where we left - ByteBuffer pagingState = pagingResult.getExecutionInfo().getPagingState(); - future = - session.executeContinuouslyAsync( - statement - .setExecutionProfile( - profile.withInt(DseDriverOption.CONTINUOUS_PAGING_MAX_PAGES_PER_SECOND, 0)) - .setPagingState(pagingState)); - ContinuousAsyncResultSet pagingResultResumed; - do { - pagingResultResumed = CompletableFutures.getUninterruptibly(future); - for (Row row : pagingResultResumed.currentPage()) { - assertThat(row.getInt("v")).isEqualTo(i); - i++; - } - if (pagingResultResumed.hasMorePages()) { - future = pagingResultResumed.fetchNextPage(); - } - } while (pagingResultResumed.hasMorePages()); - // expect 10 more rows - assertThat(i).isEqualTo(100); - } - - /** - * Validates that a client-side timeout is correctly reported to the caller. - * - * @test_category queries - * @jira_ticket JAVA-1390 - * @since 1.2.0 - */ - @Test - public void should_time_out_when_server_does_not_produce_pages_fast_enough() throws Exception { - CqlSession session = sessionRule.session(); - SimpleStatement statement = SimpleStatement.newInstance("SELECT v from test where k=?", KEY); - // Throttle server at a page per second and set client timeout much lower so that the client - // will experience a timeout. - // Note that this might not be perfect if there are pauses in the JVM and the timeout - // doesn't fire soon enough. - DriverExecutionProfile profile = - session - .getContext() - .getConfig() - .getDefaultProfile() - .withInt(DseDriverOption.CONTINUOUS_PAGING_PAGE_SIZE, 10) - .withInt(DseDriverOption.CONTINUOUS_PAGING_MAX_PAGES_PER_SECOND, 1) - .withDuration( - DseDriverOption.CONTINUOUS_PAGING_TIMEOUT_OTHER_PAGES, Duration.ofMillis(100)); - CompletionStage future = - session.executeContinuouslyAsync(statement.setExecutionProfile(profile)); - ContinuousAsyncResultSet pagingResult = CompletableFutures.getUninterruptibly(future); - try { - pagingResult.fetchNextPage().toCompletableFuture().get(); - fail("Expected a timeout"); - } catch (ExecutionException e) { - assertThat(e.getCause()) - .isInstanceOf(DriverTimeoutException.class) - .hasMessageContaining("Timed out waiting for page 2"); - } - } - - /** - * Validates that the driver behaves appropriately when the client gets behind while paging rows - * in a continuous paging session. The driver should set autoread to false on the channel for that - * connection until the client consumes enough pages, at which point it will reenable autoread and - * continue reading. - * - *

There is not really a direct way to verify that autoread is disabled, but delaying - * immediately after executing a continuous paging query should produce this effect. - * - * @test_category queries - * @jira_ticket JAVA-1375 - * @since 1.2.0 - */ - @Test - public void should_resume_reading_when_client_catches_up() { - CqlSession session = sessionRule.session(); - SimpleStatement statement = - SimpleStatement.newInstance("SELECT * from test_autoread where k=?", KEY); - DriverExecutionProfile profile = - session - .getContext() - .getConfig() - .getDefaultProfile() - .withInt(DseDriverOption.CONTINUOUS_PAGING_PAGE_SIZE, 100); - CompletionStage result = - session.executeContinuouslyAsync(statement.setExecutionProfile(profile)); - // Defer consuming of rows for a second, this should cause autoread to be disabled. - Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS); - // Start consuming rows, this should cause autoread to be reenabled once we consume some pages. - PageStatistics stats = - CompletableFutures.getUninterruptibly( - result.thenCompose(new AsyncContinuousPagingFunction())); - // 20k rows in this table. - assertThat(stats.rows).isEqualTo(20000); - // 200 * 100 = 20k. - assertThat(stats.pages).isEqualTo(200); - } - - private static class PageStatistics { - int rows; - int pages; - - PageStatistics(int rows, int pages) { - this.rows = rows; - this.pages = pages; - } - } - - /** - * A function that when invoked, will return a transformed future with another {@link - * AsyncContinuousPagingFunction} wrapping {@link ContinuousAsyncResultSet#fetchNextPage()} if - * there are more pages, otherwise returns an immediate future that shares {@link PageStatistics} - * about how many rows were returned and how many pages were encountered. - * - *

Note that if observe that data is not parsed in order this future fails with an Exception. - */ - private static class AsyncContinuousPagingFunction - implements Function> { - - private final int rowsSoFar; - - AsyncContinuousPagingFunction() { - this(0); - } - - AsyncContinuousPagingFunction(int rowsSoFar) { - this.rowsSoFar = rowsSoFar; - } - - @Override - public CompletionStage apply(ContinuousAsyncResultSet input) { - int rows = rowsSoFar; - // Iterate over page and ensure data is in order. - for (Row row : input.currentPage()) { - int v = row.getInt("v"); - if (v != rows) { - fail(String.format("Expected v == %d, got %d.", rows, v)); - } - rows++; - } - // If on last page, complete future, otherwise keep iterating. - if (!input.hasMorePages()) { - // DSE may send an empty page as it can't always know if it's done paging or not yet. - // See: CASSANDRA-8871. In this case, don't count this page. - int pages = rows == rowsSoFar ? input.pageNumber() - 1 : input.pageNumber(); - CompletableFuture future = new CompletableFuture<>(); - future.complete(new PageStatistics(rows, pages)); - return future; - } else { - return input.fetchNextPage().thenCompose(new AsyncContinuousPagingFunction(rows)); - } - } - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/cql/continuous/ContinuousPagingITBase.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/cql/continuous/ContinuousPagingITBase.java deleted file mode 100644 index 4a68454d559..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/cql/continuous/ContinuousPagingITBase.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.cql.continuous; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.awaitility.Awaitility.await; - -import com.codahale.metrics.Timer; -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.dse.driver.api.core.metrics.DseSessionMetric; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.cql.BatchStatement; -import com.datastax.oss.driver.api.core.cql.DefaultBatchType; -import com.datastax.oss.driver.api.core.cql.PreparedStatement; -import com.datastax.oss.driver.api.core.cql.SimpleStatement; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.datastax.oss.driver.api.core.metrics.DefaultNodeMetric; -import com.datastax.oss.driver.api.core.metrics.Metrics; -import com.tngtech.java.junit.dataprovider.DataProvider; -import java.time.Duration; -import java.util.UUID; - -public abstract class ContinuousPagingITBase { - - protected static final String KEY = "k"; - - static PreparedStatement prepared; - - protected static void initialize(CqlSession session, DriverExecutionProfile slowProfile) { - session.execute( - SimpleStatement.newInstance("CREATE TABLE test (k text, v int, PRIMARY KEY (k, v))") - .setExecutionProfile(slowProfile)); - // Load enough rows to cause TCP Zero Window. Default window size is 65535 bytes, each row - // is at least 48 bytes, so it would take ~1365 enqueued rows to zero window. - // Conservatively load 20k rows. - session.execute( - SimpleStatement.newInstance( - "CREATE TABLE test_autoread (k text, v int, v0 uuid, v1 uuid, PRIMARY KEY (k, v, v0))") - .setExecutionProfile(slowProfile)); - session.execute( - SimpleStatement.newInstance("CREATE TABLE test_prepare (k text PRIMARY KEY, v int)") - .setExecutionProfile(slowProfile)); - session.checkSchemaAgreement(); - prepared = session.prepare("SELECT v from test where k = ?"); - for (int i = 0; i < 100; i++) { - session.execute(String.format("INSERT INTO test (k, v) VALUES ('%s', %d)", KEY, i)); - } - int count = 0; - for (int i = 0; i < 200; i++) { - BatchStatement batch = BatchStatement.newInstance(DefaultBatchType.UNLOGGED); - for (int j = 0; j < 100; j++) { - batch = - batch.add( - SimpleStatement.newInstance( - "INSERT INTO test_autoread (k, v, v0, v1) VALUES (?, ?, ?, ?)", - KEY, - count++, - UUID.randomUUID(), - UUID.randomUUID())); - } - session.execute(batch); - } - for (int i = 0; i < 100; i++) { - session.execute(String.format("INSERT INTO test_prepare (k, v) VALUES ('%d', %d)", i, i)); - } - } - - @DataProvider(format = "%m[%p[0]]") - public static Object[][] pagingOptions() { - return new Object[][] { - // exact # of rows. - {new Options(100, false, 0, 0, 100, 1)}, - // # of rows - 1. - {new Options(99, false, 0, 0, 100, 2)}, - // # of rows / 2. - {new Options(50, false, 0, 0, 100, 2)}, - // # 1 row per page. - {new Options(1, false, 0, 0, 100, 100)}, - // 10 rows per page, 10 pages overall = 100 (exact). - {new Options(10, false, 10, 0, 100, 10)}, - // 10 rows per page, 9 pages overall = 90 (less than exact number of pages). - {new Options(10, false, 9, 0, 90, 9)}, - // 10 rows per page, 2 pages per second should take ~5secs. - {new Options(10, false, 0, 2, 100, 10)}, - // 8 bytes per page == 1 row per page as len(4) + int(4) for each row. - {new Options(8, true, 0, 0, 100, 100)}, - // 16 bytes per page == 2 rows page per page. - {new Options(16, true, 0, 0, 100, 50)}, - // 32 bytes per page == 4 rows per page. - {new Options(32, true, 0, 0, 100, 25)} - }; - } - - protected void validateMetrics(CqlSession session) { - Node node = session.getMetadata().getNodes().values().iterator().next(); - assertThat(session.getMetrics()).as("assert session.getMetrics() present").isPresent(); - Metrics metrics = session.getMetrics().get(); - assertThat(metrics.getNodeMetric(node, DefaultNodeMetric.CQL_MESSAGES)) - .as("assert metrics.getNodeMetric(node, DefaultNodeMetric.CQL_MESSAGES) present") - .isPresent(); - Timer messages = (Timer) metrics.getNodeMetric(node, DefaultNodeMetric.CQL_MESSAGES).get(); - await() - .atMost(Duration.ofSeconds(5)) - .untilAsserted( - () -> { - assertThat(messages.getCount()) - .as("assert messages.getCount() >= 0") - .isGreaterThan(0); - assertThat(messages.getMeanRate()) - .as("assert messages.getMeanRate() >= 0") - .isGreaterThan(0); - }); - assertThat(metrics.getSessionMetric(DseSessionMetric.CONTINUOUS_CQL_REQUESTS)) - .as("assert metrics.getSessionMetric(DseSessionMetric.CONTINUOUS_CQL_REQUESTS) present") - .isPresent(); - Timer requests = - (Timer) metrics.getSessionMetric(DseSessionMetric.CONTINUOUS_CQL_REQUESTS).get(); - await() - .atMost(Duration.ofSeconds(5)) - .untilAsserted( - () -> { - assertThat(requests.getCount()) - .as("assert requests.getCount() >= 0") - .isGreaterThan(0); - assertThat(requests.getMeanRate()) - .as("assert requests.getMeanRate() >= 0") - .isGreaterThan(0); - }); - } - - public static class Options { - public int pageSize; - public boolean sizeInBytes; - public int maxPages; - public int maxPagesPerSecond; - public int expectedRows; - public int expectedPages; - - Options( - int pageSize, - boolean sizeInBytes, - int maxPages, - int maxPagesPerSecond, - int expectedRows, - int expectedPages) { - this.pageSize = pageSize; - this.sizeInBytes = sizeInBytes; - this.maxPages = maxPages; - this.maxPagesPerSecond = maxPagesPerSecond; - this.expectedRows = expectedRows; - this.expectedPages = expectedPages; - } - - public DriverExecutionProfile asProfile(CqlSession session) { - return session - .getContext() - .getConfig() - .getDefaultProfile() - .withInt(DseDriverOption.CONTINUOUS_PAGING_PAGE_SIZE, pageSize) - .withBoolean(DseDriverOption.CONTINUOUS_PAGING_PAGE_SIZE_BYTES, sizeInBytes) - .withInt(DseDriverOption.CONTINUOUS_PAGING_MAX_PAGES, maxPages) - .withInt(DseDriverOption.CONTINUOUS_PAGING_MAX_PAGES_PER_SECOND, maxPagesPerSecond); - } - - @Override - public String toString() { - return "pageSize=" - + pageSize - + ", sizeInBytes=" - + sizeInBytes - + ", maxPages=" - + maxPages - + ", maxPagesPerSecond=" - + maxPagesPerSecond - + ", expectedRows=" - + expectedRows - + ", expectedPages=" - + expectedPages; - } - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/cql/continuous/reactive/ContinuousPagingReactiveIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/cql/continuous/reactive/ContinuousPagingReactiveIT.java deleted file mode 100644 index f2a28d72597..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/cql/continuous/reactive/ContinuousPagingReactiveIT.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.cql.continuous.reactive; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.dse.driver.api.core.cql.continuous.ContinuousPagingITBase; -import com.datastax.dse.driver.api.core.cql.reactive.ReactiveRow; -import com.datastax.dse.driver.api.core.metrics.DseSessionMetric; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.config.DefaultDriverOption; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.cql.ColumnDefinitions; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import com.datastax.oss.driver.api.core.cql.SimpleStatement; -import com.datastax.oss.driver.api.core.metrics.DefaultNodeMetric; -import com.datastax.oss.driver.api.testinfra.ccm.CcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import com.datastax.oss.driver.api.testinfra.session.SessionUtils; -import com.datastax.oss.driver.categories.ParallelizableTests; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import io.reactivex.Flowable; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; -import org.junit.runner.RunWith; - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "5.1.0", - description = "Continuous paging is only available from 5.1.0 onwards") -@Category(ParallelizableTests.class) -@RunWith(DataProviderRunner.class) -public class ContinuousPagingReactiveIT extends ContinuousPagingITBase { - - private static CcmRule ccmRule = CcmRule.getInstance(); - - private static SessionRule sessionRule = - SessionRule.builder(ccmRule) - .withConfigLoader( - SessionUtils.configLoaderBuilder() - .withStringList( - DefaultDriverOption.METRICS_SESSION_ENABLED, - Collections.singletonList(DseSessionMetric.CONTINUOUS_CQL_REQUESTS.getPath())) - .withStringList( - DefaultDriverOption.METRICS_NODE_ENABLED, - Collections.singletonList(DefaultNodeMetric.CQL_MESSAGES.getPath())) - .build()) - .build(); - - @ClassRule public static TestRule chain = RuleChain.outerRule(ccmRule).around(sessionRule); - - @BeforeClass - public static void setUp() { - initialize(sessionRule.session(), sessionRule.slowProfile()); - } - - @Test - @UseDataProvider("pagingOptions") - public void should_execute_reactively(Options options) { - CqlSession session = sessionRule.session(); - SimpleStatement statement = SimpleStatement.newInstance("SELECT v from test where k=?", KEY); - DriverExecutionProfile profile = options.asProfile(session); - ContinuousReactiveResultSet rs = - session.executeContinuouslyReactive(statement.setExecutionProfile(profile)); - List results = Flowable.fromPublisher(rs).toList().blockingGet(); - assertThat(results).hasSize(options.expectedRows); - Set expectedExecInfos = new LinkedHashSet<>(); - for (int i = 0; i < results.size(); i++) { - ReactiveRow row = results.get(i); - assertThat(row.getInt("v")).isEqualTo(i); - expectedExecInfos.add(row.getExecutionInfo()); - } - - List execInfos = - Flowable.fromPublisher(rs.getExecutionInfos()).toList().blockingGet(); - // DSE may send an empty page as it can't always know if it's done paging or not yet. - // See: CASSANDRA-8871. In this case, this page's execution info appears in - // rs.getExecutionInfos(), but is not present in expectedExecInfos since the page did not - // contain any rows. - assertThat(execInfos).containsAll(expectedExecInfos); - - List colDefs = - Flowable.fromPublisher(rs.getColumnDefinitions()).toList().blockingGet(); - ReactiveRow first = results.get(0); - assertThat(colDefs).hasSize(1).containsExactly(first.getColumnDefinitions()); - - List wasApplied = Flowable.fromPublisher(rs.wasApplied()).toList().blockingGet(); - assertThat(wasApplied).hasSize(1).containsExactly(first.wasApplied()); - - validateMetrics(session); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/data/geometry/GeometryIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/data/geometry/GeometryIT.java deleted file mode 100644 index 83b01796337..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/data/geometry/GeometryIT.java +++ /dev/null @@ -1,405 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.data.geometry; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.cql.BatchStatement; -import com.datastax.oss.driver.api.core.cql.BatchStatementBuilder; -import com.datastax.oss.driver.api.core.cql.BoundStatement; -import com.datastax.oss.driver.api.core.cql.DefaultBatchType; -import com.datastax.oss.driver.api.core.cql.PreparedStatement; -import com.datastax.oss.driver.api.core.cql.ResultSet; -import com.datastax.oss.driver.api.core.cql.Row; -import com.datastax.oss.driver.api.core.cql.SimpleStatement; -import com.datastax.oss.driver.api.core.data.TupleValue; -import com.datastax.oss.driver.api.core.data.UdtValue; -import com.datastax.oss.driver.api.core.type.TupleType; -import com.datastax.oss.driver.api.core.type.UserDefinedType; -import com.datastax.oss.driver.api.core.type.codec.TypeCodec; -import com.datastax.oss.driver.api.core.type.reflect.GenericType; -import com.datastax.oss.driver.api.core.uuid.Uuids; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import com.datastax.oss.driver.categories.ParallelizableTests; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import com.datastax.oss.driver.shaded.guava.common.collect.Sets; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import org.assertj.core.util.Preconditions; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.experimental.categories.Category; - -@Category({ParallelizableTests.class}) -public abstract class GeometryIT { - - private final Class genericType; - private final T baseSample; - private final List sampleData; - private final SessionRule sessionRule; - - @SuppressWarnings("unchecked") - GeometryIT(List sampleData, Class genericType, SessionRule sessionRule) { - Preconditions.checkArgument( - sampleData.size() >= 3, "Must be at least 3 samples, was given " + sampleData.size()); - this.baseSample = sampleData.get(0); - this.genericType = genericType; - this.sampleData = sampleData; - this.sessionRule = sessionRule; - } - - static void onTestContextInitialized(String cqlTypeName, SessionRule sessionRule) { - sessionRule - .session() - .execute( - SimpleStatement.builder(String.format("CREATE TYPE udt1 (g '%s')", cqlTypeName)) - .setExecutionProfile(sessionRule.slowProfile()) - .build()); - sessionRule - .session() - .execute( - SimpleStatement.builder( - String.format( - "CREATE TABLE tbl (k uuid PRIMARY KEY, g '%s', l list<'%s'>, s set<'%s'>, m0 map<'%s',int>, m1 map, t tuple<'%s','%s','%s'>, u frozen)", - cqlTypeName, - cqlTypeName, - cqlTypeName, - cqlTypeName, - cqlTypeName, - cqlTypeName, - cqlTypeName, - cqlTypeName)) - .setExecutionProfile(sessionRule.slowProfile()) - .build()); - sessionRule - .session() - .execute( - SimpleStatement.builder( - String.format("CREATE TABLE tblpk (k '%s' primary key, v int)", cqlTypeName)) - .setExecutionProfile(sessionRule.slowProfile()) - .build()); - sessionRule - .session() - .execute( - SimpleStatement.builder( - String.format( - "CREATE TABLE tblclustering (k0 int, k1 '%s', v int, primary key (k0, k1))", - cqlTypeName)) - .setExecutionProfile(sessionRule.slowProfile()) - .build()); - } - - private void validate(UUID key, String columnName, V expected, GenericType type) { - ResultSet result = - sessionRule - .session() - .execute( - SimpleStatement.builder( - String.format("SELECT k,%s FROM tbl where k =? ", columnName)) - .addPositionalValue(key) - .build()); - Row row = result.iterator().next(); - assertThat(row.getUuid("k")).isEqualTo(key); - assertThat(row.get(columnName, type)).isEqualTo(expected); - assertThat(row.get(1, type)).isEqualTo(expected); - } - - private void validate(UUID key, T expected) { - validate(key, "g", expected, GenericType.of(genericType)); - } - - /** - * Validates that a given geometry value can be inserted into a column using codec.format() and - * verifies that it is stored correctly by retrieving it and ensuring it matches. - */ - @Test - public void should_insert_using_format() { - for (T expected : sampleData) { - - String val = null; - if (expected != null) { - TypeCodec codec = - sessionRule.session().getContext().getCodecRegistry().codecFor(expected); - val = codec.format(expected); - } - UUID key = Uuids.random(); - sessionRule - .session() - .execute(String.format("INSERT INTO tbl (k, g) VALUES (%s, %s)", key, val)); - validate(key, expected); - } - } - - /** - * Validates that a given geometry value can be inserted into a column by providing it as a simple - * statement parameter and verifies that it is stored correctly by retrieving it and ensuring it - * matches. - */ - @Test - public void should_insert_using_simple_statement_with_parameters() { - for (T expected : sampleData) { - UUID key = Uuids.random(); - sessionRule - .session() - .execute( - SimpleStatement.builder("INSERT INTO tbl (k, g) VALUES (?, ?)") - .addPositionalValues(key, expected) - .build()); - validate(key, expected); - } - } - /** - * Validates that a given geometry value can be inserted into a column by providing it as a bound - * parameter in a BoundStatement and verifies that it is stored correctly by retrieving it and - * ensuring it matches. - */ - @Test - public void should_insert_using_prepared_statement_with_parameters() { - for (T expected : sampleData) { - UUID key = Uuids.random(); - PreparedStatement prepared = - sessionRule.session().prepare("INSERT INTO tbl (k, g) values (?, ?)"); - BoundStatement bs = - prepared.boundStatementBuilder().setUuid(0, key).set(1, expected, genericType).build(); - sessionRule.session().execute(bs); - validate(key, expected); - } - } - /** - * Validates that geometry values can be inserted as a list and verifies that the list is stored - * correctly by retrieving it and ensuring it matches. - */ - @Test - public void should_insert_as_list() { - UUID key = Uuids.random(); - PreparedStatement prepared = - sessionRule.session().prepare("INSERT INTO tbl (k, l) values (?, ?)"); - - BoundStatement bs = - prepared - .boundStatementBuilder() - .setUuid(0, key) - .setList(1, sampleData, genericType) - .build(); - sessionRule.session().execute(bs); - validate(key, "l", sampleData, GenericType.listOf(genericType)); - } - /** - * Validates that geometry values can be inserted as a set and verifies that the set is stored - * correctly by retrieving it and ensuring it matches. - */ - @Test - public void should_insert_as_set() { - UUID key = Uuids.random(); - Set asSet = Sets.newHashSet(sampleData); - - PreparedStatement prepared = - sessionRule.session().prepare("INSERT INTO tbl (k, s) values (?, ?)"); - BoundStatement bs = - prepared.boundStatementBuilder().setUuid(0, key).setSet(1, asSet, genericType).build(); - - sessionRule.session().execute(bs); - validate(key, "s", asSet, GenericType.setOf(genericType)); - } - - /** - * Validates that geometry values can be inserted into a map as keys and verifies that the map is - * stored correctly by retrieving it and ensuring it matches. - */ - @Test - public void should_insert_as_map_keys() { - UUID key = Uuids.random(); - ImmutableMap.Builder builder = ImmutableMap.builder(); - int count = 0; - for (T val : sampleData) { - builder = builder.put(val, count++); - } - Map asMapKeys = builder.build(); - - PreparedStatement prepared = - sessionRule.session().prepare("INSERT INTO tbl (k, m0) values (?, ?)"); - BoundStatement bs = - prepared - .boundStatementBuilder() - .setUuid(0, key) - .setMap(1, asMapKeys, genericType, Integer.class) - .build(); - sessionRule.session().execute(bs); - validate(key, "m0", asMapKeys, GenericType.mapOf(genericType, Integer.class)); - } - - /** - * Validates that geometry values can be inserted into a map as values and verifies that the map - * is stored correctly by retrieving it and ensuring it matches. - */ - @Test - public void should_insert_as_map_values() { - UUID key = Uuids.random(); - ImmutableMap.Builder builder = ImmutableMap.builder(); - int count = 0; - for (T val : sampleData) { - builder = builder.put(count++, val); - } - Map asMapValues = builder.build(); - PreparedStatement prepared = - sessionRule.session().prepare("INSERT INTO tbl (k, m1) values (?, ?)"); - BoundStatement bs = - prepared - .boundStatementBuilder() - .setUuid(0, key) - .setMap(1, asMapValues, Integer.class, genericType) - .build(); - sessionRule.session().execute(bs); - validate(key, "m1", asMapValues, GenericType.mapOf(Integer.class, genericType)); - } - - /** - * Validates that geometry values can be inserted as a tuple and verifies that the tuple is stored - * correctly by retrieving it and ensuring it matches. - */ - @Test - @Ignore - public void should_insert_as_tuple() { - UUID key = Uuids.random(); - - PreparedStatement prepared = - sessionRule.session().prepare("INSERT INTO tbl (k, t) values (?, ?)"); - TupleType tupleType = (TupleType) prepared.getVariableDefinitions().get(1).getType(); - TupleValue tuple = tupleType.newValue(); - tuple = tuple.set(0, sampleData.get(0), genericType); - tuple = tuple.set(1, sampleData.get(1), genericType); - tuple = tuple.set(2, sampleData.get(2), genericType); - BoundStatement bs = - prepared.boundStatementBuilder().setUuid(0, key).setTupleValue(1, tuple).build(); - sessionRule.session().execute(bs); - ResultSet rs = - sessionRule - .session() - .execute( - SimpleStatement.builder("SELECT k,t FROM tbl where k=?") - .addPositionalValues(key) - .build()); - Row row = rs.iterator().next(); - assertThat(row.getUuid("k")).isEqualTo(key); - assertThat(row.getTupleValue("t")).isEqualTo(tuple); - assertThat(row.getTupleValue(1)).isEqualTo(tuple); - } - /** - * Validates that a geometry value can be inserted as a field in a UDT and verifies that the UDT - * is stored correctly by retrieving it and ensuring it matches. - */ - @Test - @Ignore - public void should_insert_as_field_in_udt() { - UUID key = Uuids.random(); - UserDefinedType udtType = - sessionRule - .session() - .getMetadata() - .getKeyspace(sessionRule.session().getKeyspace().orElseThrow(AssertionError::new)) - .flatMap(ks -> ks.getUserDefinedType(CqlIdentifier.fromInternal("udt1"))) - .orElseThrow(AssertionError::new); - assertThat(udtType).isNotNull(); - UdtValue value = udtType.newValue(); - value = value.set("g", sampleData.get(0), genericType); - - PreparedStatement prepared = - sessionRule.session().prepare("INSERT INTO tbl (k, u) values (?, ?)"); - BoundStatement bs = - prepared.boundStatementBuilder().setUuid(0, key).setUdtValue(1, value).build(); - sessionRule.session().execute(bs); - - ResultSet rs = - sessionRule - .session() - .execute( - SimpleStatement.builder("SELECT k,u FROM tbl where k=?") - .addPositionalValues(key) - .build()); - Row row = rs.iterator().next(); - assertThat(row.getUuid("k")).isEqualTo(key); - assertThat(row.getUdtValue("u")).isEqualTo(value); - assertThat(row.getUdtValue(1)).isEqualTo(value); - } - - /** - * Validates that a geometry value can be inserted into a column that is the partition key and - * then validates that it can be queried back by partition key. - */ - @Test - public void should_accept_as_partition_key() { - sessionRule - .session() - .execute( - SimpleStatement.builder("INSERT INTO tblpk (k, v) VALUES (?,?)") - .addPositionalValues(baseSample, 1) - .build()); - ResultSet results = sessionRule.session().execute("SELECT k,v FROM tblpk"); - Row row = results.one(); - T key = row.get("k", genericType); - assertThat(key).isEqualTo(baseSample); - } - - /** - * Validates that geometry values can be inserted into a column that is a clustering key in rows - * sharing a partition key and then validates that the rows can be retrieved by partition key. - * - * @test_category dse:geospatial - */ - @Test - public void should_accept_as_clustering_key() { - PreparedStatement insert = - sessionRule.session().prepare("INSERT INTO tblclustering (k0, k1, v) values (?,?,?)"); - BatchStatementBuilder batchbuilder = BatchStatement.builder(DefaultBatchType.UNLOGGED); - - int count = 0; - for (T value : sampleData) { - BoundStatement bound = - insert - .boundStatementBuilder() - .setInt(0, 0) - .set(1, value, genericType) - .setInt(2, count++) - .build(); - batchbuilder.addStatement(bound); - } - sessionRule.session().execute(batchbuilder.build()); - - ResultSet result = - sessionRule - .session() - .execute( - SimpleStatement.builder("SELECT * from tblclustering where k0=?") - .addPositionalValue(0) - .build()); - - // The order of rows returned is not significant for geospatial types since it is stored in - // lexicographic byte order (8 bytes at a time). Thus we pull them all sort and extract and - // ensure all values were returned. - List rows = result.all(); - - assertThat(rows) - .extracting(row -> row.get("k1", genericType)) - .containsOnlyElementsOf(sampleData) - .hasSameSizeAs(sampleData); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/data/geometry/LineStringIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/data/geometry/LineStringIT.java deleted file mode 100644 index 3fbb4dd7b31..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/data/geometry/LineStringIT.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.data.geometry; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.cql.ResultSet; -import com.datastax.oss.driver.api.core.cql.Row; -import com.datastax.oss.driver.api.core.cql.SimpleStatement; -import com.datastax.oss.driver.api.core.uuid.Uuids; -import com.datastax.oss.driver.api.testinfra.ccm.CcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import com.datastax.oss.driver.categories.ParallelizableTests; -import java.util.List; -import java.util.UUID; -import org.assertj.core.util.Lists; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; - -@Category(ParallelizableTests.class) -@BackendRequirement(type = BackendType.DSE, minInclusive = "5.0") -public class LineStringIT extends GeometryIT { - - private static CcmRule ccm = CcmRule.getInstance(); - - private static SessionRule sessionRule = SessionRule.builder(ccm).build(); - - @ClassRule public static TestRule chain = RuleChain.outerRule(ccm).around(sessionRule); - - private static final String LINE_STRING_TYPE = "LineStringType"; - - public LineStringIT() { - super( - Lists.newArrayList( - LineString.fromPoints(Point.fromCoordinates(0, 10), Point.fromCoordinates(10, 0)), - LineString.fromPoints( - Point.fromCoordinates(30, 10), - Point.fromCoordinates(10, 30), - Point.fromCoordinates(40, 40)), - LineString.fromPoints( - Point.fromCoordinates(-5, 0), - Point.fromCoordinates(0, 10), - Point.fromCoordinates(10, 5))), - LineString.class, - sessionRule); - } - - @BeforeClass - public static void initialize() { - onTestContextInitialized(LINE_STRING_TYPE, sessionRule); - } - - @Test - public void should_insert_and_retrieve_empty_linestring() { - LineString empty = LineString.fromWellKnownText("LINESTRING EMPTY"); - UUID key = Uuids.random(); - sessionRule - .session() - .execute( - SimpleStatement.builder("INSERT INTO tbl (k, g) VALUES (?, ?)") - .addPositionalValues(key, empty) - .build()); - - ResultSet result = - sessionRule - .session() - .execute( - SimpleStatement.builder("SELECT g from tbl where k=?") - .addPositionalValues(key) - .build()); - Row row = result.iterator().next(); - List points = row.get("g", LineString.class).getPoints(); - assertThat(points.isEmpty()).isTrue(); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/data/geometry/PointIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/data/geometry/PointIT.java deleted file mode 100644 index 243ec4ccdf4..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/data/geometry/PointIT.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.data.geometry; - -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.testinfra.ccm.CcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import com.datastax.oss.driver.categories.ParallelizableTests; -import org.assertj.core.util.Lists; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.experimental.categories.Category; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; - -@Category(ParallelizableTests.class) -@BackendRequirement(type = BackendType.DSE, minInclusive = "5.0") -public class PointIT extends GeometryIT { - - private static CcmRule ccm = CcmRule.getInstance(); - - private static SessionRule sessionRule = SessionRule.builder(ccm).build(); - - @ClassRule public static TestRule chain = RuleChain.outerRule(ccm).around(sessionRule); - - private static final String POINT_TYPE = "PointType"; - - public PointIT() { - super( - Lists.newArrayList( - Point.fromCoordinates(-1.0, -5), - Point.fromCoordinates(0, 0), - Point.fromCoordinates(1.1, 2.2), - Point.fromCoordinates(Double.MIN_VALUE, 0), - Point.fromCoordinates(Double.MAX_VALUE, Double.MIN_VALUE)), - Point.class, - sessionRule); - } - - @BeforeClass - public static void initialize() { - onTestContextInitialized(POINT_TYPE, sessionRule); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/data/geometry/PolygonIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/data/geometry/PolygonIT.java deleted file mode 100644 index 6e345e05fa9..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/data/geometry/PolygonIT.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.data.geometry; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.cql.ResultSet; -import com.datastax.oss.driver.api.core.cql.Row; -import com.datastax.oss.driver.api.core.cql.SimpleStatement; -import com.datastax.oss.driver.api.core.uuid.Uuids; -import com.datastax.oss.driver.api.testinfra.ccm.CcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import com.datastax.oss.driver.categories.ParallelizableTests; -import java.util.UUID; -import org.assertj.core.util.Lists; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; - -@Category(ParallelizableTests.class) -@BackendRequirement(type = BackendType.DSE, minInclusive = "5.0") -public class PolygonIT extends GeometryIT { - - private static CcmRule ccm = CcmRule.getInstance(); - - private static SessionRule sessionRule = SessionRule.builder(ccm).build(); - - @ClassRule public static TestRule chain = RuleChain.outerRule(ccm).around(sessionRule); - - private static final String POLYGON_TYPE = "PolygonType"; - - private static Polygon squareInMinDomain = - Polygon.fromPoints( - Point.fromCoordinates(Double.MIN_VALUE, Double.MIN_VALUE), - Point.fromCoordinates(Double.MIN_VALUE, Double.MIN_VALUE + 1), - Point.fromCoordinates(Double.MIN_VALUE + 1, Double.MIN_VALUE + 1), - Point.fromCoordinates(Double.MIN_VALUE + 1, Double.MIN_VALUE)); - - private static Polygon triangle = - Polygon.fromPoints( - Point.fromCoordinates(-5, 10), - Point.fromCoordinates(5, 5), - Point.fromCoordinates(10, -5)); - - private static Polygon complexPolygon = - Polygon.builder() - .addRing( - Point.fromCoordinates(0, 0), - Point.fromCoordinates(0, 3), - Point.fromCoordinates(5, 3), - Point.fromCoordinates(5, 0)) - .addRing( - Point.fromCoordinates(1, 1), - Point.fromCoordinates(1, 2), - Point.fromCoordinates(2, 2), - Point.fromCoordinates(2, 1)) - .addRing( - Point.fromCoordinates(3, 1), - Point.fromCoordinates(3, 2), - Point.fromCoordinates(4, 2), - Point.fromCoordinates(4, 1)) - .build(); - - public PolygonIT() { - super( - Lists.newArrayList(squareInMinDomain, complexPolygon, triangle), - Polygon.class, - sessionRule); - } - - @BeforeClass - public static void initialize() { - onTestContextInitialized(POLYGON_TYPE, sessionRule); - } - - /** - * Validates that an empty {@link Polygon} can be inserted and retrieved. - * - * @jira_ticket JAVA-1076 - * @test_category dse:graph - */ - @Test - public void should_insert_and_retrieve_empty_polygon() { - Polygon empty = Polygon.builder().build(); - UUID key = Uuids.random(); - sessionRule - .session() - .execute( - SimpleStatement.builder("INSERT INTO tbl (k, g) VALUES (?, ?)") - .addPositionalValues(key, empty) - .build()); - - ResultSet result = - sessionRule - .session() - .execute( - SimpleStatement.builder("SELECT g from tbl where k=?") - .addPositionalValues(key) - .build()); - Row row = result.iterator().next(); - assertThat(row.get("g", Polygon.class).getInteriorRings()).isEmpty(); - assertThat(row.get("g", Polygon.class).getExteriorRing()).isEmpty(); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/data/time/DateRangeIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/data/time/DateRangeIT.java deleted file mode 100644 index 9b2370e3376..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/data/time/DateRangeIT.java +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.data.time; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.config.DefaultDriverOption; -import com.datastax.oss.driver.api.core.cql.PreparedStatement; -import com.datastax.oss.driver.api.core.cql.Row; -import com.datastax.oss.driver.api.core.data.TupleValue; -import com.datastax.oss.driver.api.core.data.UdtValue; -import com.datastax.oss.driver.api.core.servererrors.InvalidQueryException; -import com.datastax.oss.driver.api.testinfra.ccm.CcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import com.datastax.oss.driver.api.testinfra.session.SessionUtils; -import com.datastax.oss.driver.categories.ParallelizableTests; -import com.google.common.collect.Sets; -import java.time.Duration; -import java.util.List; -import java.util.Map; -import java.util.Set; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.rules.RuleChain; -import org.junit.rules.TestName; -import org.junit.rules.TestRule; - -@Category({ParallelizableTests.class}) -@BackendRequirement(type = BackendType.DSE, minInclusive = "5.1") -public class DateRangeIT { - - private static CcmRule ccmRule = CcmRule.getInstance(); - - private static SessionRule sessionRule = - SessionRule.builder(ccmRule) - .withConfigLoader( - SessionUtils.configLoaderBuilder() - .withDuration(DefaultDriverOption.REQUEST_TIMEOUT, Duration.ofSeconds(30)) - .build()) - .build(); - - @ClassRule public static TestRule chain = RuleChain.outerRule(ccmRule).around(sessionRule); - - @Rule public TestName testName = new TestName(); - - /** - * Validates that data can be retrieved by primary key where its primary key is a 'DateRangeType' - * column, and that the data returned properly parses into the expected {@link DateRange}. - */ - @Test - public void should_use_date_range_as_primary_key() throws Exception { - CqlSession session = sessionRule.session(); - String tableName = testName.getMethodName(); - - session.execute( - String.format("CREATE TABLE %s (k 'DateRangeType' PRIMARY KEY, v int)", tableName)); - session.execute( - String.format("INSERT INTO %s (k, v) VALUES ('[2010-12-03 TO 2010-12-04]', 1)", tableName)); - session.execute( - String.format( - "INSERT INTO %s (k, v) VALUES ('[2015-12-03T10:15:30.001Z TO 2016-01-01T00:05:11.967Z]', 2)", - tableName)); - - List rows = session.execute("SELECT * FROM " + tableName).all(); - - assertThat(rows).hasSize(2); - assertThat(rows.get(0).get("k", DateRange.class)) - .isEqualTo(DateRange.parse("[2010-12-03 TO 2010-12-04]")); - assertThat(rows.get(1).get("k", DateRange.class)) - .isEqualTo(DateRange.parse("[2015-12-03T10:15:30.001Z TO 2016-01-01T00:05:11.967Z]")); - - rows = - session - .execute( - String.format( - "SELECT * FROM %s WHERE k = '[2015-12-03T10:15:30.001Z TO 2016-01-01T00:05:11.967]'", - tableName)) - .all(); - assertThat(rows.size()).isEqualTo(1); - assertThat(rows.get(0).getInt("v")).isEqualTo(2); - } - - /** - * Validates that a 'DateRangeType' column can take a variety of {@link DateRange} inputs: - * - *

    - *
  1. Upper bound unbounded - *
  2. Lower bound unbounded - *
  3. Unbounded - *
  4. Bounded - *
  5. null - *
  6. unset - *
- */ - @Test - public void should_store_date_range() throws Exception { - CqlSession session = sessionRule.session(); - String tableName = testName.getMethodName(); - - session.execute( - String.format("CREATE TABLE %s (k int PRIMARY KEY, v 'DateRangeType')", tableName)); - session.execute( - String.format( - "INSERT INTO %s (k, v) VALUES (1, '[2000-01-01T10:15:30.301Z TO *]')", tableName)); - session.execute( - String.format("INSERT INTO %s (k, v) VALUES (2, '[2000-02 TO 2000-03]')", tableName)); - session.execute(String.format("INSERT INTO %s (k, v) VALUES (3, '[* TO 2020]')", tableName)); - session.execute(String.format("INSERT INTO %s (k, v) VALUES (4, null)", tableName)); - session.execute(String.format("INSERT INTO %s (k) VALUES (5)", tableName)); - session.execute(String.format("INSERT INTO %s (k, v) VALUES (6, '*')", tableName)); - - List rows = session.execute("SELECT * FROM " + tableName).all(); - - assertThat(rows) - .extracting(input -> input.get("v", DateRange.class)) - .containsOnly( - DateRange.parse("[2000-01-01T10:15:30.301Z TO *]"), - DateRange.parse("[2000-02 TO 2000-03]"), - DateRange.parse("[* TO 2020]"), - null, - DateRange.parse("*")); - } - - /** - * Validates that if a provided {@link DateRange} for a 'DateRangeType' column has the bounds - * reversed (lower bound is later than upper bound), then an {@link InvalidQueryException} is - * thrown. - */ - @Test - public void should_disallow_invalid_order() throws Exception { - CqlSession session = sessionRule.session(); - String tableName = testName.getMethodName(); - - session.execute( - String.format("CREATE TABLE %s (k int PRIMARY KEY, v 'DateRangeType')", tableName)); - - assertThatThrownBy( - () -> - session.execute( - String.format( - "INSERT INTO %s (k, v) " - + "VALUES (1, '[2020-01-01T10:15:30.009Z TO 2010-01-01T00:05:11.031Z]')", - tableName))) - .isInstanceOf(InvalidQueryException.class) - .hasMessageContaining("Wrong order: 2020-01-01T10:15:30.009Z TO 2010-01-01T00:05:11.031Z") - .hasMessageContaining( - "Could not parse date range: [2020-01-01T10:15:30.009Z TO 2010-01-01T00:05:11.031Z]"); - } - - /** Validates that {@link DateRange} can be used in UDT and Tuple types. */ - @Test - public void should_allow_date_range_in_udt_and_tuple() throws Exception { - CqlSession session = sessionRule.session(); - String tableName = testName.getMethodName(); - - session.execute("CREATE TYPE IF NOT EXISTS test_udt (i int, range 'DateRangeType')"); - session.execute( - String.format( - "CREATE TABLE %s (k int PRIMARY KEY, u test_udt, uf frozen, " - + "t tuple<'DateRangeType', int>, tf frozen>)", - tableName)); - session.execute( - String.format( - "INSERT INTO %s (k, u, uf, t, tf) VALUES (" - + "1, " - + "{i: 10, range: '[2000-01-01T10:15:30.003Z TO 2020-01-01T10:15:30.001Z]'}, " - + "{i: 20, range: '[2000-01-01T10:15:30.003Z TO 2020-01-01T10:15:30.001Z]'}, " - + "('[2000-01-01T10:15:30.003Z TO 2020-01-01T10:15:30.001Z]', 30), " - + "('[2000-01-01T10:15:30.003Z TO 2020-01-01T10:15:30.001Z]', 40))", - tableName)); - - DateRange expected = DateRange.parse("[2000-01-01T10:15:30.003Z TO 2020-01-01T10:15:30.001Z]"); - - List rows = session.execute("SELECT * FROM " + tableName).all(); - assertThat(rows).hasSize(1); - - UdtValue u = rows.get(0).get("u", UdtValue.class); - DateRange dateRange = u.get("range", DateRange.class); - assertThat(dateRange).isEqualTo(expected); - assertThat(u.getInt("i")).isEqualTo(10); - - u = rows.get(0).get("uf", UdtValue.class); - dateRange = u.get("range", DateRange.class); - assertThat(dateRange).isEqualTo(expected); - assertThat(u.getInt("i")).isEqualTo(20); - - TupleValue t = rows.get(0).get("t", TupleValue.class); - dateRange = t.get(0, DateRange.class); - assertThat(dateRange).isEqualTo(expected); - assertThat(t.getInt(1)).isEqualTo(30); - - t = rows.get(0).get("tf", TupleValue.class); - dateRange = t.get(0, DateRange.class); - assertThat(dateRange).isEqualTo(expected); - assertThat(t.getInt(1)).isEqualTo(40); - } - - /** Validates that {@link DateRange} can be used in Collection types (Map, Set, List). */ - @Test - public void should_allow_date_range_in_collections() throws Exception { - CqlSession session = sessionRule.session(); - String tableName = testName.getMethodName(); - - session.execute( - String.format( - "CREATE TABLE %s (k int PRIMARY KEY, l list<'DateRangeType'>, s set<'DateRangeType'>, " - + "dr2i map<'DateRangeType', int>, i2dr map)", - tableName)); - session.execute( - String.format( - "INSERT INTO %s (k, l, s, i2dr, dr2i) VALUES (" - + "1, " - // l - + "['[2000-01-01T10:15:30.001Z TO 2020]', '[2010-01-01T10:15:30.001Z TO 2020]'," - + " '2001-01-02'], " - // s - + "{'[2000-01-01T10:15:30.001Z TO 2020]', '[2000-01-01T10:15:30.001Z TO 2020]', " - + "'[2010-01-01T10:15:30.001Z TO 2020]'}, " - // i2dr - + "{1: '[2000-01-01T10:15:30.001Z TO 2020]', " - + "2: '[2010-01-01T10:15:30.001Z TO 2020]'}, " - // dr2i - + "{'[2000-01-01T10:15:30.001Z TO 2020]': 1, " - + "'[2010-01-01T10:15:30.001Z TO 2020]': 2})", - tableName)); - - List rows = session.execute("SELECT * FROM " + tableName).all(); - assertThat(rows.size()).isEqualTo(1); - - List drList = rows.get(0).getList("l", DateRange.class); - assertThat(drList.size()).isEqualTo(3); - assertThat(drList.get(0)).isEqualTo(DateRange.parse("[2000-01-01T10:15:30.001Z TO 2020]")); - assertThat(drList.get(1)).isEqualTo(DateRange.parse("[2010-01-01T10:15:30.001Z TO 2020]")); - assertThat(drList.get(2)).isEqualTo(DateRange.parse("2001-01-02")); - - Set drSet = rows.get(0).getSet("s", DateRange.class); - assertThat(drSet.size()).isEqualTo(2); - assertThat(drSet) - .isEqualTo( - Sets.newHashSet( - DateRange.parse("[2000-01-01T10:15:30.001Z TO 2020]"), - DateRange.parse("[2010-01-01T10:15:30.001Z TO 2020]"))); - - Map dr2i = rows.get(0).getMap("dr2i", DateRange.class, Integer.class); - assertThat(dr2i.size()).isEqualTo(2); - assertThat((int) dr2i.get(DateRange.parse("[2000-01-01T10:15:30.001Z TO 2020]"))).isEqualTo(1); - assertThat((int) dr2i.get(DateRange.parse("[2010-01-01T10:15:30.001Z TO 2020]"))).isEqualTo(2); - - Map i2dr = rows.get(0).getMap("i2dr", Integer.class, DateRange.class); - assertThat(i2dr.size()).isEqualTo(2); - assertThat(i2dr.get(1)).isEqualTo(DateRange.parse("[2000-01-01T10:15:30.001Z TO 2020]")); - assertThat(i2dr.get(2)).isEqualTo(DateRange.parse("[2010-01-01T10:15:30.001Z TO 2020]")); - } - - /** - * Validates that a 'DateRangeType' column can take a {@link DateRange} inputs as a prepared - * statement parameter. - */ - @Test - public void should_bind_date_range_in_prepared_statement() throws Exception { - CqlSession session = sessionRule.session(); - String tableName = testName.getMethodName(); - - session.execute( - String.format("CREATE TABLE %s (k int PRIMARY KEY, v 'DateRangeType')", tableName)); - PreparedStatement statement = - session.prepare(String.format("INSERT INTO %s (k,v) VALUES(?,?)", tableName)); - - DateRange expected = DateRange.parse("[2007-12-03 TO 2007-12]"); - session.execute(statement.bind(1, expected)); - List rows = session.execute("SELECT * FROM " + tableName).all(); - assertThat(rows.size()).isEqualTo(1); - DateRange actual = rows.get(0).get("v", DateRange.class); - assertThat(actual).isEqualTo(expected); - assertThat(actual.getLowerBound().getPrecision()).isEqualTo(DateRangePrecision.DAY); - assertThat(actual.getUpperBound()) - .hasValueSatisfying( - upperBound -> - assertThat(upperBound.getPrecision()).isEqualTo(DateRangePrecision.MONTH)); - assertThat(actual.toString()).isEqualTo("[2007-12-03 TO 2007-12]"); - - expected = DateRange.parse("[* TO *]"); - session.execute(statement.bind(1, expected)); - rows = session.execute("SELECT * FROM " + tableName).all(); - assertThat(rows.size()).isEqualTo(1); - actual = rows.get(0).get("v", DateRange.class); - assertThat(actual).isEqualTo(expected); - assertThat(actual.getLowerBound().isUnbounded()).isTrue(); - assertThat(actual.isSingleBounded()).isFalse(); - assertThat(actual.getUpperBound()) - .hasValueSatisfying(upperBound -> assertThat(upperBound.isUnbounded()).isTrue()); - assertThat(actual.toString()).isEqualTo("[* TO *]"); - - expected = DateRange.parse("*"); - session.execute(statement.bind(1, expected)); - rows = session.execute("SELECT * FROM " + tableName).all(); - assertThat(rows.size()).isEqualTo(1); - actual = rows.get(0).get("v", DateRange.class); - assertThat(actual).isEqualTo(expected); - assertThat(actual.getLowerBound().isUnbounded()).isTrue(); - assertThat(actual.isSingleBounded()).isTrue(); - assertThat(actual.toString()).isEqualTo("*"); - } - - /** - * Validates that 'DateRangeType' columns are retrievable using SELECT JSON queries - * and that their value representations match their input. - */ - @Test - public void should_select_date_range_using_json() throws Exception { - CqlSession session = sessionRule.session(); - String tableName = testName.getMethodName(); - - session.execute( - String.format("CREATE TABLE %s (k int PRIMARY KEY, v 'DateRangeType')", tableName)); - PreparedStatement statement = - session.prepare(String.format("INSERT INTO %s (k,v) VALUES(?,?)", tableName)); - - DateRange expected = DateRange.parse("[2007-12-03 TO 2007-12]"); - session.execute(statement.bind(1, expected)); - List rows = session.execute("SELECT JSON * FROM " + tableName).all(); - assertThat(rows.get(0).getString(0)) - .isEqualTo("{\"k\": 1, \"v\": \"[2007-12-03 TO 2007-12]\"}"); - - expected = DateRange.parse("[* TO *]"); - session.execute(statement.bind(1, expected)); - rows = session.execute("SELECT JSON * FROM " + tableName).all(); - assertThat(rows.get(0).getString(0)).isEqualTo("{\"k\": 1, \"v\": \"[* TO *]\"}"); - - expected = DateRange.parse("*"); - session.execute(statement.bind(1, expected)); - rows = session.execute("SELECT JSON * FROM " + tableName).all(); - assertThat(rows.get(0).getString(0)).isEqualTo("{\"k\": 1, \"v\": \"*\"}"); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/ClassicGraphDataTypeITBase.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/ClassicGraphDataTypeITBase.java deleted file mode 100644 index d42b156a8be..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/ClassicGraphDataTypeITBase.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import static com.datastax.dse.driver.api.core.graph.TinkerGraphAssertions.assertThat; - -import com.datastax.dse.driver.api.core.data.geometry.LineString; -import com.datastax.dse.driver.api.core.data.geometry.Point; -import com.datastax.dse.driver.api.core.data.geometry.Polygon; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.Version; -import com.datastax.oss.driver.api.testinfra.ccm.CcmBridge; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import com.datastax.oss.driver.shaded.guava.common.base.Charsets; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableSet; -import com.datastax.oss.driver.shaded.guava.common.net.InetAddresses; -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.time.Instant; -import java.time.LocalDate; -import java.time.LocalTime; -import java.util.Objects; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.atomic.AtomicInteger; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.junit.AssumptionViolatedException; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(DataProviderRunner.class) -public abstract class ClassicGraphDataTypeITBase { - - private static final boolean IS_DSE50 = - CcmBridge.VERSION.compareTo(Objects.requireNonNull(Version.parse("5.1"))) < 0; - private static final Set TYPES_REQUIRING_DSE51 = - ImmutableSet.of("Date()", "Time()", "Point()", "Linestring()", "Polygon()"); - - private static final AtomicInteger SCHEMA_COUNTER = new AtomicInteger(); - - @DataProvider - public static Object[][] typeSamples() { - return new Object[][] { - // Types that DSE supports. - {"Boolean()", true}, - {"Boolean()", false}, - {"Smallint()", Short.MAX_VALUE}, - {"Smallint()", Short.MIN_VALUE}, - {"Smallint()", (short) 0}, - {"Smallint()", (short) 42}, - {"Int()", Integer.MAX_VALUE}, - {"Int()", Integer.MIN_VALUE}, - {"Int()", 0}, - {"Int()", 42}, - {"Bigint()", Long.MAX_VALUE}, - {"Bigint()", Long.MIN_VALUE}, - {"Bigint()", 0L}, - {"Double()", Double.MAX_VALUE}, - {"Double()", Double.MIN_VALUE}, - {"Double()", 0.0d}, - {"Double()", Math.PI}, - {"Float()", Float.MAX_VALUE}, - {"Float()", Float.MIN_VALUE}, - {"Float()", 0.0f}, - {"Text()", ""}, - {"Text()", "75"}, - {"Text()", "Lorem Ipsum"}, - // Inet, UUID, Date - {"Inet()", InetAddresses.forString("127.0.0.1")}, - {"Inet()", InetAddresses.forString("0:0:0:0:0:0:0:1")}, - {"Inet()", InetAddresses.forString("2001:db8:85a3:0:0:8a2e:370:7334")}, - {"Uuid()", UUID.randomUUID()}, - // Timestamps - {"Timestamp()", Instant.ofEpochMilli(123)}, - {"Timestamp()", Instant.ofEpochMilli(1488313909)}, - {"Duration()", java.time.Duration.parse("P2DT3H4M")}, - {"Date()", LocalDate.of(2016, 5, 12)}, - {"Time()", LocalTime.parse("18:30:41.554")}, - {"Time()", LocalTime.parse("18:30:41.554010034")}, - // Blob - {"Blob()", "Hello World!".getBytes(Charsets.UTF_8)}, - // BigDecimal/BigInteger - {"Decimal()", new BigDecimal("8675309.9998")}, - {"Varint()", new BigInteger("8675309")}, - // Geospatial types - {"Point().withBounds(-2, -2, 2, 2)", Point.fromCoordinates(0, 1)}, - {"Point().withBounds(-40, -40, 40, 40)", Point.fromCoordinates(-5, 20)}, - { - "Linestring().withGeoBounds()", - LineString.fromPoints( - Point.fromCoordinates(30, 10), - Point.fromCoordinates(10, 30), - Point.fromCoordinates(40, 40)) - }, - { - "Polygon().withGeoBounds()", - Polygon.builder() - .addRing( - Point.fromCoordinates(35, 10), - Point.fromCoordinates(45, 45), - Point.fromCoordinates(15, 40), - Point.fromCoordinates(10, 20), - Point.fromCoordinates(35, 10)) - .addRing( - Point.fromCoordinates(20, 30), - Point.fromCoordinates(35, 35), - Point.fromCoordinates(30, 20), - Point.fromCoordinates(20, 30)) - .build() - } - }; - } - - @UseDataProvider("typeSamples") - @Test - public void should_create_and_retrieve_vertex_property_with_correct_type( - String type, Object value) { - if (IS_DSE50 && requiresDse51(type)) { - throw new AssumptionViolatedException(type + " not supported in DSE " + CcmBridge.VERSION); - } - - int id = SCHEMA_COUNTER.getAndIncrement(); - - String vertexLabel = "vertex" + id; - String propertyName = "prop" + id; - GraphStatement addVertexLabelAndProperty = - ScriptGraphStatement.builder( - "schema.propertyKey(property)." - + type - + ".create()\n" - + "schema.vertexLabel(vertexLabel).properties(property).create()") - .setQueryParam("vertexLabel", vertexLabel) - .setQueryParam("property", propertyName) - .build(); - - session().execute(addVertexLabelAndProperty); - - Vertex v = insertVertexAndReturn(vertexLabel, propertyName, value); - - assertThat(v).hasProperty(propertyName, value); - } - - private boolean requiresDse51(String type) { - for (String prefix : TYPES_REQUIRING_DSE51) { - if (type.startsWith(prefix)) { - return true; - } - } - return false; - } - - public abstract Vertex insertVertexAndReturn( - String vertexLabel, String propertyName, Object value); - - /** - * Note that the {@link SessionRule} (and setupSchema method) must be redeclared in each subclass, - * since it depends on the CCM rule that can't be shared across serial tests. - */ - public abstract CqlSession session(); -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/ClassicGraphGeoSearchIndexIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/ClassicGraphGeoSearchIndexIT.java deleted file mode 100644 index 9878f1186e6..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/ClassicGraphGeoSearchIndexIT.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import com.datastax.oss.driver.shaded.guava.common.base.Joiner; -import com.datastax.oss.driver.shaded.guava.common.collect.Lists; -import java.util.ArrayList; -import java.util.Collection; -import org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "5.1", - description = "DSE 5.1 required for graph geo indexing") -public class ClassicGraphGeoSearchIndexIT extends GraphGeoSearchIndexITBase { - private static final CustomCcmRule CCM_RULE = - CustomCcmRule.builder().withDseWorkloads("graph", "solr").build(); - - private static final SessionRule SESSION_RULE = - GraphTestSupport.getClassicGraphSessionBuilder(CCM_RULE).build(); - - @ClassRule public static TestRule chain = RuleChain.outerRule(CCM_RULE).around(SESSION_RULE); - - private final GraphTraversalSource g = - AnonymousTraversalSource.traversal() - .withRemote(DseGraph.remoteConnectionBuilder(SESSION_RULE.session()).build()); - - @Override - protected boolean isGraphBinary() { - return false; - } - - @Override - protected GraphTraversalSource graphTraversalSource() { - return g; - } - - @BeforeClass - public static void setup() { - for (String setupQuery : geoIndices()) { - SESSION_RULE.session().execute(ScriptGraphStatement.newInstance(setupQuery)); - } - - CCM_RULE.getCcmBridge().reloadCore(1, SESSION_RULE.getGraphName(), "user_p", true); - } - - /** - * A schema representing an address book with search enabled on name, description, and - * coordinates. - */ - public static Collection geoIndices() { - Object[][] providerIndexTypes = indexTypes(); - String[] indexTypes = new String[providerIndexTypes.length]; - for (int i = 0; i < providerIndexTypes.length; i++) { - indexTypes[i] = (String) providerIndexTypes[i][0]; - } - - StringBuilder schema = new StringBuilder("schema.propertyKey('full_name').Text().create()\n"); - StringBuilder propertyKeys = new StringBuilder(); - StringBuilder vertexLabel = new StringBuilder("schema.vertexLabel('user').properties("); - StringBuilder indices = new StringBuilder(); - StringBuilder vertex0 = - new StringBuilder("g.addV('user').property('full_name', 'Paul Thomas Joe')"); - StringBuilder vertex1 = - new StringBuilder("g.addV('user').property('full_name', 'George Bill Steve')"); - String vertex2 = "g.addV('user').property('full_name', 'James Paul Joe')"; - StringBuilder vertex3 = new StringBuilder("g.addV('user').property('full_name', 'Jill Alice')"); - - ArrayList propertyNames = new ArrayList<>(); - propertyNames.add("'full_name'"); - - for (String indexType : indexTypes) { - - propertyKeys.append( - String.format( - "schema.propertyKey('pointPropWithBounds_%s')." - + "Point().withBounds(0.000000, 0.000000, 100.000000, 100.000000).create()\n", - indexType)); - - propertyKeys.append( - String.format( - "schema.propertyKey('pointPropWithGeoBounds_%s').Point().withGeoBounds().create()\n", - indexType)); - - propertyNames.add("'pointPropWithBounds_" + indexType + "'"); - propertyNames.add("'pointPropWithGeoBounds_" + indexType + "'"); - - if (indexType.equals("search")) { - - indices.append( - String.format( - "schema.vertexLabel('user').index('search').search().by('pointPropWithBounds_%s').withError(0.00001, 0.0).by('pointPropWithGeoBounds_%s').withError(0.00001, 0.0).add()\n", - indexType, indexType)); - } else { - - indices.append( - String.format( - "schema.vertexLabel('user').index('by_pointPropWithBounds_%s').%s().by('pointPropWithBounds_%s').add()\n", - indexType, indexType, indexType)); - - indices.append( - String.format( - "schema.vertexLabel('user').index('by_pointPropWithGeoBounds_%s').%s().by('pointPropWithGeoBounds_%s').add()\n", - indexType, indexType, indexType)); - } - - vertex0.append( - String.format( - ".property('pointPropWithBounds_%s', 'POINT(40.0001 40)').property('pointPropWithGeoBounds_%s', 'POINT(40.0001 40)')", - indexType, indexType)); - vertex1.append( - String.format( - ".property('pointPropWithBounds_%s', 'POINT(40 40)').property('pointPropWithGeoBounds_%s', 'POINT(40 40)')", - indexType, indexType)); - vertex3.append( - String.format( - ".property('pointPropWithBounds_%s', 'POINT(30 30)').property('pointPropWithGeoBounds_%s', 'POINT(30 30)')", - indexType, indexType)); - } - - vertexLabel.append(Joiner.on(", ").join(propertyNames)); - vertexLabel.append(").create()\n"); - - schema.append(propertyKeys).append(vertexLabel).append(indices); - - return Lists.newArrayList( - SampleGraphScripts.MAKE_STRICT, - schema.toString(), - vertex0.toString(), - vertex1.toString(), - vertex2, - vertex3.toString()); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/ClassicGraphTextSearchIndexIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/ClassicGraphTextSearchIndexIT.java deleted file mode 100644 index 13d503d6b25..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/ClassicGraphTextSearchIndexIT.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import com.datastax.oss.driver.shaded.guava.common.base.Joiner; -import com.datastax.oss.driver.shaded.guava.common.collect.Lists; -import java.util.ArrayList; -import java.util.Collection; -import org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "5.1", - description = "DSE 5.1 required for graph geo indexing") -public class ClassicGraphTextSearchIndexIT extends GraphTextSearchIndexITBase { - private static final CustomCcmRule CCM_RULE = - CustomCcmRule.builder().withDseWorkloads("graph", "solr").build(); - - private static final SessionRule SESSION_RULE = - GraphTestSupport.getClassicGraphSessionBuilder(CCM_RULE).build(); - - @ClassRule public static TestRule chain = RuleChain.outerRule(CCM_RULE).around(SESSION_RULE); - - private final GraphTraversalSource g = - AnonymousTraversalSource.traversal() - .withRemote(DseGraph.remoteConnectionBuilder(SESSION_RULE.session()).build()); - - /** - * A schema representing an address book with 3 properties (full_name_*, description_*, alias_*) - * created for each type of index (search, secondary, materialized). - */ - public static Collection textIndices() { - Object[][] providerIndexTypes = indexTypes(); - String[] indexTypes = new String[providerIndexTypes.length]; - for (int i = 0; i < providerIndexTypes.length; i++) { - indexTypes[i] = (String) providerIndexTypes[i][0]; - } - - StringBuilder schema = new StringBuilder(); - StringBuilder propertyKeys = new StringBuilder(); - StringBuilder vertexLabel = new StringBuilder("schema.vertexLabel('user').properties("); - StringBuilder indices = new StringBuilder(); - StringBuilder vertex0 = new StringBuilder("g.addV('user')"); - StringBuilder vertex1 = new StringBuilder("g.addV('user')"); - StringBuilder vertex2 = new StringBuilder("g.addV('user')"); - StringBuilder vertex3 = new StringBuilder("g.addV('user')"); - - ArrayList propertyNames = new ArrayList<>(); - for (String indexType : indexTypes) { - propertyKeys.append( - String.format( - "schema.propertyKey('full_name_%s').Text().create()\n" - + "schema.propertyKey('description_%s').Text().create()\n" - + "schema.propertyKey('alias_%s').Text().create()\n", - indexType, indexType, indexType)); - - propertyNames.add("'full_name_" + indexType + "'"); - propertyNames.add("'description_" + indexType + "'"); - propertyNames.add("'alias_" + indexType + "'"); - - if (indexType.equals("search")) { - indices.append( - "schema.vertexLabel('user').index('search').search().by('full_name_search').asString().by('description_search').asText().by('alias_search').asString().add()\n"); - } else { - indices.append( - String.format( - "schema.vertexLabel('user').index('by_full_name_%s').%s().by('full_name_%s').add()\n", - indexType, indexType, indexType)); - indices.append( - String.format( - "schema.vertexLabel('user').index('by_description_%s').%s().by('description_%s').add()\n", - indexType, indexType, indexType)); - indices.append( - String.format( - "schema.vertexLabel('user').index('by_alias_name_%s').%s().by('alias_%s').add()\n", - indexType, indexType, indexType)); - } - - vertex0.append( - String.format( - ".property('full_name_%s', 'Paul Thomas Joe').property('description_%s', 'Lives by the hospital').property('alias_%s', 'mario')", - indexType, indexType, indexType)); - vertex1.append( - String.format( - ".property('full_name_%s', 'George Bill Steve').property('description_%s', 'A cold dude').property('alias_%s', 'wario')", - indexType, indexType, indexType)); - vertex2.append( - String.format( - ".property('full_name_%s', 'James Paul Joe').property('description_%s', 'Likes to hang out').property('alias_%s', 'bowser')", - indexType, indexType, indexType)); - vertex3.append( - String.format( - ".property('full_name_%s', 'Jill Alice').property('description_%s', 'Enjoys a very nice cold coca cola').property('alias_%s', 'peach')", - indexType, indexType, indexType)); - } - - vertexLabel.append(Joiner.on(", ").join(propertyNames)); - vertexLabel.append(").create()\n"); - - schema.append(propertyKeys).append(vertexLabel).append(indices); - - return Lists.newArrayList( - SampleGraphScripts.MAKE_STRICT, - schema.toString(), - vertex0.toString(), - vertex1.toString(), - vertex2.toString(), - vertex3.toString()); - } - - @BeforeClass - public static void setup() { - for (String setupQuery : textIndices()) { - SESSION_RULE.session().execute(ScriptGraphStatement.newInstance(setupQuery)); - } - - CCM_RULE.getCcmBridge().reloadCore(1, SESSION_RULE.getGraphName(), "user_p", true); - } - - @Override - protected boolean isGraphBinary() { - return false; - } - - @Override - protected GraphTraversalSource graphTraversalSource() { - return g; - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/CoreGraphDataTypeITBase.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/CoreGraphDataTypeITBase.java deleted file mode 100644 index 7fe31a059d7..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/CoreGraphDataTypeITBase.java +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import static com.datastax.oss.driver.api.core.type.DataTypes.BIGINT; -import static com.datastax.oss.driver.api.core.type.DataTypes.INT; -import static com.datastax.oss.driver.api.core.type.DataTypes.TEXT; -import static com.datastax.oss.driver.api.core.type.DataTypes.listOf; -import static com.datastax.oss.driver.api.core.type.DataTypes.tupleOf; -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.dse.driver.api.core.data.geometry.LineString; -import com.datastax.dse.driver.api.core.data.geometry.Point; -import com.datastax.dse.driver.api.core.data.geometry.Polygon; -import com.datastax.dse.driver.api.core.graph.predicates.Geo; -import com.datastax.dse.driver.api.core.type.DseDataTypes; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.data.CqlDuration; -import com.datastax.oss.driver.api.core.data.UdtValue; -import com.datastax.oss.driver.api.core.type.TupleType; -import com.datastax.oss.driver.api.core.type.UserDefinedType; -import com.datastax.oss.driver.api.core.uuid.Uuids; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Sets; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.nio.ByteBuffer; -import java.time.Instant; -import java.time.LocalDate; -import java.time.LocalTime; -import java.time.ZoneId; -import java.time.temporal.ChronoUnit; -import java.util.Arrays; -import java.util.Map; -import org.junit.Test; - -public abstract class CoreGraphDataTypeITBase { - - protected abstract CqlSession session(); - - protected abstract String graphName(); - - @Test - public void should_create_and_retrieve_correct_data_with_types() { - CqlSession session = session(); - - // use CQL to create type for now because DSP-17567 is not in yet, so this is more stable - session.execute( - String.format( - "CREATE TYPE %s.udt_graphbinary(simple text, complex tuple, missing text)", - graphName())); - - session.execute( - String.format( - "CREATE TYPE %s.udt_graphbinarygeo(point 'PointType', line 'LineStringType', poly 'PolygonType')", - graphName())); - - ImmutableMap.Builder properties = - ImmutableMap.builder() - .put("Ascii", "test") - .put("Bigint", 5L) - .put("Boolean", true) - .put("Date", LocalDate.of(2007, 7, 7)) - .put("Decimal", BigDecimal.valueOf(2.3)) - .put("Double", 4.5d) - .put("Float", 4.8f) - .put("Int", 45) - .put("Smallint", (short) 1) - .put("Text", "test") - .put("Time", LocalTime.now(ZoneId.systemDefault())) - .put("Timeuuid", Uuids.timeBased()) - .put("Timestamp", Instant.now().truncatedTo(ChronoUnit.MILLIS)) - .put("Uuid", java.util.UUID.randomUUID()) - .put("Varint", BigInteger.valueOf(3234)) - .put("Blob", ByteBuffer.wrap(new byte[] {1, 2, 3})) - .put("Tinyint", (byte) 38) - .put("listOf(Int)", Arrays.asList(2, 3, 4)) - .put("setOf(Int)", Sets.newHashSet(2, 3, 4)) - .put("mapOf(Int, Text)", ImmutableMap.of(2, "two", 4, "four")) - .put("Duration", CqlDuration.newInstance(1, 2, 3)) - .put("LineString", Geo.lineString(1, 2, 3, 4, 5, 6)) - .put("Point", Geo.point(3, 4)) - .put("Polygon", Geo.polygon(Geo.point(3, 4), Geo.point(5, 4), Geo.point(6, 6))) - .put("tupleOf(Int, Text)", tupleOf(INT, TEXT).newValue(5, "Bar")) - .put( - "typeOf('udt_graphbinary')", - session - .getMetadata() - .getKeyspace(graphName()) - .flatMap(keyspace -> keyspace.getUserDefinedType("udt_graphbinary")) - .orElseThrow(IllegalStateException::new) - .newValue( - "some text", tupleOf(INT, TEXT).newValue(5, "Bar"), "some missing text")) - .put( - "typeOf('udt_graphbinarygeo')", - session - .getMetadata() - .getKeyspace(graphName()) - .flatMap( - keyspaceMetadata -> - keyspaceMetadata.getUserDefinedType("udt_graphbinarygeo")) - .orElseThrow(IllegalStateException::new) - .newValue( - Point.fromCoordinates(3.3, 4.4), - LineString.fromPoints( - Point.fromCoordinates(1, 1), - Point.fromCoordinates(2, 2), - Point.fromCoordinates(3, 3)), - Polygon.fromPoints( - Point.fromCoordinates(3, 4), - Point.fromCoordinates(5, 4), - Point.fromCoordinates(6, 6)))); - - TupleType tuple = tupleOf(DseDataTypes.POINT, DseDataTypes.LINE_STRING, DseDataTypes.POLYGON); - tuple.attach(session.getContext()); - - properties.put( - "tupleOf(Point, LineString, Polygon)", - tuple.newValue( - Point.fromCoordinates(3.3, 4.4), - LineString.fromPoints( - Point.fromCoordinates(1, 1), - Point.fromCoordinates(2, 2), - Point.fromCoordinates(3, 3)), - Polygon.fromPoints( - Point.fromCoordinates(3, 4), - Point.fromCoordinates(5, 4), - Point.fromCoordinates(6, 6)))); - - int vertexID = 1; - String vertexLabel = "graphBinaryAllTypes"; - - runTest(properties.build(), vertexLabel, vertexID); - } - - @Test - public void should_insert_and_retrieve_nested_UDTS_and_tuples() { - CqlSession session = session(); - - // use CQL to create type for now because DSP-17567 is not in yet, so this is more stable - session.execute(String.format("CREATE TYPE %s.udt1(a int, b text)", graphName())); - - session.execute( - String.format( - "CREATE TYPE %s.udt2(" - + "a int" - + ", b text" - + ", c frozen" - + ", mylist list" - + ", mytuple_withlist tuple>>>" - + ")", - graphName())); - - session.execute( - String.format( - "CREATE TYPE %s.udt3(" - + "a list" - + ", b set" - + ", c map" - + ", d list>>" - + ", e set>>" - + ", f list>>" - + ")", - graphName())); - - UserDefinedType udt1 = - session - .getMetadata() - .getKeyspace(graphName()) - .flatMap(keyspace -> keyspace.getUserDefinedType("udt1")) - .orElseThrow(IllegalStateException::new); - UdtValue udtValue1 = udt1.newValue(1, "2"); - - UserDefinedType udt2 = - session - .getMetadata() - .getKeyspace(graphName()) - .flatMap(keyspace -> keyspace.getUserDefinedType("udt2")) - .orElseThrow(IllegalStateException::new); - TupleType secondNested = tupleOf(BIGINT, listOf(BIGINT)); - TupleType firstNested = tupleOf(TEXT, secondNested); - UdtValue udtValue2 = - udt2.newValue( - 1, - "2", - udt1.newValue(3, "4"), - ImmutableList.of(5L), - firstNested.newValue("6", secondNested.newValue(7L, ImmutableList.of(8L)))); - - UserDefinedType udt3 = - session - .getMetadata() - .getKeyspace(graphName()) - .flatMap(keyspace -> keyspace.getUserDefinedType("udt3")) - .orElseThrow(IllegalStateException::new); - UdtValue udtValue3 = - udt3.newValue( - ImmutableList.of(1), - ImmutableSet.of(2.1f), - ImmutableMap.of("3", 4L), - ImmutableList.of(ImmutableList.of(5.1d, 6.1d), ImmutableList.of(7.1d)), - ImmutableSet.of(ImmutableSet.of(8.1f), ImmutableSet.of(9.1f)), - ImmutableList.of(tupleOf(INT, TEXT).newValue(10, "11"))); - - Map properties = - ImmutableMap.builder() - .put("frozen(typeOf('udt1'))", udtValue1) - .put("frozen(typeOf('udt2'))", udtValue2) - .put("frozen(typeOf('udt3'))", udtValue3) - .build(); - - int vertexID = 1; - String vertexLabel = "graphBinaryNestedTypes"; - - runTest(properties, vertexLabel, vertexID); - } - - private void runTest(Map properties, String vertexLabel, int vertexID) { - // setup schema - session().execute(createVertexLabelStatement(properties, vertexLabel)); - - // execute insert query and read query - Map results = insertVertexThenReadProperties(properties, vertexID, vertexLabel); - - // test valid properties are returned - properties.forEach((k, v) -> assertThat(results.get(formatPropertyName(k))).isEqualTo(v)); - } - - private static GraphStatement createVertexLabelStatement( - Map properties, String vertexLabel) { - StringBuilder ddl = - new StringBuilder("schema.vertexLabel(vertexLabel).ifNotExists().partitionBy('id', Int)"); - - for (Map.Entry entry : properties.entrySet()) { - String typeDefinition = entry.getKey(); - String propName = formatPropertyName(typeDefinition); - - ddl.append(String.format(".property('%s', %s)", propName, typeDefinition)); - } - ddl.append(".create()"); - - return ScriptGraphStatement.newInstance(ddl.toString()) - .setQueryParam("vertexLabel", vertexLabel); - } - - protected abstract Map insertVertexThenReadProperties( - Map properties, int vertexID, String vertexLabel); - - protected static String formatPropertyName(String originalName) { - return String.format( - "prop%s", - originalName.replace("(", "").replace(")", "").replace(", ", "").replace("'", "")); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/CoreGraphGeoSearchIndexIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/CoreGraphGeoSearchIndexIT.java deleted file mode 100644 index 12db8820117..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/CoreGraphGeoSearchIndexIT.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import com.datastax.oss.driver.shaded.guava.common.collect.Lists; -import java.util.Collection; -import org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "6.8.0", - description = "DSE 6.8.0 required for Core graph support") -public class CoreGraphGeoSearchIndexIT extends GraphGeoSearchIndexITBase { - - private static final CustomCcmRule CCM_RULE = - CustomCcmRule.builder().withDseWorkloads("graph", "solr").build(); - - private static final SessionRule SESSION_RULE = - GraphTestSupport.getCoreGraphSessionBuilder(CCM_RULE).build(); - - @ClassRule public static TestRule chain = RuleChain.outerRule(CCM_RULE).around(SESSION_RULE); - private final GraphTraversalSource g = - AnonymousTraversalSource.traversal() - .withRemote(DseGraph.remoteConnectionBuilder(SESSION_RULE.session()).build()) - .with("allow-filtering"); - - @Override - protected boolean isGraphBinary() { - return true; - } - - @Override - protected GraphTraversalSource graphTraversalSource() { - return g; - } - - @BeforeClass - public static void setup() { - for (String setupQuery : geoIndices()) { - SESSION_RULE.session().execute(ScriptGraphStatement.newInstance(setupQuery)); - } - - CCM_RULE.getCcmBridge().reloadCore(1, SESSION_RULE.getGraphName(), "user", true); - } - - /** - * A schema representing an address book with search enabled on name, description, and - * coordinates. - */ - public static Collection geoIndices() { - Object[][] providerIndexTypes = indexTypes(); - String[] indexTypes = new String[providerIndexTypes.length]; - for (int i = 0; i < providerIndexTypes.length; i++) { - indexTypes[i] = (String) providerIndexTypes[i][0]; - } - - StringBuilder schema = - new StringBuilder("schema.vertexLabel('user').partitionBy('full_name', Text)"); - StringBuilder propertyKeys = new StringBuilder(); - StringBuilder indices = new StringBuilder(); - StringBuilder vertex0 = - new StringBuilder("g.addV('user').property('full_name', 'Paul Thomas Joe')"); - StringBuilder vertex1 = - new StringBuilder("g.addV('user').property('full_name', 'George Bill Steve')"); - String vertex2 = "g.addV('user').property('full_name', 'James Paul Joe')"; - StringBuilder vertex3 = new StringBuilder("g.addV('user').property('full_name', 'Jill Alice')"); - - for (String indexType : indexTypes) { - propertyKeys.append(String.format(".property('pointPropWithBounds_%s', Point)\n", indexType)); - - propertyKeys.append( - String.format(".property('pointPropWithGeoBounds_%s', Point)\n", indexType)); - - if (indexType.equals("search")) { - indices.append( - String.format( - "schema.vertexLabel('user').searchIndex().by('pointPropWithBounds_%s').by('pointPropWithGeoBounds_%s').create()\n", - indexType, indexType)); - - } else { - throw new UnsupportedOperationException("IndexType other than search is not supported."); - } - - vertex0.append( - String.format( - ".property('pointPropWithBounds_%s', point(40.0001,40)).property('pointPropWithGeoBounds_%s', point(40.0001,40))", - indexType, indexType)); - vertex1.append( - String.format( - ".property('pointPropWithBounds_%s', point(40,40)).property('pointPropWithGeoBounds_%s', point(40,40))", - indexType, indexType)); - vertex3.append( - String.format( - ".property('pointPropWithBounds_%s', point(30,30)).property('pointPropWithGeoBounds_%s', point(30,30))", - indexType, indexType)); - } - - schema.append(propertyKeys).append(".create();\n").append(indices); - - return Lists.newArrayList( - schema.toString(), vertex0.toString(), vertex1.toString(), vertex2, vertex3.toString()); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/CoreGraphTextSearchIndexIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/CoreGraphTextSearchIndexIT.java deleted file mode 100644 index 5545c3c00ac..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/CoreGraphTextSearchIndexIT.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import com.datastax.oss.driver.shaded.guava.common.collect.Lists; -import java.util.Collection; -import org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "6.8.0", - description = "DSE 6.8.0 required for Core graph support") -public class CoreGraphTextSearchIndexIT extends GraphTextSearchIndexITBase { - - private static final CustomCcmRule CCM_RULE = - CustomCcmRule.builder().withDseWorkloads("graph", "solr").build(); - - private static final SessionRule SESSION_RULE = - GraphTestSupport.getCoreGraphSessionBuilder(CCM_RULE).build(); - - @ClassRule public static TestRule chain = RuleChain.outerRule(CCM_RULE).around(SESSION_RULE); - - private final GraphTraversalSource g = - AnonymousTraversalSource.traversal() - .withRemote(DseGraph.remoteConnectionBuilder(SESSION_RULE.session()).build()) - .with("allow-filtering"); - - @Override - protected boolean isGraphBinary() { - return true; - } - - @Override - protected GraphTraversalSource graphTraversalSource() { - return g; - } - - /** - * A schema representing an address book with 3 properties (full_name_*, description_*, alias_*) - * created for each type of index (search, secondary, materialized). - */ - public static Collection textIndices() { - Object[][] providerIndexTypes = indexTypes(); - String[] indexTypes = new String[providerIndexTypes.length]; - for (int i = 0; i < providerIndexTypes.length; i++) { - indexTypes[i] = (String) providerIndexTypes[i][0]; - } - - StringBuilder schema = new StringBuilder("schema.vertexLabel('user')"); - StringBuilder propertyKeys = new StringBuilder(); - StringBuilder indices = new StringBuilder(); - StringBuilder vertex0 = new StringBuilder("g.addV('user')"); - StringBuilder vertex1 = new StringBuilder("g.addV('user')"); - StringBuilder vertex2 = new StringBuilder("g.addV('user')"); - StringBuilder vertex3 = new StringBuilder("g.addV('user')"); - - for (String indexType : indexTypes) { - propertyKeys.append( - String.format( - ".partitionBy('full_name_%s', Text)" - + ".property('description_%s', Text)" - + ".property('alias_%s', Text)\n", - indexType, indexType, indexType)); - - if (indexType.equals("search")) { - indices.append( - "schema.vertexLabel('user').searchIndex().by('full_name_search').asString().by('description_search').asText().by('alias_search').asString().create()\n"); - } else { - throw new UnsupportedOperationException("IndexType other than search is not supported."); - } - - vertex0.append( - String.format( - ".property('full_name_%s', 'Paul Thomas Joe').property('description_%s', 'Lives by the hospital').property('alias_%s', 'mario')", - indexType, indexType, indexType)); - vertex1.append( - String.format( - ".property('full_name_%s', 'George Bill Steve').property('description_%s', 'A cold dude').property('alias_%s', 'wario')", - indexType, indexType, indexType)); - vertex2.append( - String.format( - ".property('full_name_%s', 'James Paul Joe').property('description_%s', 'Likes to hang out').property('alias_%s', 'bowser')", - indexType, indexType, indexType)); - vertex3.append( - String.format( - ".property('full_name_%s', 'Jill Alice').property('description_%s', 'Enjoys a very nice cold coca cola').property('alias_%s', 'peach')", - indexType, indexType, indexType)); - } - - schema.append(propertyKeys).append(".create();\n").append(indices); - - return Lists.newArrayList( - schema.toString(), - vertex0.toString(), - vertex1.toString(), - vertex2.toString(), - vertex3.toString()); - } - - @BeforeClass - public static void setup() { - for (String setupQuery : textIndices()) { - SESSION_RULE.session().execute(ScriptGraphStatement.newInstance(setupQuery)); - } - - CCM_RULE.getCcmBridge().reloadCore(1, SESSION_RULE.getGraphName(), "user", true); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/CqlCollectionIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/CqlCollectionIT.java deleted file mode 100644 index 8bc497c37db..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/CqlCollectionIT.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import static com.datastax.dse.driver.api.core.graph.predicates.CqlCollection.contains; -import static com.datastax.dse.driver.api.core.graph.predicates.CqlCollection.containsKey; -import static com.datastax.dse.driver.api.core.graph.predicates.CqlCollection.entryEq; -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.dse.driver.api.core.graph.predicates.CqlCollection; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.CqlSessionRuleBuilder; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; -import org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "6.8", - description = "DSE 6.8.0 required for collection predicates support") -public class CqlCollectionIT { - - private static final CustomCcmRule CCM_RULE = - CustomCcmRule.builder().withDseWorkloads("graph").build(); - - private static final SessionRule SESSION_RULE = - new CqlSessionRuleBuilder(CCM_RULE) - .withCreateGraph() - .withCoreEngine() - .withGraphProtocol("graph-binary-1.0") - .build(); - - @ClassRule public static TestRule CHAIN = RuleChain.outerRule(CCM_RULE).around(SESSION_RULE); - - private final GraphTraversalSource g = - AnonymousTraversalSource.traversal() - .withRemote(DseGraph.remoteConnectionBuilder(SESSION_RULE.session()).build()); - - @BeforeClass - public static void setup() { - for (String setupQuery : createSchema()) { - SESSION_RULE.session().execute(ScriptGraphStatement.newInstance(setupQuery)); - } - } - - private static Collection createSchema() { - return ImmutableList.of( - "schema.vertexLabel('software').ifNotExists().partitionBy('name', Varchar)" - + ".property('myList', listOf(Varchar))" - + ".property('mySet', setOf(Varchar))" - + ".property('myMapKeys', mapOf(Varchar, Int))" - + ".property('myMapValues', mapOf(Int, Varchar))" - + ".property('myMapEntries', mapOf(Int, Varchar))" - + ".property('myFrozenList', frozen(listOf(Varchar)))" - + ".property('myFrozenSet', frozen(setOf(Float)))" - + ".property('myFrozenMap', frozen(mapOf(Int, Varchar)))" - + ".create()", - "schema.vertexLabel('software').secondaryIndex('by_myList').ifNotExists().by('myList').create();" - + "schema.vertexLabel('software').secondaryIndex('by_mySet').ifNotExists().by('mySet').create();" - + "schema.vertexLabel('software').secondaryIndex('by_myMapKeys').ifNotExists().by('myMapKeys').indexKeys().create();" - + "schema.vertexLabel('software').secondaryIndex('by_myMapValues').ifNotExists().by('myMapValues').indexValues().create();" - + "schema.vertexLabel('software').secondaryIndex('by_myMapEntries').ifNotExists().by('myMapEntries').indexEntries().create();" - + "schema.vertexLabel('software').secondaryIndex('by_myFrozenList').ifNotExists().by('myFrozenList').indexFull().create();" - + "schema.vertexLabel('software').secondaryIndex('by_myFrozenSet').ifNotExists().by('myFrozenSet').indexFull().create();" - + "schema.vertexLabel('software').secondaryIndex('by_myFrozenMap').ifNotExists().by('myFrozenMap').indexFull().create()"); - } - - @Test - public void should_apply_contains_predicate_to_non_frozen_list() { - CqlSession session = SESSION_RULE.session(); - - List myList1 = com.google.common.collect.ImmutableList.of("apple", "banana"); - List myList2 = com.google.common.collect.ImmutableList.of("cranberry", "orange"); - - session.execute( - FluentGraphStatement.newInstance( - DseGraph.g - .addV("software") - .property("name", "dse list 1") - .property("myList", myList1))); - session.execute( - FluentGraphStatement.newInstance( - DseGraph.g - .addV("software") - .property("name", "dse list 2") - .property("myList", myList2))); - - assertThat(g.V().has("software", "myList", contains("apple")).values("myList").toList()) - .hasSize(1) - .contains(myList1) - .doesNotContain(myList2); - assertThat(g.V().has("software", "myList", contains("strawberry")).toList()).isEmpty(); - } - - @Test - public void should_apply_contains_predicate_to_non_frozen_set() { - CqlSession session = SESSION_RULE.session(); - - Set mySet1 = ImmutableSet.of("apple", "banana"); - Set mySet2 = ImmutableSet.of("cranberry", "orange"); - - session.execute( - FluentGraphStatement.newInstance( - DseGraph.g.addV("software").property("name", "dse set 1").property("mySet", mySet1))); - session.execute( - FluentGraphStatement.newInstance( - DseGraph.g.addV("software").property("name", "dse set 2").property("mySet", mySet2))); - - assertThat(g.V().has("software", "mySet", contains("apple")).values("mySet").toList()) - .hasSize(1) - .contains(mySet1) - .doesNotContain(mySet2); - assertThat(g.V().has("software", "mySet", contains("strawberry")).toList()).isEmpty(); - } - - @Test - public void should_apply_containsKey_predicate_to_non_frozen_map() { - CqlSession session = SESSION_RULE.session(); - - Map myMap1 = ImmutableMap.builder().put("id1", 1).build(); - Map myMap2 = ImmutableMap.builder().put("id2", 2).build(); - - session.execute( - FluentGraphStatement.newInstance( - DseGraph.g - .addV("software") - .property("name", "dse map containsKey 1") - .property("myMapKeys", myMap1))); - session.execute( - FluentGraphStatement.newInstance( - DseGraph.g - .addV("software") - .property("name", "dse map containsKey 2") - .property("myMapKeys", myMap2))); - - assertThat(g.V().has("software", "myMapKeys", containsKey("id1")).values("myMapKeys").toList()) - .hasSize(1) - .contains(myMap1) - .doesNotContain(myMap2); - assertThat(g.V().has("software", "myMapKeys", containsKey("id3")).toList()).isEmpty(); - } - - @Test - public void should_apply_containsValue_predicate_to_non_frozen_map() { - CqlSession session = SESSION_RULE.session(); - - Map myMap1 = ImmutableMap.builder().put(11, "abc").build(); - Map myMap2 = ImmutableMap.builder().put(22, "def").build(); - - session.execute( - FluentGraphStatement.newInstance( - DseGraph.g - .addV("software") - .property("name", "dse map containsValue 1") - .property("myMapValues", myMap1))); - session.execute( - FluentGraphStatement.newInstance( - DseGraph.g - .addV("software") - .property("name", "dse map containsValue 2") - .property("myMapValues", myMap2))); - assertThat( - g.V() - .has("software", "myMapValues", CqlCollection.containsValue("abc")) - .values("myMapValues") - .toList()) - .hasSize(1) - .contains(myMap1) - .doesNotContain(myMap2); - assertThat(g.V().has("software", "myMapValues", CqlCollection.containsValue("xyz")).toList()) - .isEmpty(); - } - - @Test - public void should_apply_entryEq_predicate_to_non_frozen_map() { - CqlSession session = SESSION_RULE.session(); - - Map myMap1 = ImmutableMap.builder().put(11, "abc").build(); - Map myMap2 = ImmutableMap.builder().put(22, "def").build(); - - session.execute( - FluentGraphStatement.newInstance( - DseGraph.g - .addV("software") - .property("name", "dse map entryEq 1") - .property("myMapEntries", myMap1))); - session.execute( - FluentGraphStatement.newInstance( - DseGraph.g - .addV("software") - .property("name", "dse map entryEq 2") - .property("myMapEntries", myMap2))); - assertThat( - g.V() - .has("software", "myMapEntries", entryEq(11, "abc")) - .values("myMapEntries") - .toList()) - .hasSize(1) - .contains(myMap1) - .doesNotContain(myMap2); - assertThat(g.V().has("software", "myMapEntries", entryEq(11, "xyz")).toList()).isEmpty(); - assertThat(g.V().has("software", "myMapEntries", entryEq(33, "abc")).toList()).isEmpty(); - assertThat(g.V().has("software", "myMapEntries", entryEq(33, "xyz")).toList()).isEmpty(); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/GraphAuthenticationIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/GraphAuthenticationIT.java deleted file mode 100644 index de1c23fd661..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/GraphAuthenticationIT.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import static com.datastax.dse.driver.api.core.graph.TinkerGraphAssertions.assertThat; - -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.Version; -import com.datastax.oss.driver.api.core.config.DefaultDriverOption; -import com.datastax.oss.driver.api.core.config.DriverConfigLoader; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionUtils; -import com.datastax.oss.driver.internal.core.auth.PlainTextAuthProvider; -import com.datastax.oss.driver.shaded.guava.common.util.concurrent.Uninterruptibles; -import java.util.concurrent.TimeUnit; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Test; - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "5.0.0", - description = "DSE 5 required for Graph") -public class GraphAuthenticationIT { - - @ClassRule - public static CustomCcmRule ccm = - CustomCcmRule.builder() - .withDseConfiguration("authentication_options.enabled", true) - .withJvmArgs("-Dcassandra.superuser_setup_delay_ms=0") - .withDseWorkloads("graph") - .build(); - - @BeforeClass - public static void sleepForAuth() { - if (ccm.getCassandraVersion().compareTo(Version.V2_2_0) < 0) { - // Sleep for 1 second to allow C* auth to do its work. This is only needed for 2.1 - Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS); - } - } - - @Test - public void should_execute_graph_query_on_authenticated_connection() { - CqlSession dseSession = - SessionUtils.newSession( - ccm, - DriverConfigLoader.programmaticBuilder() - .withString(DseDriverOption.AUTH_PROVIDER_AUTHORIZATION_ID, "") - .withString(DefaultDriverOption.AUTH_PROVIDER_USER_NAME, "cassandra") - .withString(DefaultDriverOption.AUTH_PROVIDER_PASSWORD, "cassandra") - .withClass(DefaultDriverOption.AUTH_PROVIDER_CLASS, PlainTextAuthProvider.class) - .build()); - - GraphNode gn = - dseSession.execute(ScriptGraphStatement.newInstance("1+1").setSystemQuery(true)).one(); - assertThat(gn).isNotNull(); - assertThat(gn.asInt()).isEqualTo(2); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/GraphGeoSearchIndexITBase.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/GraphGeoSearchIndexITBase.java deleted file mode 100644 index 67d0cb34d43..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/GraphGeoSearchIndexITBase.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import static com.datastax.dse.driver.api.core.graph.TinkerGraphAssertions.assertThat; -import static org.assertj.core.api.Assertions.fail; -import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; - -import com.datastax.dse.driver.api.core.data.geometry.Point; -import com.datastax.dse.driver.api.core.graph.predicates.Geo; -import com.datastax.oss.driver.api.core.servererrors.InvalidQueryException; -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.assertj.core.api.Assumptions; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(DataProviderRunner.class) -public abstract class GraphGeoSearchIndexITBase { - - protected abstract boolean isGraphBinary(); - - protected abstract GraphTraversalSource graphTraversalSource(); - - @DataProvider - public static Object[][] indexTypes() { - return new Object[][] {{"search"} - - // FIXME for some reason, materialized and secondary indices have decided not to work - // I get an exception saying "there is no index for this query, here is the defined - // indices: " and the list contains the indices that are needed. Mysterious. - // There may be something to do with differences in the CCMBridge adapter of the new - // driver, some changes make materialized views and secondary indices to be not - // considered for graph: - // - // , {"materialized"} - // , {"secondary"} - }; - } - - @UseDataProvider("indexTypes") - @Test - public void search_by_distance_cartesian_graphson(String indexType) { - // cartesian is not supported by graph_binary - Assumptions.assumeThat(isGraphBinary()).isFalse(); - // in cartesian geometry, the distance between POINT(30 30) and POINT(40 40) is exactly - // 14.142135623730951 - // any point further than that should be detected outside of the range. - // the vertex "Paul Thomas Joe" is at POINT(40.0001 40), and shouldn't be detected inside the - // range for classic. - - GraphTraversal traversal = - graphTraversalSource() - .V() - .has( - "user", - "pointPropWithBounds_" + indexType, - Geo.inside(Point.fromCoordinates(30, 30), 14.142135623730951)) - .values("full_name"); - assertThat(traversal.toList()).containsOnly("George Bill Steve", "Jill Alice"); - } - - @UseDataProvider("indexTypes") - @Test - public void search_by_distance_geodetic(String indexType) { - // in geodetic geometry, the distance between POINT(30 30) and POINT(40 40) is exactly - // 12.908258700131379 - // any point further than that should be detected outside of the range. - // the vertex "Paul Thomas Joe" is at POINT(40.0001 40), and shouldn't be detected inside the - // range. - GraphTraversal traversal = - graphTraversalSource() - .V() - .has( - "user", - "pointPropWithGeoBounds_" + indexType, - Geo.inside(Point.fromCoordinates(30, 30), 12.908258700131379, Geo.Unit.DEGREES)) - .values("full_name"); - assertThat(traversal.toList()).containsOnly("George Bill Steve", "Jill Alice"); - } - - @Test - public void - should_fail_if_geodetic_predicate_used_against_cartesian_property_with_search_index() { - - // for graph_binary cartesian properties are not supported, thus it does not fail - if (isGraphBinary()) { - assertThatCode( - () -> { - GraphTraversal traversal = - graphTraversalSource() - .V() - .has( - "user", - "pointPropWithBounds_search", - Geo.inside( - Point.fromCoordinates(30, 30), - 12.908258700131379, - Geo.Unit.DEGREES)) - .values("full_name"); - traversal.toList(); - }) - .doesNotThrowAnyException(); - } else { - try { - GraphTraversal traversal = - graphTraversalSource() - .V() - .has( - "user", - "pointPropWithBounds_search", - Geo.inside(Point.fromCoordinates(30, 30), 12.908258700131379, Geo.Unit.DEGREES)) - .values("full_name"); - traversal.toList(); - fail("Should have failed executing the traversal because the property type is incorrect"); - } catch (InvalidQueryException e) { - assertThat(e.getMessage()) - .contains("Distance units cannot be used in queries against non-geodetic points."); - } - } - } - - @Test - public void - should_fail_if_cartesian_predicate_used_against_geodetic_property_with_search_index() { - - if (isGraphBinary()) { - try { - GraphTraversal traversal = - graphTraversalSource() - .V() - .has( - "user", - "pointPropWithGeoBounds_search", - Geo.inside(Point.fromCoordinates(30, 30), 14.142135623730951)) - .values("full_name"); - traversal.toList(); - fail("Should have failed executing the traversal because the property type is incorrect"); - } catch (InvalidQueryException e) { - assertThat(e.getMessage()) - .contains("Predicate 'insideCartesian' is not supported on property"); - } - } else { - try { - GraphTraversal traversal = - graphTraversalSource() - .V() - .has( - "user", - "pointPropWithGeoBounds_search", - Geo.inside(Point.fromCoordinates(30, 30), 14.142135623730951)) - .values("full_name"); - traversal.toList(); - fail("Should have failed executing the traversal because the property type is incorrect"); - } catch (InvalidQueryException e) { - assertThat(e.getMessage()) - .contains("Distance units are required for queries against geodetic points."); - } - } - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/GraphPagingIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/GraphPagingIT.java deleted file mode 100644 index aa0ada7840c..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/GraphPagingIT.java +++ /dev/null @@ -1,510 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import static com.datastax.dse.driver.api.core.cql.continuous.ContinuousPagingITBase.Options; -import static org.assertj.core.api.Assertions.fail; -import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; - -import com.codahale.metrics.Timer; -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.dse.driver.api.core.cql.continuous.ContinuousPagingITBase; -import com.datastax.dse.driver.api.core.metrics.DseNodeMetric; -import com.datastax.dse.driver.api.core.metrics.DseSessionMetric; -import com.datastax.dse.driver.internal.core.graph.MultiPageGraphResultSet; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.DriverTimeoutException; -import com.datastax.oss.driver.api.core.config.DefaultDriverOption; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.datastax.oss.driver.api.core.metrics.Metrics; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import com.datastax.oss.driver.api.testinfra.session.SessionUtils; -import com.datastax.oss.driver.internal.core.util.CountingIterator; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import java.net.SocketAddress; -import java.time.Duration; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.ExecutionException; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; -import org.junit.runner.RunWith; - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "6.8.0", - description = "Graph paging requires DSE 6.8+") -@RunWith(DataProviderRunner.class) -public class GraphPagingIT { - - private static final CustomCcmRule CCM_RULE = GraphTestSupport.GRAPH_CCM_RULE_BUILDER.build(); - - private static final SessionRule SESSION_RULE = - GraphTestSupport.getCoreGraphSessionBuilder(CCM_RULE) - .withConfigLoader( - SessionUtils.configLoaderBuilder() - .withStringList( - DefaultDriverOption.METRICS_SESSION_ENABLED, - Collections.singletonList(DseSessionMetric.GRAPH_REQUESTS.getPath())) - .withStringList( - DefaultDriverOption.METRICS_NODE_ENABLED, - Collections.singletonList(DseNodeMetric.GRAPH_MESSAGES.getPath())) - .build()) - .build(); - - @ClassRule - public static final TestRule CHAIN = RuleChain.outerRule(CCM_RULE).around(SESSION_RULE); - - @BeforeClass - public static void setupSchema() { - SESSION_RULE - .session() - .execute( - ScriptGraphStatement.newInstance( - "schema.vertexLabel('person')" - + ".partitionBy('pk', Int)" - + ".clusterBy('cc', Int)" - + ".property('name', Text)" - + ".create();") - .setGraphName(SESSION_RULE.getGraphName())); - for (int i = 1; i <= 100; i++) { - SESSION_RULE - .session() - .execute( - ScriptGraphStatement.newInstance( - String.format( - "g.addV('person').property('pk',0).property('cc',%d).property('name', '%s');", - i, "user" + i)) - .setGraphName(SESSION_RULE.getGraphName())); - } - } - - @UseDataProvider(location = ContinuousPagingITBase.class, value = "pagingOptions") - @Test - public void synchronous_paging_with_options(Options options) { - // given - DriverExecutionProfile profile = enableGraphPaging(options, PagingEnabledOptions.ENABLED); - - if (options.sizeInBytes) { - // Page sizes in bytes are not supported with graph queries - return; - } - - // when - GraphResultSet result = - SESSION_RULE - .session() - .execute( - ScriptGraphStatement.newInstance("g.V().hasLabel('person').values('name')") - .setGraphName(SESSION_RULE.getGraphName()) - .setTraversalSource("g") - .setExecutionProfile(profile)); - - // then - List nodes = result.all(); - - assertThat(((CountingIterator) result.iterator()).remaining()).isZero(); - assertThat(nodes).hasSize(options.expectedRows); - for (int i = 1; i <= nodes.size(); i++) { - GraphNode node = nodes.get(i - 1); - assertThat(node.asString()).isEqualTo("user" + i); - } - assertThat(result.getRequestExecutionInfo()).isNotNull(); - assertThat(result.getRequestExecutionInfo().getCoordinator().getEndPoint().resolve()) - .isEqualTo(firstCcmNode()); - assertIfMultiPage(result, options.expectedPages); - validateMetrics(SESSION_RULE.session()); - } - - @UseDataProvider(location = ContinuousPagingITBase.class, value = "pagingOptions") - @Test - public void synchronous_paging_with_options_when_auto(Options options) { - // given - DriverExecutionProfile profile = enableGraphPaging(options, PagingEnabledOptions.AUTO); - - if (options.sizeInBytes) { - // Page sizes in bytes are not supported with graph queries - return; - } - - // when - GraphResultSet result = - SESSION_RULE - .session() - .execute( - ScriptGraphStatement.newInstance("g.V().hasLabel('person').values('name')") - .setGraphName(SESSION_RULE.getGraphName()) - .setTraversalSource("g") - .setExecutionProfile(profile)); - - // then - List nodes = result.all(); - - assertThat(((CountingIterator) result.iterator()).remaining()).isZero(); - assertThat(nodes).hasSize(options.expectedRows); - for (int i = 1; i <= nodes.size(); i++) { - GraphNode node = nodes.get(i - 1); - assertThat(node.asString()).isEqualTo("user" + i); - } - assertThat(result.getRequestExecutionInfo()).isNotNull(); - assertThat(result.getRequestExecutionInfo().getCoordinator().getEndPoint().resolve()) - .isEqualTo(firstCcmNode()); - - assertIfMultiPage(result, options.expectedPages); - validateMetrics(SESSION_RULE.session()); - } - - private void assertIfMultiPage(GraphResultSet result, int expectedPages) { - if (result instanceof MultiPageGraphResultSet) { - assertThat(((MultiPageGraphResultSet) result).getRequestExecutionInfos()) - .hasSize(expectedPages); - assertThat(result.getRequestExecutionInfo()) - .isSameAs( - ((MultiPageGraphResultSet) result).getRequestExecutionInfos().get(expectedPages - 1)); - } - } - - @UseDataProvider(location = ContinuousPagingITBase.class, value = "pagingOptions") - @Test - public void synchronous_options_with_paging_disabled_should_fallback_to_single_page( - Options options) { - // given - DriverExecutionProfile profile = enableGraphPaging(options, PagingEnabledOptions.DISABLED); - - if (options.sizeInBytes) { - // Page sizes in bytes are not supported with graph queries - return; - } - - // when - GraphResultSet result = - SESSION_RULE - .session() - .execute( - ScriptGraphStatement.newInstance("g.V().hasLabel('person').values('name')") - .setGraphName(SESSION_RULE.getGraphName()) - .setTraversalSource("g") - .setExecutionProfile(profile)); - - // then - List nodes = result.all(); - - assertThat(((CountingIterator) result.iterator()).remaining()).isZero(); - assertThat(nodes).hasSize(100); - for (int i = 1; i <= nodes.size(); i++) { - GraphNode node = nodes.get(i - 1); - assertThat(node.asString()).isEqualTo("user" + i); - } - assertThat(result.getRequestExecutionInfo()).isNotNull(); - assertThat(result.getRequestExecutionInfo().getCoordinator().getEndPoint().resolve()) - .isEqualTo(firstCcmNode()); - validateMetrics(SESSION_RULE.session()); - } - - @UseDataProvider(location = ContinuousPagingITBase.class, value = "pagingOptions") - @Test - public void asynchronous_paging_with_options(Options options) - throws ExecutionException, InterruptedException { - // given - DriverExecutionProfile profile = enableGraphPaging(options, PagingEnabledOptions.ENABLED); - - if (options.sizeInBytes) { - // Page sizes in bytes are not supported with graph queries - return; - } - - // when - CompletionStage result = - SESSION_RULE - .session() - .executeAsync( - ScriptGraphStatement.newInstance("g.V().hasLabel('person').values('name')") - .setGraphName(SESSION_RULE.getGraphName()) - .setTraversalSource("g") - .setExecutionProfile(profile)); - - // then - checkAsyncResult(result, options, 0, 1, new ArrayList<>()); - validateMetrics(SESSION_RULE.session()); - } - - @UseDataProvider(location = ContinuousPagingITBase.class, value = "pagingOptions") - @Test - public void asynchronous_paging_with_options_when_auto(Options options) - throws ExecutionException, InterruptedException { - // given - DriverExecutionProfile profile = enableGraphPaging(options, PagingEnabledOptions.AUTO); - - if (options.sizeInBytes) { - // Page sizes in bytes are not supported with graph queries - return; - } - - // when - CompletionStage result = - SESSION_RULE - .session() - .executeAsync( - ScriptGraphStatement.newInstance("g.V().hasLabel('person').values('name')") - .setGraphName(SESSION_RULE.getGraphName()) - .setTraversalSource("g") - .setExecutionProfile(profile)); - - // then - checkAsyncResult(result, options, 0, 1, new ArrayList<>()); - validateMetrics(SESSION_RULE.session()); - } - - @UseDataProvider(location = ContinuousPagingITBase.class, value = "pagingOptions") - @Test - public void asynchronous_options_with_paging_disabled_should_fallback_to_single_page( - Options options) throws ExecutionException, InterruptedException { - // given - DriverExecutionProfile profile = enableGraphPaging(options, PagingEnabledOptions.DISABLED); - - if (options.sizeInBytes) { - // Page sizes in bytes are not supported with graph queries - return; - } - - // when - CompletionStage result = - SESSION_RULE - .session() - .executeAsync( - ScriptGraphStatement.newInstance("g.V().hasLabel('person').values('name')") - .setGraphName(SESSION_RULE.getGraphName()) - .setTraversalSource("g") - .setExecutionProfile(profile)); - - // then - AsyncGraphResultSet asyncGraphResultSet = result.toCompletableFuture().get(); - for (int i = 1; i <= 100; i++, asyncGraphResultSet.remaining()) { - GraphNode node = asyncGraphResultSet.one(); - assertThat(node.asString()).isEqualTo("user" + i); - } - assertThat(asyncGraphResultSet.remaining()).isEqualTo(0); - validateMetrics(SESSION_RULE.session()); - } - - private void checkAsyncResult( - CompletionStage future, - Options options, - int rowsFetched, - int pageNumber, - List graphExecutionInfos) - throws ExecutionException, InterruptedException { - AsyncGraphResultSet result = future.toCompletableFuture().get(); - int remaining = result.remaining(); - rowsFetched += remaining; - assertThat(remaining).isLessThanOrEqualTo(options.pageSize); - - if (options.expectedRows == rowsFetched) { - assertThat(result.hasMorePages()).isFalse(); - } else { - assertThat(result.hasMorePages()).isTrue(); - } - - int first = (pageNumber - 1) * options.pageSize + 1; - int last = (pageNumber - 1) * options.pageSize + remaining; - - for (int i = first; i <= last; i++, remaining--) { - GraphNode node = result.one(); - assertThat(node.asString()).isEqualTo("user" + i); - assertThat(result.remaining()).isEqualTo(remaining - 1); - } - - assertThat(result.remaining()).isZero(); - assertThat(result.getRequestExecutionInfo()).isNotNull(); - assertThat(result.getRequestExecutionInfo().getCoordinator().getEndPoint().resolve()) - .isEqualTo(firstCcmNode()); - - graphExecutionInfos.add(result.getRequestExecutionInfo()); - - assertThat(graphExecutionInfos).hasSize(pageNumber); - assertThat(result.getRequestExecutionInfo()).isSameAs(graphExecutionInfos.get(pageNumber - 1)); - if (pageNumber == options.expectedPages) { - assertThat(result.hasMorePages()).isFalse(); - assertThat(options.expectedRows).isEqualTo(rowsFetched); - assertThat(options.expectedPages).isEqualTo(pageNumber); - } else { - assertThat(result.hasMorePages()).isTrue(); - checkAsyncResult( - result.fetchNextPage(), options, rowsFetched, pageNumber + 1, graphExecutionInfos); - } - } - - @Test - public void should_cancel_result_set() { - // given - DriverExecutionProfile profile = - enableGraphPaging() - .withInt(DseDriverOption.GRAPH_CONTINUOUS_PAGING_MAX_ENQUEUED_PAGES, 1) - .withInt(DseDriverOption.GRAPH_CONTINUOUS_PAGING_PAGE_SIZE, 10); - - // when - GraphStatement statement = - ScriptGraphStatement.newInstance("g.V().hasLabel('person').values('name')") - .setGraphName(SESSION_RULE.getGraphName()) - .setTraversalSource("g") - .setExecutionProfile(profile); - MultiPageGraphResultSet results = - (MultiPageGraphResultSet) SESSION_RULE.session().execute(statement); - - assertThat(((MultiPageGraphResultSet.RowIterator) results.iterator()).isCancelled()).isFalse(); - assertThat(((CountingIterator) results.iterator()).remaining()).isEqualTo(10); - results.cancel(); - - assertThat(((MultiPageGraphResultSet.RowIterator) results.iterator()).isCancelled()).isTrue(); - assertThat(((CountingIterator) results.iterator()).remaining()).isEqualTo(10); - for (int i = 0; i < 10; i++) { - results.one(); - } - } - - @Test - public void should_trigger_global_timeout_sync_from_config() { - // given - Duration timeout = Duration.ofMillis(100); - DriverExecutionProfile profile = - enableGraphPaging().withDuration(DseDriverOption.GRAPH_TIMEOUT, timeout); - - // when - try { - CCM_RULE.getCcmBridge().pause(1); - try { - SESSION_RULE - .session() - .execute( - ScriptGraphStatement.newInstance("g.V().hasLabel('person').values('name')") - .setGraphName(SESSION_RULE.getGraphName()) - .setTraversalSource("g") - .setExecutionProfile(profile)); - fail("Expecting DriverTimeoutException"); - } catch (DriverTimeoutException e) { - assertThat(e).hasMessageStartingWith("Query timed out after " + timeout); - } - } finally { - CCM_RULE.getCcmBridge().resume(1); - } - } - - @Test - public void should_trigger_global_timeout_sync_from_statement() { - // given - Duration timeout = Duration.ofMillis(100); - - // when - try { - CCM_RULE.getCcmBridge().pause(1); - try { - SESSION_RULE - .session() - .execute( - ScriptGraphStatement.newInstance("g.V().hasLabel('person').values('name')") - .setGraphName(SESSION_RULE.getGraphName()) - .setTraversalSource("g") - .setTimeout(timeout)); - fail("Expecting DriverTimeoutException"); - } catch (DriverTimeoutException e) { - assertThat(e).hasMessageStartingWith("Query timed out after " + timeout); - } - } finally { - CCM_RULE.getCcmBridge().resume(1); - } - } - - @Test - public void should_trigger_global_timeout_async() throws InterruptedException { - // given - Duration timeout = Duration.ofMillis(100); - DriverExecutionProfile profile = - enableGraphPaging().withDuration(DseDriverOption.GRAPH_TIMEOUT, timeout); - - // when - try { - CCM_RULE.getCcmBridge().pause(1); - CompletionStage result = - SESSION_RULE - .session() - .executeAsync( - ScriptGraphStatement.newInstance("g.V().hasLabel('person').values('name')") - .setGraphName(SESSION_RULE.getGraphName()) - .setTraversalSource("g") - .setExecutionProfile(profile)); - result.toCompletableFuture().get(); - fail("Expecting DriverTimeoutException"); - } catch (ExecutionException e) { - assertThat(e.getCause()).hasMessageStartingWith("Query timed out after " + timeout); - } finally { - CCM_RULE.getCcmBridge().resume(1); - } - } - - private DriverExecutionProfile enableGraphPaging() { - return SESSION_RULE - .session() - .getContext() - .getConfig() - .getDefaultProfile() - .withString(DseDriverOption.GRAPH_PAGING_ENABLED, PagingEnabledOptions.ENABLED.name()); - } - - private DriverExecutionProfile enableGraphPaging( - Options options, PagingEnabledOptions pagingEnabledOptions) { - return SESSION_RULE - .session() - .getContext() - .getConfig() - .getDefaultProfile() - .withInt(DseDriverOption.GRAPH_CONTINUOUS_PAGING_PAGE_SIZE, options.pageSize) - .withInt(DseDriverOption.GRAPH_CONTINUOUS_PAGING_MAX_PAGES, options.maxPages) - .withInt( - DseDriverOption.GRAPH_CONTINUOUS_PAGING_MAX_PAGES_PER_SECOND, options.maxPagesPerSecond) - .withString(DseDriverOption.GRAPH_PAGING_ENABLED, pagingEnabledOptions.name()); - } - - private SocketAddress firstCcmNode() { - return CCM_RULE.getContactPoints().iterator().next().resolve(); - } - - private void validateMetrics(CqlSession session) { - Node node = session.getMetadata().getNodes().values().iterator().next(); - assertThat(session.getMetrics()).isPresent(); - Metrics metrics = session.getMetrics().get(); - assertThat(metrics.getNodeMetric(node, DseNodeMetric.GRAPH_MESSAGES)).isPresent(); - Timer messages = (Timer) metrics.getNodeMetric(node, DseNodeMetric.GRAPH_MESSAGES).get(); - assertThat(messages.getCount()).isGreaterThan(0); - assertThat(messages.getMeanRate()).isGreaterThan(0); - assertThat(metrics.getSessionMetric(DseSessionMetric.GRAPH_REQUESTS)).isPresent(); - Timer requests = (Timer) metrics.getSessionMetric(DseSessionMetric.GRAPH_REQUESTS).get(); - assertThat(requests.getCount()).isGreaterThan(0); - assertThat(requests.getMeanRate()).isGreaterThan(0); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/GraphSpeculativeExecutionIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/GraphSpeculativeExecutionIT.java deleted file mode 100644 index 130e9a17cc1..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/GraphSpeculativeExecutionIT.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.config.DefaultDriverOption; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionUtils; -import com.datastax.oss.driver.internal.core.specex.ConstantSpeculativeExecutionPolicy; -import com.datastax.oss.driver.internal.core.specex.NoSpeculativeExecutionPolicy; -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import java.time.Duration; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.runner.RunWith; - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "6.8.0", - description = "DSE 6.8 required for graph paging") -@RunWith(DataProviderRunner.class) -public class GraphSpeculativeExecutionIT { - - @ClassRule - public static CustomCcmRule ccmRule = CustomCcmRule.builder().withDseWorkloads("graph").build(); - - @Test - @UseDataProvider("idempotenceAndSpecExecs") - public void should_use_speculative_executions_when_enabled( - boolean defaultIdempotence, - Boolean statementIdempotence, - Class speculativeExecutionClass, - boolean expectSpeculativeExecutions) { - - try (CqlSession session = - CqlSession.builder() - .addContactEndPoints(ccmRule.getContactPoints()) - .withConfigLoader( - SessionUtils.configLoaderBuilder() - .withBoolean( - DefaultDriverOption.REQUEST_DEFAULT_IDEMPOTENCE, defaultIdempotence) - .withInt(DefaultDriverOption.SPECULATIVE_EXECUTION_MAX, 10) - .withClass( - DefaultDriverOption.SPECULATIVE_EXECUTION_POLICY_CLASS, - speculativeExecutionClass) - .withDuration( - DefaultDriverOption.SPECULATIVE_EXECUTION_DELAY, Duration.ofMillis(10)) - .withString(DseDriverOption.GRAPH_PAGING_ENABLED, "ENABLED") - .build()) - .build()) { - - ScriptGraphStatement statement = - ScriptGraphStatement.newInstance( - "java.util.concurrent.TimeUnit.MILLISECONDS.sleep(1000L);") - .setIdempotent(statementIdempotence); - - GraphResultSet result = session.execute(statement); - int speculativeExecutionCount = - result.getRequestExecutionInfo().getSpeculativeExecutionCount(); - if (expectSpeculativeExecutions) { - assertThat(speculativeExecutionCount).isGreaterThan(0); - } else { - assertThat(speculativeExecutionCount).isEqualTo(0); - } - } - } - - @DataProvider - public static Object[][] idempotenceAndSpecExecs() { - return new Object[][] { - new Object[] {false, false, NoSpeculativeExecutionPolicy.class, false}, - new Object[] {false, true, NoSpeculativeExecutionPolicy.class, false}, - new Object[] {false, null, NoSpeculativeExecutionPolicy.class, false}, - new Object[] {true, false, NoSpeculativeExecutionPolicy.class, false}, - new Object[] {true, true, NoSpeculativeExecutionPolicy.class, false}, - new Object[] {true, null, NoSpeculativeExecutionPolicy.class, false}, - new Object[] {false, false, ConstantSpeculativeExecutionPolicy.class, false}, - new Object[] {false, true, ConstantSpeculativeExecutionPolicy.class, true}, - new Object[] {false, null, ConstantSpeculativeExecutionPolicy.class, false}, - new Object[] {true, false, ConstantSpeculativeExecutionPolicy.class, false}, - new Object[] {true, true, ConstantSpeculativeExecutionPolicy.class, true}, - new Object[] {true, null, ConstantSpeculativeExecutionPolicy.class, true}, - }; - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/GraphTestSupport.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/GraphTestSupport.java deleted file mode 100644 index 6508be38175..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/GraphTestSupport.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import com.datastax.dse.driver.internal.core.graph.GraphProtocol; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.session.CqlSessionRuleBuilder; - -/** Utility for creating commonly used Rule builders for tests. */ -public class GraphTestSupport { - - /** CCM Rule builder for Graph Data Type tests. */ - public static final CustomCcmRule.Builder CCM_BUILDER_WITH_GRAPH = - CustomCcmRule.builder() - .withDseWorkloads("graph") - .withDseConfiguration("graph.max_query_params", 32) - .withDseConfiguration( - "graph.gremlin_server.scriptEngines.gremlin-groovy.config.sandbox_enabled", "false"); - - /** CCM Rule builder for general Graph workload tests. */ - public static final CustomCcmRule.Builder GRAPH_CCM_RULE_BUILDER = - CustomCcmRule.builder().withDseWorkloads("graph"); - - /** - * Creates a session rule builder for Classic Graph workloads with the default Graph protocol. The - * default GraphProtocol for Classic Graph: GraphSON 2.0. - * - * @param ccmRule CustomCcmRule configured for Graph workloads - * @return A Session rule builder configured for Classic Graph workloads - */ - public static CqlSessionRuleBuilder getClassicGraphSessionBuilder(CustomCcmRule ccmRule) { - return new CqlSessionRuleBuilder(ccmRule) - .withCreateGraph() - .withGraphProtocol(GraphProtocol.GRAPHSON_2_0.toInternalCode()); - } - - /** - * Creates a session rule builder for Core Graph workloads with the default Graph protocol. The - * default GraphProtocol for Core Graph: Graph Binary 1.0. - * - * @param ccmRule CustomCcmRule configured for Graph workloads - * @return A Session rule builder configured for Core Graph workloads - */ - public static CqlSessionRuleBuilder getCoreGraphSessionBuilder(CustomCcmRule ccmRule) { - return new CqlSessionRuleBuilder(ccmRule) - .withCreateGraph() - .withCoreEngine() - .withGraphProtocol(GraphProtocol.GRAPH_BINARY_1_0.toInternalCode()); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/GraphTextSearchIndexITBase.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/GraphTextSearchIndexITBase.java deleted file mode 100644 index d70d206715e..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/GraphTextSearchIndexITBase.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.dse.driver.api.core.graph.predicates.Search; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(DataProviderRunner.class) -public abstract class GraphTextSearchIndexITBase { - - protected abstract boolean isGraphBinary(); - - protected abstract GraphTraversalSource graphTraversalSource(); - - @DataProvider - public static Object[][] indexTypes() { - return new Object[][] {{"search"} - - // FIXME for some reason, materialized and secondary indices have decided not to work - // I get an exception saying "there is no index for this query, here is the defined - // indices: " and the list contains the indices that are needed. Mysterious. - // There may be something to do with differences in the CCMBridge adapter of the new - // driver, some changes make materialized views and secondary indices to be not - // considered for graph: - // - // , {"materialized"} - // , {"secondary"} - }; - } - - /** - * Validates that a graph traversal can be made by using a Search prefix predicate on an indexed - * property of the given type. - * - *

Finds all 'user' vertices having a 'full_name' property beginning with 'Paul'. - * - * @test_category dse:graph - */ - @UseDataProvider("indexTypes") - @Test - public void search_by_prefix_search(String indexType) { - // Only one user with full_name starting with Paul. - GraphTraversal traversal = - graphTraversalSource() - .V() - .has("user", "full_name_" + indexType, Search.prefix("Paul")) - .values("full_name_" + indexType); - assertThat(traversal.toList()).containsOnly("Paul Thomas Joe"); - } - - /** - * Validates that a graph traversal can be made by using a Search regex predicate on an indexed - * property of the given type. - * - *

Finds all 'user' vertices having a 'full_name' property matching regex '.*Paul.*'. - * - * @test_category dse:graph - */ - @UseDataProvider("indexTypes") - @Test - public void search_by_regex(String indexType) { - // Only two people with names containing pattern for Paul. - GraphTraversal traversal = - graphTraversalSource() - .V() - .has("user", "full_name_" + indexType, Search.regex(".*Paul.*")) - .values("full_name_" + indexType); - assertThat(traversal.toList()).containsOnly("Paul Thomas Joe", "James Paul Joe"); - } - - /** - * Validates that a graph traversal can be made by using a Search fuzzy predicate on an indexed - * property of the given type. - * - *

Finds all 'user' vertices having a 'alias' property matching 'awrio' with a fuzzy distance - * of 1. - * - * @test_category dse:graph - */ - @UseDataProvider("indexTypes") - @Test - @BackendRequirement(type = BackendType.DSE, minInclusive = "5.1.0") - public void search_by_fuzzy(String indexType) { - // Alias matches 'awrio' fuzzy - GraphTraversal traversal = - graphTraversalSource() - .V() - .has("user", "alias_" + indexType, Search.fuzzy("awrio", 1)) - .values("full_name_" + indexType); - // Should not match 'Paul Thomas Joe' since alias is 'mario', which is at distance 2 of 'awrio' - // (a -> m, w -> a) - // Should match 'George Bill Steve' since alias is 'wario' witch matches 'awrio' within a - // distance of 1 (transpose w with a). - assertThat(traversal.toList()).containsOnly("George Bill Steve"); - } - - /** - * Validates that a graph traversal can be made by using a Search token predicate on an indexed - * property of the given type. - * - *

Finds all 'user' vertices having a 'description' property containing the token 'cold'. - * - * @test_category dse:graph - */ - @UseDataProvider("indexTypes") - @Test - public void search_by_token(String indexType) { - // Description containing token 'cold' - GraphTraversal traversal = - graphTraversalSource() - .V() - .has("user", "description_" + indexType, Search.token("cold")) - .values("full_name_" + indexType); - assertThat(traversal.toList()).containsOnly("Jill Alice", "George Bill Steve"); - } - - /** - * Validates that a graph traversal can be made by using a Search token prefix predicate on an - * indexed property of the given type. - * - *

Finds all 'user' vertices having a 'description' containing the token prefix 'h'. - */ - @UseDataProvider("indexTypes") - @Test - public void search_by_token_prefix(String indexType) { - // Description containing a token starting with h - GraphTraversal traversal = - graphTraversalSource() - .V() - .has("user", "description_" + indexType, Search.tokenPrefix("h")) - .values("full_name_" + indexType); - assertThat(traversal.toList()).containsOnly("Paul Thomas Joe", "James Paul Joe"); - } - - /** - * Validates that a graph traversal can be made by using a Search token regex predicate on an - * indexed property of the given type. - * - *

Finds all 'user' vertices having a 'description' containing the token regex - * '(nice|hospital)'. - */ - @UseDataProvider("indexTypes") - @Test - public void search_by_token_regex(String indexType) { - // Description containing nice or hospital - GraphTraversal traversal = - graphTraversalSource() - .V() - .has("user", "description_" + indexType, Search.tokenRegex("(nice|hospital)")) - .values("full_name_" + indexType); - assertThat(traversal.toList()).containsOnly("Paul Thomas Joe", "Jill Alice"); - } - - /** - * Validates that a graph traversal can be made by using a Search fuzzy predicate on an indexed - * property of the given type. - * - *

Finds all 'user' vertices having a 'description' property matching 'lieks' with a fuzzy - * distance of 1. - * - * @test_category dse:graph - */ - @UseDataProvider("indexTypes") - @Test - @BackendRequirement(type = BackendType.DSE, minInclusive = "5.1.0") - public void search_by_token_fuzzy(String indexType) { - // Description containing 'lives' fuzzy - GraphTraversal traversal = - graphTraversalSource() - .V() - .has("user", "description_" + indexType, Search.tokenFuzzy("lieks", 1)) - .values("full_name_" + indexType); - // Should not match 'Paul Thomas Joe' since description contains 'Lives' which is at distance of - // 2 (e -> v, k -> e) - // Should match 'James Paul Joe' since description contains 'Likes' (transpose e for k) - assertThat(traversal.toList()).containsOnly("James Paul Joe"); - } - - /** - * Validates that a graph traversal can be made by using a Search phrase predicate on an indexed - * property of the given type. - * - *

Finds all 'user' vertices having a 'description' property matching 'a cold' with a distance - * of 2. - * - * @test_category dse:graph - */ - @UseDataProvider("indexTypes") - @Test - @BackendRequirement(type = BackendType.DSE, minInclusive = "5.1.0") - public void search_by_phrase(String indexType) { - // Full name contains phrase "Paul Joe" - GraphTraversal traversal = - graphTraversalSource() - .V() - .has("user", "description_" + indexType, Search.phrase("a cold", 2)) - .values("full_name_" + indexType); - // Should match 'George Bill Steve' since 'A cold dude' is at distance of 0 for 'a cold'. - // Should match 'Jill Alice' since 'Enjoys a very nice cold coca cola' is at distance of 2 for - // 'a cold'. - assertThat(traversal.toList()).containsOnly("George Bill Steve", "Jill Alice"); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/GraphTimeoutsIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/GraphTimeoutsIT.java deleted file mode 100644 index edf398a4c3c..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/GraphTimeoutsIT.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import static com.datastax.dse.driver.api.core.graph.ScriptGraphStatement.newInstance; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; - -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.DriverTimeoutException; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.servererrors.InvalidQueryException; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import java.time.Duration; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "5.0.0", - description = "DSE 5 required for Graph") -public class GraphTimeoutsIT { - - public static CustomCcmRule ccmRule = CustomCcmRule.builder().withDseWorkloads("graph").build(); - - public static SessionRule sessionRule = - SessionRule.builder(ccmRule).withCreateGraph().build(); - - @ClassRule public static TestRule chain = RuleChain.outerRule(ccmRule).around(sessionRule); - - @Test - public void should_have_driver_wait_indefinitely_by_default_and_server_return_timeout_response() { - Duration serverTimeout = Duration.ofSeconds(1); - - DriverExecutionProfile drivertest1 = - sessionRule - .session() - .getContext() - .getConfig() - .getDefaultProfile() - .withString(DseDriverOption.GRAPH_TRAVERSAL_SOURCE, "drivertest1"); - - // We could have done with the server's default but it's 30 secs so the test would have taken at - // least that time. So we simulate a server timeout change. - sessionRule - .session() - .execute( - newInstance( - "graph.schema().config().option(\"graph.traversal_sources.drivertest1.evaluation_timeout\").set('" - + serverTimeout.toMillis() - + " ms')") - .setExecutionProfile(drivertest1)); - - try { - // The driver should wait indefinitely, but the server should timeout first. - sessionRule - .session() - .execute( - newInstance("java.util.concurrent.TimeUnit.MILLISECONDS.sleep(35000L);1+1") - .setExecutionProfile(drivertest1)); - fail("The request should have timed out"); - } catch (InvalidQueryException e) { - assertThat(e) - .hasMessageContainingAll( - "evaluation exceeded", - "threshold of ", - Long.toString(serverTimeout.toMillis()), - "ms"); - } - } - - @Test - public void should_not_take_into_account_request_timeout_if_more_than_server_timeout() { - Duration serverTimeout = Duration.ofSeconds(1); - Duration clientTimeout = Duration.ofSeconds(10); - - DriverExecutionProfile drivertest2 = - sessionRule - .session() - .getContext() - .getConfig() - .getDefaultProfile() - .withString(DseDriverOption.GRAPH_TRAVERSAL_SOURCE, "drivertest2") - .withDuration(DseDriverOption.GRAPH_TIMEOUT, clientTimeout); - - sessionRule - .session() - .execute( - newInstance( - "graph.schema().config().option(\"graph.traversal_sources.drivertest2.evaluation_timeout\").set('" - + serverTimeout.toMillis() - + " ms')") - .setExecutionProfile(drivertest2)); - - try { - // The driver should wait 32 secs, but the server should timeout first. - sessionRule - .session() - .execute( - newInstance("java.util.concurrent.TimeUnit.MILLISECONDS.sleep(35000L);1+1") - .setExecutionProfile(drivertest2)); - fail("The request should have timed out"); - } catch (InvalidQueryException e) { - assertThat(e) - .hasMessageContainingAll( - "evaluation exceeded", - "threshold of ", - Long.toString(serverTimeout.toMillis()), - "ms"); - } - } - - @Test - public void should_take_into_account_request_timeout_if_less_than_server_timeout() { - Duration serverTimeout = Duration.ofSeconds(10); - Duration clientTimeout = Duration.ofSeconds(1); - - DriverExecutionProfile drivertest3 = - sessionRule - .session() - .getContext() - .getConfig() - .getDefaultProfile() - .withString(DseDriverOption.GRAPH_TRAVERSAL_SOURCE, "drivertest3"); - - // We could have done with the server's default but it's 30 secs so the test would have taken at - // least that time. Also, we don't want to rely on server's default. So we simulate a server - // timeout change. - sessionRule - .session() - .execute( - ScriptGraphStatement.newInstance( - "graph.schema().config().option(\"graph.traversal_sources.drivertest3.evaluation_timeout\").set('" - + serverTimeout.toMillis() - + " ms')") - .setExecutionProfile(drivertest3)); - - try { - // The timeout on the request is lower than what's defined server side, so it should be taken - // into account. - sessionRule - .session() - .execute( - ScriptGraphStatement.newInstance( - "java.util.concurrent.TimeUnit.MILLISECONDS.sleep(35000L);1+1") - .setExecutionProfile( - drivertest3.withDuration(DseDriverOption.GRAPH_TIMEOUT, clientTimeout))); - fail("The request should have timed out"); - // Since the driver sends its timeout in the request payload, server timeout will be equal to - // client timeout for this request. We cannot know for sure if it will be a client timeout - // error, or a server timeout, and during tests, both happened and not deterministically. - } catch (DriverTimeoutException e) { - assertThat(e).hasMessageStartingWith("Query timed out after " + clientTimeout); - } catch (InvalidQueryException e) { - assertThat(e) - .hasMessageContainingAll( - "evaluation exceeded", - "threshold of ", - Long.toString(clientTimeout.toMillis()), - "ms"); - } - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/SampleGraphScripts.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/SampleGraphScripts.java deleted file mode 100644 index 19ff957736a..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/SampleGraphScripts.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -public class SampleGraphScripts { - - public static final String MAKE_STRICT = - "schema.config().option('graph.schema_mode').set('production');\n"; - - public static final String MAKE_NOT_STRICT = - "schema.config().option('graph.schema_mode').set('development');\n"; - - public static final String ALLOW_SCANS = - "schema.config().option('graph.allow_scan').set('true');\n"; - - private static final String CLASSIC_SCHEMA = - "schema.propertyKey('name').Text().ifNotExists().create();\n" - + "schema.propertyKey('age').Int().ifNotExists().create();\n" - + "schema.propertyKey('lang').Text().ifNotExists().create();\n" - + "schema.propertyKey('weight').Float().ifNotExists().create();\n" - + "schema.vertexLabel('person').properties('name', 'age').ifNotExists().create();\n" - + "schema.vertexLabel('software').properties('name', 'lang').ifNotExists().create();\n" - + "schema.edgeLabel('created').properties('weight').connection('person', 'software').ifNotExists().create();\n" - + "schema.edgeLabel('knows').properties('weight').connection('person', 'person').ifNotExists().create();\n"; - - private static final String INSERT_DATA = - "marko = g.addV('person').property('name', 'marko').property('age', 29).next();\n" - + "vadas = g.addV('person').property('name', 'vadas').property('age', 27).next();\n" - + "josh = g.addV('person').property('name', 'josh').property('age', 32).next();\n" - + "peter = g.addV('person').property('name', 'peter').property('age', 35).next();\n" - + "lop = g.addV('software').property('name', 'lop').property('lang', 'java').next();\n" - + "ripple = g.addV('software').property('name', 'ripple').property('lang', 'java').next();\n" - + "g.V().has('name', 'marko').as('marko').V().has('name', 'vadas').as('vadas').addE('knows').from('marko').property('weight', 0.5f).next();\n" - + "g.V().has('name', 'marko').as('marko').V().has('name', 'josh').as('josh').addE('knows').from('marko').property('weight', 1.0f).next();\n" - + "g.V().has('name', 'marko').as('marko').V().has('name', 'lop').as('lop').addE('created').from('marko').property('weight', 0.4f).next();\n" - + "g.V().has('name', 'josh').as('josh').V().has('name', 'ripple').as('ripple').addE('created').from('josh').property('weight', 1.0f).next();\n" - + "g.V().has('name', 'josh').as('josh').V().has('name', 'lop').as('lop').addE('created').from('josh').property('weight', 0.4f).next();\n" - + "g.V().has('name', 'peter').as('peter').V().has('name', 'lop').as('lop').addE('created').from('peter').property('weight', 0.2f);"; - - public static String CLASSIC_GRAPH = CLASSIC_SCHEMA + INSERT_DATA; - - private static final String CORE_SCHEMA = - "schema.vertexLabel('person').ifNotExists().partitionBy('name', Text).property('age', Int).create();\n" - + "schema.vertexLabel('software').ifNotExists().partitionBy('name', Text).property('lang', Text).create();\n" - + "schema.edgeLabel('created').ifNotExists().from('person').to('software').property('weight', Float).create();\n" - + "schema.edgeLabel('knows').ifNotExists().from('person').to('person').property('weight', Float).create();\n"; - - public static String CORE_GRAPH = CORE_SCHEMA + INSERT_DATA; -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/SocialTraversalDsl.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/SocialTraversalDsl.java deleted file mode 100644 index 327f32a240d..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/SocialTraversalDsl.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import org.apache.tinkerpop.gremlin.process.traversal.dsl.GremlinDsl; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; -import org.apache.tinkerpop.gremlin.structure.Vertex; - -@GremlinDsl(traversalSource = "com.datastax.dse.driver.api.core.graph.SocialTraversalSourceDsl") -public interface SocialTraversalDsl extends GraphTraversal.Admin { - public default GraphTraversal knows(String personName) { - return out("knows").hasLabel("person").has("name", personName).in(); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/SocialTraversalSourceDsl.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/SocialTraversalSourceDsl.java deleted file mode 100644 index e61b94e2d09..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/SocialTraversalSourceDsl.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import org.apache.tinkerpop.gremlin.process.remote.RemoteConnection; -import org.apache.tinkerpop.gremlin.process.traversal.P; -import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.apache.tinkerpop.gremlin.process.traversal.step.map.GraphStep; -import org.apache.tinkerpop.gremlin.structure.Graph; -import org.apache.tinkerpop.gremlin.structure.Vertex; - -public class SocialTraversalSourceDsl extends GraphTraversalSource { - - public SocialTraversalSourceDsl( - final Graph graph, final TraversalStrategies traversalStrategies) { - super(graph, traversalStrategies); - } - - public SocialTraversalSourceDsl(final Graph graph) { - super(graph); - } - - public SocialTraversalSourceDsl(RemoteConnection connection) { - super(connection); - } - - public GraphTraversal persons(String... names) { - GraphTraversalSource clone = this.clone(); - - // Manually add a "start" step for the traversal in this case the equivalent of V(). GraphStep - // is marked - // as a "start" step by passing "true" in the constructor. - clone.getBytecode().addStep(GraphTraversal.Symbols.V); - GraphTraversal traversal = new DefaultGraphTraversal<>(clone); - traversal.asAdmin().addStep(new GraphStep(traversal.asAdmin(), Vertex.class, true)); - - traversal = traversal.hasLabel("person"); - if (names.length > 0) traversal = traversal.has("name", P.within(names)); - - return traversal; - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/TinkerEdgeAssert.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/TinkerEdgeAssert.java deleted file mode 100644 index e3cc8cb687b..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/TinkerEdgeAssert.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import com.datastax.oss.driver.assertions.Assertions; -import org.apache.tinkerpop.gremlin.structure.Edge; -import org.apache.tinkerpop.gremlin.structure.Vertex; - -public class TinkerEdgeAssert extends TinkerElementAssert { - - public TinkerEdgeAssert(Edge actual) { - super(actual, TinkerEdgeAssert.class); - } - - public TinkerEdgeAssert hasInVLabel(String label) { - Assertions.assertThat(actual.inVertex().label()).isEqualTo(label); - return myself; - } - - public TinkerEdgeAssert hasOutVLabel(String label) { - Assertions.assertThat(actual.outVertex().label()).isEqualTo(label); - return myself; - } - - public TinkerEdgeAssert hasOutV(Vertex vertex) { - Assertions.assertThat(actual.outVertex()).isEqualTo(vertex); - return myself; - } - - public TinkerEdgeAssert hasInV(Vertex vertex) { - Assertions.assertThat(actual.inVertex()).isEqualTo(vertex); - return myself; - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/TinkerElementAssert.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/TinkerElementAssert.java deleted file mode 100644 index f54cec3065a..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/TinkerElementAssert.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.apache.tinkerpop.gremlin.structure.Element; -import org.assertj.core.api.AbstractAssert; - -public abstract class TinkerElementAssert, A extends Element> - extends AbstractAssert { - - protected TinkerElementAssert(A actual, Class selfType) { - super(actual, selfType); - } - - public S hasId(Object id) { - assertThat(actual.id()).isEqualTo(id); - return myself; - } - - public S hasLabel(String label) { - assertThat(actual.label()).isEqualTo(label); - return myself; - } - - public S hasProperty(String propertyName) { - assertThat(actual.property(propertyName).isPresent()).isTrue(); - return myself; - } - - public S hasProperty(String propertyName, Object value) { - hasProperty(propertyName); - assertThat(actual.property(propertyName).value()).isEqualTo(value); - return myself; - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/TinkerGraphAssertions.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/TinkerGraphAssertions.java deleted file mode 100644 index 9c38a58db4c..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/TinkerGraphAssertions.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import org.apache.tinkerpop.gremlin.process.traversal.Path; -import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree; -import org.apache.tinkerpop.gremlin.structure.Edge; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.apache.tinkerpop.gremlin.structure.VertexProperty; - -public class TinkerGraphAssertions extends com.datastax.oss.driver.assertions.Assertions { - - public static TinkerEdgeAssert assertThat(Edge edge) { - return new TinkerEdgeAssert(edge); - } - - public static TinkerVertexAssert assertThat(Vertex vertex) { - return new TinkerVertexAssert(vertex); - } - - public static TinkerVertexPropertyAssert assertThat(VertexProperty vertexProperty) { - return new TinkerVertexPropertyAssert(vertexProperty); - } - - public static TinkerPathAssert assertThat(Path path) { - return new TinkerPathAssert(path); - } - - public static TinkerTreeAssert assertThat(Tree tree) { - return new TinkerTreeAssert<>(tree); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/TinkerPathAssert.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/TinkerPathAssert.java deleted file mode 100644 index 30f8f5fffa4..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/TinkerPathAssert.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.apache.tinkerpop.gremlin.process.traversal.Path; -import org.apache.tinkerpop.gremlin.structure.Edge; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.assertj.core.api.AbstractAssert; -import org.assertj.core.api.AbstractObjectAssert; - -public class TinkerPathAssert extends AbstractAssert { - - public TinkerPathAssert(Path actual) { - super(actual, TinkerPathAssert.class); - } - - /** - * Ensures that the given Path matches one of the exact traversals we'd expect for a person whom - * Marko knows that has created software and what software that is. - * - *

These paths should be: - * - *

    - *
  • marko -> knows -> josh -> created -> lop - *
  • marko -> knows -> josh -> created -> ripple - *
- */ - public static void validatePathObjects(Path path) { - - // marko should be the origin point. - TinkerGraphAssertions.assertThat(path).vertexAt(0).hasLabel("person"); - - // there should be a 'knows' outgoing relationship between marko and josh. - TinkerGraphAssertions.assertThat(path) - .edgeAt(1) - .hasLabel("knows") - .hasOutVLabel("person") - .hasOutV((Vertex) path.objects().get(0)) - .hasInVLabel("person") - .hasInV((Vertex) path.objects().get(2)); - - // josh... - TinkerGraphAssertions.assertThat(path).vertexAt(2).hasLabel("person"); - - // there should be a 'created' relationship between josh and lop. - TinkerGraphAssertions.assertThat(path) - .edgeAt(3) - .hasLabel("created") - .hasOutVLabel("person") - .hasOutV((Vertex) path.objects().get(2)) - .hasInVLabel("software") - .hasInV((Vertex) path.objects().get(4)); - - // lop.. - TinkerGraphAssertions.assertThat(path).vertexAt(4).hasLabel("software"); - } - - public AbstractObjectAssert objectAt(int i) { - assertThat(actual.size()).isGreaterThanOrEqualTo(i); - return assertThat(actual.objects().get(i)); - } - - public TinkerVertexAssert vertexAt(int i) { - assertThat(actual.size()).isGreaterThanOrEqualTo(i); - Object o = actual.objects().get(i); - assertThat(o).isInstanceOf(Vertex.class); - return new TinkerVertexAssert((Vertex) o); - } - - public TinkerEdgeAssert edgeAt(int i) { - assertThat(actual.size()).isGreaterThanOrEqualTo(i); - Object o = actual.objects().get(i); - assertThat(o).isInstanceOf(Edge.class); - return new TinkerEdgeAssert((Edge) o); - } - - public TinkerPathAssert hasLabel(int i, String... labels) { - assertThat(actual.labels().size()).isGreaterThanOrEqualTo(i); - assertThat(actual.labels().get(i)).containsExactly(labels); - return myself; - } - - public TinkerPathAssert hasNoLabel(int i) { - assertThat(actual.labels().size()).isGreaterThanOrEqualTo(i); - assertThat(actual.labels().get(i)).isEmpty(); - return myself; - } - - public TinkerPathAssert doesNotHaveLabel(String label) { - assertThat(actual.hasLabel(label)).isFalse(); - return myself; - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/TinkerTreeAssert.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/TinkerTreeAssert.java deleted file mode 100644 index 6196e0a1021..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/TinkerTreeAssert.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree; -import org.assertj.core.api.MapAssert; - -public class TinkerTreeAssert extends MapAssert> { - - public TinkerTreeAssert(Tree actual) { - super(actual); - } - - public TinkerTreeAssert hasTree(T key) { - assertThat(actual).containsKey(key); - return this; - } - - public TinkerTreeAssert isLeaf() { - assertThat(actual).hasSize(0); - return this; - } - - public TinkerTreeAssert tree(T key) { - hasTree(key); - return new TinkerTreeAssert<>(actual.get(key)); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/TinkerVertexAssert.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/TinkerVertexAssert.java deleted file mode 100644 index 3777fc8e96a..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/TinkerVertexAssert.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.apache.tinkerpop.gremlin.structure.Property; -import org.apache.tinkerpop.gremlin.structure.Vertex; - -public class TinkerVertexAssert extends TinkerElementAssert { - - public TinkerVertexAssert(Vertex actual) { - super(actual, TinkerVertexAssert.class); - } - - @Override - public TinkerVertexAssert hasProperty(String propertyName) { - assertThat(actual.properties(propertyName)).toIterable().isNotEmpty(); - return myself; - } - - @Override - public TinkerVertexAssert hasProperty(String propertyName, Object value) { - hasProperty(propertyName); - assertThat(actual.properties(propertyName)) - .toIterable() - .extracting(Property::value) - .contains(value); - return myself; - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/TinkerVertexPropertyAssert.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/TinkerVertexPropertyAssert.java deleted file mode 100644 index 40bb8b5e239..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/TinkerVertexPropertyAssert.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.apache.tinkerpop.gremlin.structure.Element; -import org.apache.tinkerpop.gremlin.structure.VertexProperty; - -public class TinkerVertexPropertyAssert - extends TinkerElementAssert, VertexProperty> { - - public TinkerVertexPropertyAssert(VertexProperty actual) { - super(actual, TinkerVertexPropertyAssert.class); - } - - public TinkerVertexPropertyAssert hasKey(String key) { - assertThat(actual.key()).isEqualTo(key); - return this; - } - - public TinkerVertexPropertyAssert hasParent(Element parent) { - assertThat(actual.element()).isEqualTo(parent); - return this; - } - - public TinkerVertexPropertyAssert hasValue(T value) { - assertThat(actual.value()).isEqualTo(value); - return this; - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/reactive/DefaultReactiveGraphResultSetIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/reactive/DefaultReactiveGraphResultSetIT.java deleted file mode 100644 index b4c8bb05df4..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/reactive/DefaultReactiveGraphResultSetIT.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph.reactive; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.dse.driver.api.core.graph.ScriptGraphStatement; -import com.datastax.dse.driver.internal.core.graph.GraphProtocol; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.cql.ExecutionInfo; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import io.reactivex.Flowable; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; -import org.junit.runner.RunWith; - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "6.8.0", - description = "Graph paging requires DSE 6.8+") -@RunWith(DataProviderRunner.class) -public class DefaultReactiveGraphResultSetIT { - - private static CustomCcmRule ccmRule = CustomCcmRule.builder().withDseWorkloads("graph").build(); - - private static SessionRule sessionRule = - SessionRule.builder(ccmRule) - .withCreateGraph() - .withCoreEngine() - .withGraphProtocol(GraphProtocol.GRAPH_BINARY_1_0.toInternalCode()) - .build(); - - @ClassRule public static TestRule chain = RuleChain.outerRule(ccmRule).around(sessionRule); - - @BeforeClass - public static void setupSchema() { - sessionRule - .session() - .execute( - ScriptGraphStatement.newInstance( - "schema.vertexLabel('person')" - + ".partitionBy('pk', Int)" - + ".clusterBy('cc', Int)" - + ".property('name', Text)" - + ".create();") - .setGraphName(sessionRule.getGraphName())); - for (int i = 1; i <= 1000; i++) { - sessionRule - .session() - .execute( - ScriptGraphStatement.newInstance( - String.format( - "g.addV('person').property('pk',0).property('cc',%d).property('name', '%s');", - i, "user" + i)) - .setGraphName(sessionRule.getGraphName())); - } - } - - @Test - @DataProvider( - value = {"1", "10", "100", "999", "1000", "1001", "2000"}, - format = "%m [page size %p[0]]") - public void should_retrieve_all_rows(int pageSize) { - DriverExecutionProfile profile = - sessionRule - .session() - .getContext() - .getConfig() - .getDefaultProfile() - .withInt(DseDriverOption.GRAPH_CONTINUOUS_PAGING_PAGE_SIZE, pageSize); - ScriptGraphStatement statement = - ScriptGraphStatement.builder("g.V()").setExecutionProfile(profile).build(); - ReactiveGraphResultSet rs = sessionRule.session().executeReactive(statement); - List results = Flowable.fromPublisher(rs).toList().blockingGet(); - assertThat(results.size()).isEqualTo(1000); - Set expectedExecInfos = new LinkedHashSet<>(); - for (ReactiveGraphNode row : results) { - assertThat(row.getExecutionInfo()).isNotNull(); - assertThat(row.isVertex()).isTrue(); - expectedExecInfos.add(row.getExecutionInfo()); - } - List execInfos = - Flowable.fromPublisher(rs.getExecutionInfos()).toList().blockingGet(); - // DSE may send an empty page as it can't always know if it's done paging or not yet. - // See: CASSANDRA-8871. In this case, this page's execution info appears in - // rs.getExecutionInfos(), but is not present in expectedExecInfos since the page did not - // contain any rows. - assertThat(execInfos).containsAll(expectedExecInfos); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/remote/ClassicGraphDataTypeRemoteIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/remote/ClassicGraphDataTypeRemoteIT.java deleted file mode 100644 index b57d7a952bc..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/remote/ClassicGraphDataTypeRemoteIT.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph.remote; - -import com.datastax.dse.driver.api.core.graph.ClassicGraphDataTypeITBase; -import com.datastax.dse.driver.api.core.graph.DseGraph; -import com.datastax.dse.driver.api.core.graph.GraphTestSupport; -import com.datastax.dse.driver.api.core.graph.SampleGraphScripts; -import com.datastax.dse.driver.api.core.graph.ScriptGraphStatement; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "5.0.3", - description = "DSE 5.0.3 required for remote TinkerPop support") -public class ClassicGraphDataTypeRemoteIT extends ClassicGraphDataTypeITBase { - - private static final CustomCcmRule CCM_RULE = GraphTestSupport.GRAPH_CCM_RULE_BUILDER.build(); - - private static final SessionRule SESSION_RULE = - GraphTestSupport.getClassicGraphSessionBuilder(CCM_RULE).build(); - - @ClassRule - public static final TestRule CHAIN = RuleChain.outerRule(CCM_RULE).around(SESSION_RULE); - - @BeforeClass - public static void setupSchema() { - SESSION_RULE - .session() - .execute(ScriptGraphStatement.newInstance(SampleGraphScripts.ALLOW_SCANS)); - SESSION_RULE - .session() - .execute(ScriptGraphStatement.newInstance(SampleGraphScripts.MAKE_STRICT)); - } - - @Override - public CqlSession session() { - return SESSION_RULE.session(); - } - - private final GraphTraversalSource g = - AnonymousTraversalSource.traversal() - .withRemote(DseGraph.remoteConnectionBuilder(SESSION_RULE.session()).build()); - - @Override - public Vertex insertVertexAndReturn(String vertexLabel, String propertyName, Object value) { - return g.addV(vertexLabel).property(propertyName, value).next(); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/remote/ClassicGraphTraversalRemoteIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/remote/ClassicGraphTraversalRemoteIT.java deleted file mode 100644 index de85b6af267..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/remote/ClassicGraphTraversalRemoteIT.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph.remote; - -import static org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource.traversal; - -import com.datastax.dse.driver.api.core.graph.DseGraph; -import com.datastax.dse.driver.api.core.graph.GraphTestSupport; -import com.datastax.dse.driver.api.core.graph.SampleGraphScripts; -import com.datastax.dse.driver.api.core.graph.ScriptGraphStatement; -import com.datastax.dse.driver.api.core.graph.SocialTraversalSource; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "5.0.9", - description = "DSE 5.0.9 required for inserting edges and vertices script.") -public class ClassicGraphTraversalRemoteIT extends GraphTraversalRemoteITBase { - - private static final CustomCcmRule CCM_RULE = GraphTestSupport.GRAPH_CCM_RULE_BUILDER.build(); - - private static final SessionRule SESSION_RULE = - GraphTestSupport.getClassicGraphSessionBuilder(CCM_RULE).build(); - - @ClassRule - public static final TestRule CHAIN = RuleChain.outerRule(CCM_RULE).around(SESSION_RULE); - - @BeforeClass - public static void setupSchema() { - SESSION_RULE - .session() - .execute(ScriptGraphStatement.newInstance(SampleGraphScripts.ALLOW_SCANS)); - SESSION_RULE - .session() - .execute(ScriptGraphStatement.newInstance(SampleGraphScripts.CLASSIC_GRAPH)); - SESSION_RULE - .session() - .execute(ScriptGraphStatement.newInstance(SampleGraphScripts.MAKE_STRICT)); - } - - @Override - protected CqlSession session() { - return SESSION_RULE.session(); - } - - @Override - protected boolean isGraphBinary() { - return false; - } - - @Override - protected GraphTraversalSource graphTraversalSource() { - return traversal().withRemote(DseGraph.remoteConnectionBuilder(session()).build()); - } - - @Override - protected SocialTraversalSource socialTraversalSource() { - return traversal(SocialTraversalSource.class) - .withRemote(DseGraph.remoteConnectionBuilder(session()).build()); - } - - @Override - protected CustomCcmRule ccmRule() { - return CCM_RULE; - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/remote/CoreGraphDataTypeRemoteIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/remote/CoreGraphDataTypeRemoteIT.java deleted file mode 100644 index 88b9cdc0433..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/remote/CoreGraphDataTypeRemoteIT.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph.remote; - -import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.unfold; - -import com.datastax.dse.driver.api.core.graph.CoreGraphDataTypeITBase; -import com.datastax.dse.driver.api.core.graph.DseGraph; -import com.datastax.dse.driver.api.core.graph.GraphTestSupport; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import java.util.Map; -import org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.junit.ClassRule; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; -import org.junit.runner.RunWith; - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "6.8.0", - description = "DSE 6.8.0 required for Core graph support") -@RunWith(DataProviderRunner.class) -public class CoreGraphDataTypeRemoteIT extends CoreGraphDataTypeITBase { - - private static final CustomCcmRule CCM_RULE = GraphTestSupport.CCM_BUILDER_WITH_GRAPH.build(); - - private static final SessionRule SESSION_RULE = - GraphTestSupport.getCoreGraphSessionBuilder(CCM_RULE).build(); - - @ClassRule - public static final TestRule CHAIN = RuleChain.outerRule(CCM_RULE).around(SESSION_RULE); - - @Override - protected CqlSession session() { - return SESSION_RULE.session(); - } - - @Override - protected String graphName() { - return SESSION_RULE.getGraphName(); - } - - private final GraphTraversalSource g = - AnonymousTraversalSource.traversal() - .withRemote(DseGraph.remoteConnectionBuilder(session()).build()); - - @Override - public Map insertVertexThenReadProperties( - Map properties, int vertexID, String vertexLabel) { - GraphTraversal traversal = g.addV(vertexLabel).property("id", vertexID); - - for (Map.Entry entry : properties.entrySet()) { - String typeDefinition = entry.getKey(); - String propName = formatPropertyName(typeDefinition); - Object value = entry.getValue(); - traversal = traversal.property(propName, value); - } - - // insert vertex - traversal.iterate(); - - // query properties - return g.V().has(vertexLabel, "id", vertexID).valueMap().by(unfold()).next(); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/remote/CoreGraphTraversalRemoteIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/remote/CoreGraphTraversalRemoteIT.java deleted file mode 100644 index 2bbdf1f6d45..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/remote/CoreGraphTraversalRemoteIT.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph.remote; - -import static org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource.traversal; - -import com.datastax.dse.driver.api.core.graph.DseGraph; -import com.datastax.dse.driver.api.core.graph.GraphTestSupport; -import com.datastax.dse.driver.api.core.graph.SampleGraphScripts; -import com.datastax.dse.driver.api.core.graph.ScriptGraphStatement; -import com.datastax.dse.driver.api.core.graph.SocialTraversalSource; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "6.8", - description = "DSE 6.8 required for Core graph support") -public class CoreGraphTraversalRemoteIT extends GraphTraversalRemoteITBase { - - private static final CustomCcmRule CCM_RULE = GraphTestSupport.GRAPH_CCM_RULE_BUILDER.build(); - - private static final SessionRule SESSION_RULE = - GraphTestSupport.getCoreGraphSessionBuilder(CCM_RULE).build(); - - @ClassRule - public static final TestRule CHAIN = RuleChain.outerRule(CCM_RULE).around(SESSION_RULE); - - @BeforeClass - public static void setupSchema() { - SESSION_RULE.session().execute(ScriptGraphStatement.newInstance(SampleGraphScripts.CORE_GRAPH)); - } - - @Override - protected CqlSession session() { - return SESSION_RULE.session(); - } - - @Override - protected boolean isGraphBinary() { - return true; - } - - @Override - protected GraphTraversalSource graphTraversalSource() { - return traversal() - .withRemote(DseGraph.remoteConnectionBuilder(session()).build()) - .with("allow-filtering"); - } - - @Override - protected SocialTraversalSource socialTraversalSource() { - return traversal(SocialTraversalSource.class) - .withRemote(DseGraph.remoteConnectionBuilder(session()).build()) - .with("allow-filtering"); - } - - @Override - protected CustomCcmRule ccmRule() { - return CCM_RULE; - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/remote/GraphTraversalMetaPropertiesRemoteIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/remote/GraphTraversalMetaPropertiesRemoteIT.java deleted file mode 100644 index 2966fb44cf9..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/remote/GraphTraversalMetaPropertiesRemoteIT.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph.remote; - -import static com.datastax.dse.driver.api.core.graph.SampleGraphScripts.ALLOW_SCANS; -import static com.datastax.dse.driver.api.core.graph.SampleGraphScripts.MAKE_STRICT; -import static com.datastax.dse.driver.api.core.graph.TinkerGraphAssertions.assertThat; - -import com.datastax.dse.driver.api.core.graph.DseGraph; -import com.datastax.dse.driver.api.core.graph.GraphTestSupport; -import com.datastax.dse.driver.api.core.graph.ScriptGraphStatement; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.apache.tinkerpop.gremlin.structure.VertexProperty; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; - -// INFO: meta props are going away in NGDG - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "5.0.3", - description = "DSE 5.0.3 required for remote TinkerPop support") -public class GraphTraversalMetaPropertiesRemoteIT { - - private static final CustomCcmRule CCM_RULE = GraphTestSupport.GRAPH_CCM_RULE_BUILDER.build(); - - private static final SessionRule SESSION_RULE = - GraphTestSupport.getClassicGraphSessionBuilder(CCM_RULE).build(); - - @ClassRule - public static final TestRule CHAIN = RuleChain.outerRule(CCM_RULE).around(SESSION_RULE); - - private final GraphTraversalSource g = - AnonymousTraversalSource.traversal() - .withRemote(DseGraph.remoteConnectionBuilder(SESSION_RULE.session()).build()); - - /** Builds a simple schema that provides for a vertex with a property with sub properties. */ - public static final String META_PROPS = - MAKE_STRICT - + ALLOW_SCANS - + "schema.propertyKey('sub_prop').Text().create()\n" - + "schema.propertyKey('sub_prop2').Text().create()\n" - + "schema.propertyKey('meta_prop').Text().properties('sub_prop', 'sub_prop2').create()\n" - + "schema.vertexLabel('meta_v').properties('meta_prop').create()"; - - /** - * Ensures that a traversal that yields a vertex with a property that has its own properties that - * is appropriately parsed and made accessible via {@link VertexProperty#property}. - * - * @test_category dse:graph - */ - @Test - public void should_parse_meta_properties() { - // given a schema that defines meta properties. - SESSION_RULE.session().execute(ScriptGraphStatement.newInstance(META_PROPS)); - - // when adding a vertex with that meta property - Vertex v = - g.addV("meta_v") - .property("meta_prop", "hello", "sub_prop", "hi", "sub_prop2", "hi2") - .next(); - - // then the created vertex should have the meta prop present with its sub properties. - assertThat(v).hasProperty("meta_prop"); - VertexProperty metaProp = v.property("meta_prop"); - assertThat(metaProp) - .hasValue("hello") - .hasProperty("sub_prop", "hi") - .hasProperty("sub_prop2", "hi2"); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/remote/GraphTraversalMultiPropertiesRemoteIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/remote/GraphTraversalMultiPropertiesRemoteIT.java deleted file mode 100644 index c55a7b67c4a..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/remote/GraphTraversalMultiPropertiesRemoteIT.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph.remote; - -import static com.datastax.dse.driver.api.core.graph.SampleGraphScripts.ALLOW_SCANS; -import static com.datastax.dse.driver.api.core.graph.SampleGraphScripts.MAKE_STRICT; -import static com.datastax.dse.driver.api.core.graph.TinkerGraphAssertions.assertThat; - -import com.datastax.dse.driver.api.core.graph.DseGraph; -import com.datastax.dse.driver.api.core.graph.GraphTestSupport; -import com.datastax.dse.driver.api.core.graph.ScriptGraphStatement; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import java.util.Iterator; -import org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.apache.tinkerpop.gremlin.structure.VertexProperty; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; - -// INFO: multi props are not supported in Core -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "5.0.3", - description = "DSE 5.0.3 required for remote TinkerPop support") -public class GraphTraversalMultiPropertiesRemoteIT { - - private static final CustomCcmRule CCM_RULE = GraphTestSupport.GRAPH_CCM_RULE_BUILDER.build(); - - private static final SessionRule SESSION_RULE = - GraphTestSupport.getClassicGraphSessionBuilder(CCM_RULE).build(); - - @ClassRule - public static final TestRule CHAIN = RuleChain.outerRule(CCM_RULE).around(SESSION_RULE); - - private final GraphTraversalSource g = - AnonymousTraversalSource.traversal() - .withRemote(DseGraph.remoteConnectionBuilder(SESSION_RULE.session()).build()); - - /** Builds a simple schema that provides for a vertex with a multi-cardinality property. */ - public static final String MULTI_PROPS = - MAKE_STRICT - + ALLOW_SCANS - + "schema.propertyKey('multi_prop').Text().multiple().create()\n" - + "schema.vertexLabel('multi_v').properties('multi_prop').create()\n"; - - /** - * Ensures that a traversal that yields a vertex with a property name that is present multiple - * times that the properties are parsed and made accessible via {@link - * Vertex#properties(String...)}. - * - * @test_category dse:graph - */ - @Test - public void should_parse_multiple_cardinality_properties() { - // given a schema that defines multiple cardinality properties. - SESSION_RULE.session().execute(ScriptGraphStatement.newInstance(MULTI_PROPS)); - - // when adding a vertex with a multiple cardinality property - Vertex v = - g.addV("multi_v") - .property("multi_prop", "Hello") - .property("multi_prop", "Sweet") - .property("multi_prop", "World") - .next(); - - // then the created vertex should have the multi-cardinality property present with its values. - assertThat(v).hasProperty("multi_prop"); - Iterator> multiProp = v.properties("multi_prop"); - assertThat(multiProp) - .toIterable() - .extractingResultOf("value") - .containsExactly("Hello", "Sweet", "World"); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/remote/GraphTraversalRemoteITBase.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/remote/GraphTraversalRemoteITBase.java deleted file mode 100644 index 3db8a7d1a12..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/remote/GraphTraversalRemoteITBase.java +++ /dev/null @@ -1,661 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph.remote; - -import static com.datastax.dse.driver.api.core.graph.TinkerGraphAssertions.assertThat; -import static com.datastax.dse.driver.internal.core.graph.GraphTestUtils.assertThatContainsLabel; -import static com.datastax.dse.driver.internal.core.graph.GraphTestUtils.assertThatContainsProperties; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.assertj.core.api.Assertions.fail; - -import com.datastax.dse.driver.Assertions; -import com.datastax.dse.driver.api.core.graph.SocialTraversalSource; -import com.datastax.dse.driver.api.core.graph.TinkerPathAssert; -import com.datastax.dse.driver.api.core.graph.__; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.Version; -import com.datastax.oss.driver.api.core.servererrors.InvalidQueryException; -import com.datastax.oss.driver.api.testinfra.ccm.CcmBridge; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.stream.Collectors; -import org.apache.tinkerpop.gremlin.process.traversal.Path; -import org.apache.tinkerpop.gremlin.process.traversal.Traversal; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree; -import org.apache.tinkerpop.gremlin.structure.Direction; -import org.apache.tinkerpop.gremlin.structure.Edge; -import org.apache.tinkerpop.gremlin.structure.Graph; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.assertj.core.api.Assumptions; -import org.junit.Test; - -public abstract class GraphTraversalRemoteITBase { - - protected abstract CqlSession session(); - - protected abstract boolean isGraphBinary(); - - protected abstract GraphTraversalSource graphTraversalSource(); - - protected abstract SocialTraversalSource socialTraversalSource(); - - protected abstract CustomCcmRule ccmRule(); - - /** - * Ensures that a previously returned {@link Vertex}'s {@link Vertex#id()} can be used as an input - * to {@link - * org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource#V(Object...)} to - * retrieve the {@link Vertex} and that the returned {@link Vertex} is the same. - * - * @test_category dse:graph - */ - @Test - public void should_use_vertex_id_as_parameter() { - GraphTraversalSource g = graphTraversalSource(); - - // given an existing vertex - Vertex marko = g.V().hasLabel("person").has("name", "marko").next(); - if (isGraphBinary()) { - Map properties = - g.V().hasLabel("person").has("name", "marko").elementMap("name").next(); - - assertThat(properties).containsEntry("name", "marko"); - } else { - assertThat(marko).hasProperty("name", "marko"); - } - - // then should be able to retrieve that same vertex by id. - assertThat(g.V(marko.id()).next()).isEqualTo(marko); - } - - /** - * Ensures that a previously returned {@link Edge}'s {@link Edge#id()} can be used as an input to - * {@link - * org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource#E(Object...)} to - * retrieve the {@link Edge} and that the returned {@link Edge} is the same. - * - * @test_category dse:graph - */ - @Test - public void should_use_edge_is_as_parameter() { - GraphTraversalSource g = graphTraversalSource(); - - // given an existing edge - Edge created = g.E().has("weight", 0.2f).next(); - - if (isGraphBinary()) { - List> properties = - g.E().has("weight").elementMap("weight", "software", "person").toList(); - - assertThat(properties) - .anySatisfy( - props -> { - assertThatContainsProperties(props, "weight", 0.2f); - assertThatContainsLabel(props, Direction.IN, "software"); - assertThatContainsLabel(props, Direction.OUT, "person"); - }); - - } else { - assertThat(created) - .hasProperty("weight", 0.2f) - .hasInVLabel("software") - .hasOutVLabel("person"); - } - - // should be able to retrieve incoming and outgoing vertices by edge id - if (isGraphBinary()) { - Map inProperties = g.E(created.id()).inV().elementMap("name", "lang").next(); - Map outProperties = g.E(created.id()).outV().elementMap("name").next(); - assertThatContainsProperties(inProperties, "name", "lop", "lang", "java"); - assertThatContainsProperties(outProperties, "name", "peter"); - - } else { - Vertex in = g.E(created.id()).inV().next(); - Vertex out = g.E(created.id()).outV().next(); - - // should resolve to lop - assertThat(in).hasLabel("software").hasProperty("name", "lop").hasProperty("lang", "java"); - - // should resolve to marko, josh and peter whom created lop. - assertThat(out).hasLabel("person").hasProperty("name", "peter"); - } - } - - /** - * A sanity check that a returned {@link Vertex}'s id is a {@link Map}. This test could break in - * the future if the format of a vertex ID changes from a Map to something else in DSE. - * - * @test_category dse:graph - */ - @Test - public void should_deserialize_vertex_id_as_map() { - GraphTraversalSource g = graphTraversalSource(); - // given an existing vertex - Vertex marko = g.V().hasLabel("person").has("name", "marko").next(); - - // then id should be a map with expected values. - // Note: this is pretty dependent on DSE Graphs underlying id structure which may vary in - // the future. - if (isGraphBinary()) { - assertThat(((String) marko.id())).contains("marko"); - assertThat(marko.label()).isEqualTo("person"); - } else { - @SuppressWarnings("unchecked") - Map id = (Map) marko.id(); - assertThat(id) - .hasSize(3) - .containsEntry("~label", "person") - .containsKey("community_id") - .containsKey("member_id"); - } - } - - /** - * Ensures that a traversal that returns a result of mixed types is interpreted as a {@link Map} - * with {@link Object} values. Also uses {@link - * org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal#by(Traversal)} with an - * anonymous traversal to get inbound 'created' edges and folds them into a list. - * - *

Executes a vertex traversal that binds label 'a' and 'b' to vertex properties and label 'c' - * to vertices that have edges from that vertex. - * - * @test_category dse:graph - */ - @Test - public void should_handle_result_object_of_mixed_types() { - GraphTraversalSource g = graphTraversalSource(); - // find all software vertices and select name, language, and find all vertices that created - // such software. - List> results = - g.V() - .hasLabel("software") - .as("a", "b", "c") - .select("a", "b", "c") - .by("name") - .by("lang") - .by(__.in("created").fold()) - .toList(); - - // ensure that lop and ripple and their data are the results return. - assertThat(results).extracting(m -> m.get("a")).containsOnly("lop", "ripple"); - - for (Map result : results) { - assertThat(result).containsOnlyKeys("a", "b", "c"); - // both software are written in java. - assertThat(result.get("b")).isEqualTo("java"); - // ensure the created vertices match the creators of the software. - @SuppressWarnings("unchecked") - List vertices = (List) result.get("c"); - if (result.get("a").equals("lop")) { - if (isGraphBinary()) { - // should contain three vertices - assertThat(vertices.size()).isEqualTo(3); - } else { - // lop, 'c' should contain marko, josh, peter. - assertThat(vertices) - .extracting(vertex -> vertex.property("name").value()) - .containsOnly("marko", "josh", "peter"); - } - } else { - if (isGraphBinary()) { - // has only one label - assertThat(vertices.size()).isEqualTo(1); - } else { - assertThat(vertices) - .extracting(vertex -> vertex.property("name").value()) - .containsOnly("josh"); - } - } - } - } - - /** - * Ensures that a traversal that returns a sub graph can be retrieved. - * - *

The subgraph is all members in a knows relationship, thus is all people who marko knows and - * the edges that connect them. - */ - @Test - public void should_handle_subgraph_graphson() { - Assumptions.assumeThat(isGraphBinary()).isFalse(); - - GraphTraversalSource g = graphTraversalSource(); - // retrieve a subgraph on the knows relationship, this omits the created edges. - Graph graph = (Graph) g.E().hasLabel("knows").subgraph("subGraph").cap("subGraph").next(); - - // there should only be 2 edges (since there are are only 2 knows relationships) and 3 vertices - assertThat(graph.edges()).toIterable().hasSize(2); - assertThat(graph.vertices()).toIterable().hasSize(3); - } - - /** - * Ensures that a traversal that returns a sub graph can be retrieved. - * - *

The subgraph is all members in a knows relationship, thus is all people who marko knows and - * the edges that connect them. - */ - @Test - public void should_handle_subgraph_graph_binary() { - Assumptions.assumeThat(isGraphBinary()).isTrue(); - - GraphTraversalSource g = graphTraversalSource(); - // retrieve a subgraph on the knows relationship, this omits the created edges. - String graph = (String) g.E().hasLabel("knows").subgraph("subGraph").cap("subGraph").next(); - - // there should only be 2 edges (since there are are only 2 knows relationships) and 3 vertices - assertThat(graph).contains("vertices:3").contains("edges:2"); - } - - /** - * Ensures a traversal that yields no results is properly retrieved and is empty. - * - * @test_category dse:graph - */ - @Test - public void should_return_zero_results() { - if (isGraphBinary()) { - assertThatThrownBy(() -> graphTraversalSource().V().hasLabel("notALabel").toList()) - .isInstanceOf(InvalidQueryException.class) - .hasMessageContaining("Unknown vertex label 'notALabel'"); - } else { - assertThat(graphTraversalSource().V().hasLabel("notALabel").toList()).isEmpty(); - } - } - - /** - * Validates that a traversal returning a {@link Tree} structure is returned appropriately with - * the expected contents. - * - *

Retrieves trees of people marko knows and the software they created. - * - * @test_category dse:graph - */ - @Test - public void should_parse_tree() { - // Get a tree structure showing the paths from mark to people he knows to software they've - // created. - @SuppressWarnings("unchecked") - Tree tree = - graphTraversalSource() - .V() - .hasLabel("person") - .out("knows") - .out("created") - .tree() - .by("name") - .next(); - - // Marko knows josh who created lop and ripple. - assertThat(tree).tree("marko").tree("josh").tree("lop").isLeaf(); - - assertThat(tree).tree("marko").tree("josh").tree("ripple").isLeaf(); - } - - /** - * Validates that a traversal using lambda operations with anonymous traversals are applied - * appropriately and return the expected results. - * - *

Traversal that filters 'person'-labeled vertices by name 'marko' and flatMaps outgoing - * vertices on the 'knows' relationship by their outgoing 'created' vertices and then maps by - * their 'name' property and folds them into one list. - * - *

Note: This does not validate lambdas with functions as those can't be interpreted and - * sent remotely. - * - * @test_category dse:graph - */ - @Test - public void should_handle_lambdas() { - // Find all people marko knows and the software they created. - List software = - graphTraversalSource() - .V() - .hasLabel("person") - .filter(__.has("name", "marko")) - .out("knows") - .flatMap(__.out("created")) - .map(__.values("name")) - .fold() - .next(); - - // Marko only knows josh and vadas, of which josh created lop and ripple. - assertThat(software).containsOnly("lop", "ripple"); - } - - /** - * Validates that {@link - * org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal#tryNext()} functions - * appropriate by returning an {@link Optional} of which the presence of the underlying data - * depends on whether or not remaining data is present. - * - *

This is more of a test of Tinkerpop than the protocol between the client and DSE graph. - * - * @test_category dse:graph - */ - @Test - public void should_handle_tryNext() { - GraphTraversal traversal = - graphTraversalSource().V().hasLabel("person").has("name", "marko"); - - // value present - Optional v0 = traversal.tryNext(); - assertThat(v0.isPresent()).isTrue(); - if (!isGraphBinary()) { - assertThat(v0.get()).hasProperty("name", "marko"); - } - - // value absent as there was only 1 matching vertex. - Optional v1 = traversal.tryNext(); - assertThat(v1.isPresent()).isFalse(); - } - - /** - * Validates that {@link GraphTraversal#toStream()} appropriately creates a stream from the - * underlying iterator on the traversal, and then an attempt to call toStream again yields no - * results. - * - *

This is more of a test of Tinkerpop than the protocol between the client and DSE graph. - * - * @test_category dse:graph - */ - @Test - public void should_handle_streaming_graphson() { - Assumptions.assumeThat(isGraphBinary()).isFalse(); - - GraphTraversal traversal = graphTraversalSource().V().hasLabel("person"); - // retrieve all person vertices to stream, and filter on client side all persons under age 30 - // and map to their name. - List under30 = - traversal - .toStream() - .filter(v -> v.property("age").value() < 30) - .map(v -> v.property("name").value()) - .collect(Collectors.toList()); - - assertThat(under30).containsOnly("marko", "vadas"); - - // attempt to get a stream again, which should be empty. - assertThat(traversal.toStream().collect(Collectors.toList())).isEmpty(); - } - - /** - * Validates that {@link GraphTraversal#toStream()} appropriately creates a stream from the - * underlying iterator on the traversal, and then an attempt to call toStream again yields no - * results. - * - *

This is more of a test of Tinkerpop than the protocol between the client and DSE graph. - * - * @test_category dse:graph - */ - @Test - public void should_handle_streaming_binary() { - Assumptions.assumeThat(isGraphBinary()).isTrue(); - - GraphTraversal> traversal = - graphTraversalSource().V().hasLabel("person").elementMap("age", "name"); - // retrieve all person vertices to stream, and filter on client side all persons under age 30 - // and map to their name. - List under30 = - traversal - .toStream() - .filter(v -> (Integer) v.get("age") < 30) - .map(v -> (String) v.get("name")) - .collect(Collectors.toList()); - - assertThat(under30).containsOnly("marko", "vadas"); - - // attempt to get a stream again, which should be empty. - assertThat(traversal.toStream().collect(Collectors.toList())).isEmpty(); - } - - /** - * Validates that when traversing a path and labeling some of the elements during the traversal - * that the output elements are properly labeled. - * - * @test_category dse:graph - */ - @Test - public void should_resolve_path_with_some_labels() { - // given a traversal where some objects have labels. - List paths = - graphTraversalSource() - .V() - .hasLabel("person") - .has("name", "marko") - .as("a") - .outE("knows") - .inV() - .as("c", "d") - .outE("created") - .as("e", "f", "g") - .inV() - .path() - .toList(); - - // then the paths returned should be labeled for the - // appropriate objects, and not labeled otherwise. - for (Path path : paths) { - TinkerPathAssert.validatePathObjects(path); - assertThat(path) - .hasLabel(0, "a") - .hasNoLabel(1) - .hasLabel(2, "c", "d") - .hasLabel(3, "e", "f", "g") - .hasNoLabel(4); - } - } - - /** - * Validates that when traversing a path and labeling all of the elements during the traversal - * that the output elements are properly labeled. - * - * @test_category dse:graph - */ - @Test - public void should_resolve_path_with_labels() { - // given a traversal where all objects have labels. - List paths = - graphTraversalSource() - .V() - .hasLabel("person") - .has("name", "marko") - .as("a") - .outE("knows") - .as("b") - .inV() - .as("c", "d") - .outE("created") - .as("e", "f", "g") - .inV() - .as("h") - .path() - .toList(); - - // then the paths returned should be labeled for all - // objects. - for (Path path : paths) { - TinkerPathAssert.validatePathObjects(path); - Assertions.assertThat(path.labels()).hasSize(5); - assertThat(path) - .hasLabel(0, "a") - .hasLabel(1, "b") - .hasLabel(2, "c", "d") - .hasLabel(3, "e", "f", "g") - .hasLabel(4, "h"); - } - } - - /** - * Validates that when traversing a path and labeling none of the elements during the traversal - * that all the labels are empty in the result. - * - * @test_category dse:graph - */ - @Test - public void should_resolve_path_without_labels() { - // given a traversal where no objects have labels. - List paths = - graphTraversalSource() - .V() - .hasLabel("person") - .has("name", "marko") - .outE("knows") - .inV() - .outE("created") - .inV() - .path() - .toList(); - - // then the paths returned should be labeled for - // all objects. - for (Path path : paths) { - TinkerPathAssert.validatePathObjects(path); - for (int i = 0; i < 5; i++) assertThat(path).hasNoLabel(i); - } - } - - @Test - public void should_handle_asynchronous_execution_graphson() { - Assumptions.assumeThat(isGraphBinary()).isFalse(); - - StringBuilder names = new StringBuilder(); - - CompletableFuture> future = - graphTraversalSource().V().hasLabel("person").promise(Traversal::toList); - try { - // dumb processing to make sure the completable future works correctly and correct results are - // returned - future - .thenAccept( - vertices -> vertices.forEach(vertex -> names.append((String) vertex.value("name")))) - .get(); - } catch (InterruptedException | ExecutionException e) { - fail("Shouldn't have thrown an exception waiting for the result to complete"); - } - - assertThat(names.toString()).contains("peter", "marko", "vadas", "josh"); - } - - @Test - public void should_handle_asynchronous_execution_graph_binary() { - Assumptions.assumeThat(isGraphBinary()).isTrue(); - - StringBuilder names = new StringBuilder(); - - CompletableFuture> future = - graphTraversalSource().V().hasLabel("person").promise(Traversal::toList); - try { - // dumb processing to make sure the completable future works correctly and correct results are - // returned - future.thenAccept(vertices -> vertices.forEach(vertex -> names.append(vertex.id()))).get(); - } catch (InterruptedException | ExecutionException e) { - fail("Shouldn't have thrown an exception waiting for the result to complete"); - } - - assertThat(names.toString()).contains("peter", "marko", "vadas", "josh"); - } - - /** - * Validates that if a traversal is made that encounters an error on the server side that the - * exception is set on the future. - * - * @test_category dse:graph - */ - @Test - @BackendRequirement(type = BackendType.DSE, minInclusive = "5.1.0") - public void should_fail_future_returned_from_promise_on_query_error() throws Exception { - CompletableFuture future = - graphTraversalSource().V("invalidid").peerPressure().promise(Traversal::next); - - try { - future.get(); - fail("Expected an ExecutionException"); - } catch (ExecutionException e) { - assertThat(e.getCause()).isInstanceOf(InvalidQueryException.class); - } - } - - /** - * A simple smoke test to ensure that a user can supply a custom {@link GraphTraversalSource} for - * use with DSLs. - * - * @test_category dse:graph - */ - @Test - public void should_allow_use_of_dsl_graphson() { - Assumptions.assumeThat(isGraphBinary()).isFalse(); - - List vertices = socialTraversalSource().persons("marko").knows("vadas").toList(); - assertThat(vertices.size()).isEqualTo(1); - assertThat(vertices.get(0)) - .hasProperty("name", "marko") - .hasProperty("age", 29) - .hasLabel("person"); - } - - /** - * A simple smoke test to ensure that a user can supply a custom {@link GraphTraversalSource} for - * use with DSLs. - * - * @test_category dse:graph - */ - @Test - public void should_allow_use_of_dsl_graph_binary() { - Assumptions.assumeThat(isGraphBinary()).isTrue(); - - List> vertices = - socialTraversalSource().persons("marko").knows("vadas").elementMap("name", "age").toList(); - assertThat(vertices.size()).isEqualTo(1); - - assertThatContainsProperties(vertices.get(0), "name", "marko", "age", 29); - assertThat(vertices.get(0).values()).contains("person"); - } - - /** - * Ensures that traversals with barriers (which return results bulked) contain the correct amount - * of end results. - * - *

This will fail if ran against DSE < 5.0.9 or DSE < 5.1.2. - */ - @Test - public void should_return_correct_results_when_bulked() { - Assumptions.assumeThat( - CcmBridge.isDistributionOf( - BackendType.DSE, (dist, cass) -> dist.compareTo(Version.parse("5.1.2")) > 0)) - .isTrue(); - - List results = graphTraversalSource().E().label().barrier().toList(); - Collections.sort(results); - - List expected = - Arrays.asList("knows", "created", "created", "knows", "created", "created"); - Collections.sort(expected); - - assertThat(results).isEqualTo(expected); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/ClassicGraphDataTypeFluentIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/ClassicGraphDataTypeFluentIT.java deleted file mode 100644 index d1355100c4b..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/ClassicGraphDataTypeFluentIT.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph.statement; - -import com.datastax.dse.driver.api.core.graph.ClassicGraphDataTypeITBase; -import com.datastax.dse.driver.api.core.graph.DseGraph; -import com.datastax.dse.driver.api.core.graph.FluentGraphStatement; -import com.datastax.dse.driver.api.core.graph.GraphTestSupport; -import com.datastax.dse.driver.api.core.graph.SampleGraphScripts; -import com.datastax.dse.driver.api.core.graph.ScriptGraphStatement; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "5.0.3", - description = "DSE 5.0.3 required for fluent API support") -public class ClassicGraphDataTypeFluentIT extends ClassicGraphDataTypeITBase { - - private static final CustomCcmRule CCM_RULE = GraphTestSupport.CCM_BUILDER_WITH_GRAPH.build(); - - private static final SessionRule SESSION_RULE = - GraphTestSupport.getClassicGraphSessionBuilder(CCM_RULE).build(); - - @ClassRule - public static final TestRule CHAIN = RuleChain.outerRule(CCM_RULE).around(SESSION_RULE); - - @BeforeClass - public static void setupSchema() { - SESSION_RULE - .session() - .execute(ScriptGraphStatement.newInstance(SampleGraphScripts.ALLOW_SCANS)); - SESSION_RULE - .session() - .execute(ScriptGraphStatement.newInstance(SampleGraphScripts.MAKE_STRICT)); - } - - @Override - public CqlSession session() { - return SESSION_RULE.session(); - } - - @Override - public Vertex insertVertexAndReturn(String vertexLabel, String propertyName, Object value) { - return SESSION_RULE - .session() - .execute( - FluentGraphStatement.newInstance( - DseGraph.g.addV(vertexLabel).property(propertyName, value))) - .one() - .asVertex(); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/ClassicGraphDataTypeScriptIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/ClassicGraphDataTypeScriptIT.java deleted file mode 100644 index 81f088d0c18..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/ClassicGraphDataTypeScriptIT.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph.statement; - -import com.datastax.dse.driver.api.core.graph.ClassicGraphDataTypeITBase; -import com.datastax.dse.driver.api.core.graph.GraphTestSupport; -import com.datastax.dse.driver.api.core.graph.SampleGraphScripts; -import com.datastax.dse.driver.api.core.graph.ScriptGraphStatement; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "5.0.4", - description = "DSE 5.0.4 required for script API with GraphSON 2") -public class ClassicGraphDataTypeScriptIT extends ClassicGraphDataTypeITBase { - - private static final CustomCcmRule CCM_RULE = GraphTestSupport.CCM_BUILDER_WITH_GRAPH.build(); - - private static final SessionRule SESSION_RULE = - GraphTestSupport.getClassicGraphSessionBuilder(CCM_RULE).build(); - - @ClassRule - public static final TestRule CHAIN = RuleChain.outerRule(CCM_RULE).around(SESSION_RULE); - - @BeforeClass - public static void setupSchema() { - SESSION_RULE - .session() - .execute(ScriptGraphStatement.newInstance(SampleGraphScripts.ALLOW_SCANS)); - SESSION_RULE - .session() - .execute(ScriptGraphStatement.newInstance(SampleGraphScripts.MAKE_STRICT)); - } - - @Override - public CqlSession session() { - return SESSION_RULE.session(); - } - - @Override - public Vertex insertVertexAndReturn(String vertexLabel, String propertyName, Object value) { - return SESSION_RULE - .session() - .execute( - ScriptGraphStatement.builder("g.addV(labelP).property(nameP, valueP)") - .setQueryParam("labelP", vertexLabel) - .setQueryParam("nameP", propertyName) - .setQueryParam("valueP", value) - .build()) - .one() - .asVertex(); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/ClassicGraphTraversalBatchIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/ClassicGraphTraversalBatchIT.java deleted file mode 100644 index 81f39753856..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/ClassicGraphTraversalBatchIT.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph.statement; - -import com.datastax.dse.driver.api.core.graph.GraphTestSupport; -import com.datastax.dse.driver.api.core.graph.SampleGraphScripts; -import com.datastax.dse.driver.api.core.graph.ScriptGraphStatement; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "6.0", - description = "DSE 6.0 required for BatchGraphStatement.") -public class ClassicGraphTraversalBatchIT extends GraphTraversalBatchITBase { - - private static final CustomCcmRule CCM_RULE = GraphTestSupport.GRAPH_CCM_RULE_BUILDER.build(); - - private static final SessionRule SESSION_RULE = - GraphTestSupport.getClassicGraphSessionBuilder(CCM_RULE).build(); - - @ClassRule - public static final TestRule CHAIN = RuleChain.outerRule(CCM_RULE).around(SESSION_RULE); - - private final GraphTraversalSource g = EmptyGraph.instance().traversal(); - - @BeforeClass - public static void setupSchema() { - SESSION_RULE - .session() - .execute(ScriptGraphStatement.newInstance(SampleGraphScripts.ALLOW_SCANS)); - SESSION_RULE - .session() - .execute(ScriptGraphStatement.newInstance(SampleGraphScripts.MAKE_NOT_STRICT)); - } - - @Override - protected CqlSession session() { - return SESSION_RULE.session(); - } - - @Override - protected boolean isGraphBinary() { - return false; - } - - @Override - protected CustomCcmRule ccmRule() { - return CCM_RULE; - } - - @Override - protected GraphTraversalSource graphTraversalSource() { - return g; - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/ClassicGraphTraversalIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/ClassicGraphTraversalIT.java deleted file mode 100644 index 672e1b6f679..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/ClassicGraphTraversalIT.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph.statement; - -import com.datastax.dse.driver.api.core.graph.GraphTestSupport; -import com.datastax.dse.driver.api.core.graph.SampleGraphScripts; -import com.datastax.dse.driver.api.core.graph.ScriptGraphStatement; -import com.datastax.dse.driver.api.core.graph.SocialTraversalSource; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "5.0.9", - description = "DSE 5.0.9 required for inserting edges and vertices script.") -public class ClassicGraphTraversalIT extends GraphTraversalITBase { - - private static final CustomCcmRule CCM_RULE = GraphTestSupport.GRAPH_CCM_RULE_BUILDER.build(); - - private static final SessionRule SESSION_RULE = - GraphTestSupport.getClassicGraphSessionBuilder(CCM_RULE).build(); - - @ClassRule - public static final TestRule CHAIN = RuleChain.outerRule(CCM_RULE).around(SESSION_RULE); - - private final GraphTraversalSource graphTraversalSource = EmptyGraph.instance().traversal(); - private final SocialTraversalSource socialTraversal = - EmptyGraph.instance().traversal(SocialTraversalSource.class); - - @BeforeClass - public static void setupSchema() { - SESSION_RULE - .session() - .execute(ScriptGraphStatement.newInstance(SampleGraphScripts.ALLOW_SCANS)); - SESSION_RULE - .session() - .execute(ScriptGraphStatement.newInstance(SampleGraphScripts.CLASSIC_GRAPH)); - SESSION_RULE - .session() - .execute(ScriptGraphStatement.newInstance(SampleGraphScripts.MAKE_STRICT)); - } - - @Override - protected CqlSession session() { - return SESSION_RULE.session(); - } - - @Override - protected boolean isGraphBinary() { - return false; - } - - @Override - protected CustomCcmRule ccmRule() { - return CCM_RULE; - } - - @Override - protected GraphTraversalSource graphTraversalSource() { - return graphTraversalSource; - } - - @Override - protected SocialTraversalSource socialTraversalSource() { - return socialTraversal; - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/CoreGraphDataTypeFluentIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/CoreGraphDataTypeFluentIT.java deleted file mode 100644 index 94e6415f471..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/CoreGraphDataTypeFluentIT.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph.statement; - -import static com.datastax.dse.driver.api.core.graph.DseGraph.g; -import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.unfold; - -import com.datastax.dse.driver.api.core.graph.CoreGraphDataTypeITBase; -import com.datastax.dse.driver.api.core.graph.FluentGraphStatement; -import com.datastax.dse.driver.api.core.graph.GraphTestSupport; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import java.util.Map; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.junit.ClassRule; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; -import org.junit.runner.RunWith; - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "6.8.0", - description = "DSE 6.8.0 required for Core graph support") -@RunWith(DataProviderRunner.class) -public class CoreGraphDataTypeFluentIT extends CoreGraphDataTypeITBase { - - private static final CustomCcmRule CCM_RULE = GraphTestSupport.CCM_BUILDER_WITH_GRAPH.build(); - - private static final SessionRule SESSION_RULE = - GraphTestSupport.getCoreGraphSessionBuilder(CCM_RULE).build(); - - @ClassRule - public static final TestRule CHAIN = RuleChain.outerRule(CCM_RULE).around(SESSION_RULE); - - @Override - protected CqlSession session() { - return SESSION_RULE.session(); - } - - @Override - protected String graphName() { - return SESSION_RULE.getGraphName(); - } - - @Override - public Map insertVertexThenReadProperties( - Map properties, int vertexID, String vertexLabel) { - GraphTraversal traversal = g.addV(vertexLabel).property("id", vertexID); - - for (Map.Entry entry : properties.entrySet()) { - String typeDefinition = entry.getKey(); - String propName = formatPropertyName(typeDefinition); - Object value = entry.getValue(); - traversal = traversal.property(propName, value); - } - - session().execute(FluentGraphStatement.newInstance(traversal)); - - return session() - .execute( - FluentGraphStatement.newInstance( - g.V().has(vertexLabel, "id", vertexID).valueMap().by(unfold()))) - .one() - .asMap(); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/CoreGraphDataTypeScriptIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/CoreGraphDataTypeScriptIT.java deleted file mode 100644 index b79aecf6c6a..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/CoreGraphDataTypeScriptIT.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph.statement; - -import com.datastax.dse.driver.api.core.graph.CoreGraphDataTypeITBase; -import com.datastax.dse.driver.api.core.graph.GraphTestSupport; -import com.datastax.dse.driver.api.core.graph.ScriptGraphStatement; -import com.datastax.dse.driver.api.core.graph.ScriptGraphStatementBuilder; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import java.util.Map; -import org.junit.ClassRule; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; -import org.junit.runner.RunWith; - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "6.8.0", - description = "DSE 6.8.0 required for Core graph support") -@RunWith(DataProviderRunner.class) -public class CoreGraphDataTypeScriptIT extends CoreGraphDataTypeITBase { - - private static final CustomCcmRule CCM_RULE = GraphTestSupport.CCM_BUILDER_WITH_GRAPH.build(); - - private static final SessionRule SESSION_RULE = - GraphTestSupport.getCoreGraphSessionBuilder(CCM_RULE).build(); - - @ClassRule - public static final TestRule CHAIN = RuleChain.outerRule(CCM_RULE).around(SESSION_RULE); - - @Override - protected CqlSession session() { - return SESSION_RULE.session(); - } - - @Override - protected String graphName() { - return SESSION_RULE.getGraphName(); - } - - @Override - protected Map insertVertexThenReadProperties( - Map properties, int vertexID, String vertexLabel) { - StringBuilder insert = new StringBuilder("g.addV(vertexLabel).property('id', vertexID)"); - - ScriptGraphStatementBuilder statementBuilder = - new ScriptGraphStatementBuilder() - .setQueryParam("vertexID", vertexID) - .setQueryParam("vertexLabel", vertexLabel); - - for (Map.Entry entry : properties.entrySet()) { - String typeDefinition = entry.getKey(); - String propName = formatPropertyName(typeDefinition); - Object value = entry.getValue(); - - insert.append(String.format(".property('%s', %s)", propName, propName)); - statementBuilder = statementBuilder.setQueryParam(propName, value); - } - - session().execute(statementBuilder.setScript(insert.toString()).build()); - - return session() - .execute( - ScriptGraphStatement.newInstance( - "g.V().has(vertexLabel, 'id', vertexID).valueMap().by(unfold())") - .setQueryParam("vertexID", vertexID) - .setQueryParam("vertexLabel", vertexLabel)) - .one() - .asMap(); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/CoreGraphTraversalBatchIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/CoreGraphTraversalBatchIT.java deleted file mode 100644 index be09ac1bfb2..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/CoreGraphTraversalBatchIT.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph.statement; - -import com.datastax.dse.driver.api.core.graph.GraphTestSupport; -import com.datastax.dse.driver.api.core.graph.SampleGraphScripts; -import com.datastax.dse.driver.api.core.graph.ScriptGraphStatement; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "6.8.0", - description = "DSE 6.8.0 required for Core graph support") -public class CoreGraphTraversalBatchIT extends GraphTraversalBatchITBase { - - private static final CustomCcmRule CCM_RULE = GraphTestSupport.GRAPH_CCM_RULE_BUILDER.build(); - - private static final SessionRule SESSION_RULE = - GraphTestSupport.getCoreGraphSessionBuilder(CCM_RULE).build(); - - @ClassRule - public static final TestRule CHAIN = RuleChain.outerRule(CCM_RULE).around(SESSION_RULE); - - private final GraphTraversalSource g = EmptyGraph.instance().traversal().with("allow-filtering"); - - @BeforeClass - public static void setupSchema() { - SESSION_RULE.session().execute(ScriptGraphStatement.newInstance(SampleGraphScripts.CORE_GRAPH)); - } - - @Override - protected CqlSession session() { - return SESSION_RULE.session(); - } - - @Override - protected boolean isGraphBinary() { - return true; - } - - @Override - protected CustomCcmRule ccmRule() { - return CCM_RULE; - } - - @Override - protected GraphTraversalSource graphTraversalSource() { - return g; - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/CoreGraphTraversalIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/CoreGraphTraversalIT.java deleted file mode 100644 index d97b0da958a..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/CoreGraphTraversalIT.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph.statement; - -import com.datastax.dse.driver.api.core.graph.GraphTestSupport; -import com.datastax.dse.driver.api.core.graph.SampleGraphScripts; -import com.datastax.dse.driver.api.core.graph.ScriptGraphStatement; -import com.datastax.dse.driver.api.core.graph.SocialTraversalSource; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "6.8.0", - description = "DSE 6.8.0 required for Core graph support") -public class CoreGraphTraversalIT extends GraphTraversalITBase { - - private static final CustomCcmRule CCM_RULE = GraphTestSupport.CCM_BUILDER_WITH_GRAPH.build(); - - private static final SessionRule SESSION_RULE = - GraphTestSupport.getCoreGraphSessionBuilder(CCM_RULE).build(); - - @ClassRule - public static final TestRule CHAIN = RuleChain.outerRule(CCM_RULE).around(SESSION_RULE); - - private final GraphTraversalSource graphTraversalSource = - EmptyGraph.instance().traversal().with("allow-filtering"); - private final SocialTraversalSource socialTraversalSource = - EmptyGraph.instance().traversal(SocialTraversalSource.class).with("allow-filtering"); - - @BeforeClass - public static void setupSchema() { - SESSION_RULE.session().execute(ScriptGraphStatement.newInstance(SampleGraphScripts.CORE_GRAPH)); - } - - @Override - protected CqlSession session() { - return SESSION_RULE.session(); - } - - @Override - protected boolean isGraphBinary() { - return true; - } - - @Override - protected CustomCcmRule ccmRule() { - return CCM_RULE; - } - - @Override - protected GraphTraversalSource graphTraversalSource() { - return graphTraversalSource; - } - - @Override - protected SocialTraversalSource socialTraversalSource() { - return socialTraversalSource; - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/GraphTraversalBatchITBase.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/GraphTraversalBatchITBase.java deleted file mode 100644 index 0c8c3b8b5d4..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/GraphTraversalBatchITBase.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph.statement; - -import static com.datastax.dse.driver.api.core.graph.TinkerGraphAssertions.assertThat; -import static com.datastax.dse.driver.internal.core.graph.GraphTestUtils.assertThatContainsLabel; -import static com.datastax.dse.driver.internal.core.graph.GraphTestUtils.assertThatContainsProperties; -import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.addE; -import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.addV; -import static org.assertj.core.api.Assertions.fail; - -import com.datastax.dse.driver.api.core.graph.BatchGraphStatement; -import com.datastax.dse.driver.api.core.graph.FluentGraphStatement; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.servererrors.InvalidQueryException; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import java.util.Map; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__; -import org.apache.tinkerpop.gremlin.structure.Direction; -import org.apache.tinkerpop.gremlin.structure.Edge; -import org.junit.Test; - -public abstract class GraphTraversalBatchITBase { - - protected abstract CqlSession session(); - - protected abstract boolean isGraphBinary(); - - protected abstract CustomCcmRule ccmRule(); - - protected abstract GraphTraversalSource graphTraversalSource(); - - @Test - public void should_allow_vertex_and_edge_insertions_in_batch() { - BatchGraphStatement batch = - BatchGraphStatement.builder() - .addTraversals( - ImmutableList.of( - addV("person").property("name", "batch1").property("age", 1), - addV("person").property("name", "batch2").property("age", 2))) - .build(); - - BatchGraphStatement batch2 = - BatchGraphStatement.builder() - .addTraversals(batch) - .addTraversal( - addE("knows") - .from(__.V().has("name", "batch1")) - .to(__.V().has("name", "batch2")) - .property("weight", 2.3f)) - .build(); - - assertThat(batch.size()).isEqualTo(2); - assertThat(batch2.size()).isEqualTo(3); - - session().execute(batch2); - - if (isGraphBinary()) { - Map properties = - session() - .execute( - FluentGraphStatement.newInstance( - graphTraversalSource().V().has("name", "batch1").elementMap("age"))) - .one() - .asMap(); - - assertThatContainsProperties(properties, "age", 1); - - properties = - session() - .execute( - FluentGraphStatement.newInstance( - graphTraversalSource().V().has("name", "batch2").elementMap("age"))) - .one() - .asMap(); - - assertThatContainsProperties(properties, "age", 2); - - properties = - session() - .execute( - FluentGraphStatement.newInstance( - graphTraversalSource() - .V() - .has("name", "batch1") - .bothE() - .elementMap("weight", "person"))) - .one() - .asMap(); - - assertThatContainsProperties(properties, "weight", 2.3f); - assertThatContainsLabel(properties, Direction.IN, "person"); - assertThatContainsLabel(properties, Direction.OUT, "person"); - - } else { - - assertThat( - session() - .execute( - FluentGraphStatement.newInstance( - graphTraversalSource().V().has("name", "batch1"))) - .one() - .asVertex()) - .hasProperty("age", 1); - - assertThat( - session() - .execute( - FluentGraphStatement.newInstance( - graphTraversalSource().V().has("name", "batch2"))) - .one() - .asVertex()) - .hasProperty("age", 2); - - assertThat( - session() - .execute( - FluentGraphStatement.newInstance( - graphTraversalSource().V().has("name", "batch1").bothE())) - .one() - .asEdge()) - .hasProperty("weight", 2.3f) - .hasOutVLabel("person") - .hasInVLabel("person"); - } - } - - @Test - public void should_fail_if_no_bytecode_in_batch() { - BatchGraphStatement batch = - BatchGraphStatement.builder().addTraversals(ImmutableList.of()).build(); - assertThat(batch.size()).isEqualTo(0); - try { - session().execute(batch); - fail( - "Should have thrown InvalidQueryException because batch does not contain any traversals."); - } catch (InvalidQueryException e) { - assertThat(e.getMessage()) - .contains("The batch statement sent does not contain any traversal"); - } - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/GraphTraversalITBase.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/GraphTraversalITBase.java deleted file mode 100644 index 5bcb01bc165..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/GraphTraversalITBase.java +++ /dev/null @@ -1,668 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph.statement; - -import static com.datastax.dse.driver.api.core.graph.FluentGraphStatement.newInstance; -import static com.datastax.dse.driver.api.core.graph.TinkerGraphAssertions.assertThat; -import static com.datastax.dse.driver.api.core.graph.TinkerPathAssert.validatePathObjects; -import static com.datastax.dse.driver.internal.core.graph.GraphTestUtils.assertThatContainsLabel; -import static com.datastax.dse.driver.internal.core.graph.GraphTestUtils.assertThatContainsProperties; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.assertj.core.api.Assertions.fail; - -import com.datastax.dse.driver.api.core.graph.AsyncGraphResultSet; -import com.datastax.dse.driver.api.core.graph.FluentGraphStatement; -import com.datastax.dse.driver.api.core.graph.GraphNode; -import com.datastax.dse.driver.api.core.graph.GraphResultSet; -import com.datastax.dse.driver.api.core.graph.GraphStatement; -import com.datastax.dse.driver.api.core.graph.ScriptGraphStatement; -import com.datastax.dse.driver.api.core.graph.SocialTraversalSource; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.Version; -import com.datastax.oss.driver.api.core.servererrors.InvalidQueryException; -import com.datastax.oss.driver.api.core.type.reflect.GenericType; -import com.datastax.oss.driver.api.testinfra.ccm.CcmBridge; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import com.datastax.oss.driver.shaded.guava.common.collect.Lists; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.ExecutionException; -import java.util.stream.Collectors; -import org.apache.tinkerpop.gremlin.process.traversal.Path; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__; -import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree; -import org.apache.tinkerpop.gremlin.structure.Direction; -import org.apache.tinkerpop.gremlin.structure.Edge; -import org.apache.tinkerpop.gremlin.structure.Graph; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.assertj.core.api.Assertions; -import org.assertj.core.api.Assumptions; -import org.junit.Test; - -public abstract class GraphTraversalITBase { - - protected abstract CqlSession session(); - - protected abstract boolean isGraphBinary(); - - protected abstract CustomCcmRule ccmRule(); - - protected abstract GraphTraversalSource graphTraversalSource(); - - protected abstract SocialTraversalSource socialTraversalSource(); - - /** - * Ensures that a previously returned {@link Vertex}'s {@link Vertex#id()} can be used as an input - * to {@link - * org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource#V(Object...)} to - * retrieve the {@link Vertex} and that the returned {@link Vertex} is the same. - * - * @test_category dse:graph - */ - @Test - public void should_use_vertex_id_as_parameter() { - GraphTraversal query = - graphTraversalSource().V().hasLabel("person").has("name", "marko"); - GraphResultSet resultSet = session().execute(newInstance(query)); - - List results = resultSet.all(); - - assertThat(results.size()).isEqualTo(1); - Vertex marko = results.get(0).asVertex(); - if (isGraphBinary()) { - Map properties = - session().execute(newInstance(query.elementMap("name"))).one().asMap(); - assertThatContainsProperties(properties, "name", "marko"); - } else { - assertThat(marko).hasProperty("name", "marko"); - } - - resultSet = session().execute(newInstance(graphTraversalSource().V(marko.id()))); - - results = resultSet.all(); - assertThat(results.size()).isEqualTo(1); - Vertex marko2 = results.get(0).asVertex(); - // Ensure that the returned vertex is the same as the first. - assertThat(marko2).isEqualTo(marko); - } - - /** - * Ensures that a previously returned {@link Edge}'s {@link Edge#id()} can be used as an input to - * {@link - * org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource#E(Object...)} to - * retrieve the {@link Edge} and that the returned {@link Edge} is the same. - * - * @test_category dse:graph - */ - @Test - public void should_use_edge_id_as_parameter() { - GraphTraversal query = graphTraversalSource().E().has("weight", 0.2f); - GraphResultSet resultSet = session().execute(newInstance(query)); - - List results = resultSet.all(); - assertThat(results.size()).isEqualTo(1); - - Edge created = results.get(0).asEdge(); - if (isGraphBinary()) { - Map properties = - session() - .execute(newInstance(query.elementMap("weight", "software", "person"))) - .one() - .asMap(); - - assertThatContainsProperties(properties, "weight", 0.2f); - assertThatContainsLabel(properties, Direction.IN, "software"); - assertThatContainsLabel(properties, Direction.OUT, "person"); - } else { - assertThat(created) - .hasProperty("weight", 0.2f) - .hasInVLabel("software") - .hasOutVLabel("person"); - } - - if (isGraphBinary()) { - Map inProperties = - session() - .execute( - newInstance( - graphTraversalSource().E(created.id()).inV().elementMap("name", "lang"))) - .one() - .asMap(); - assertThatContainsProperties(inProperties, "name", "lop", "lang", "java"); - } else { - resultSet = session().execute(newInstance(graphTraversalSource().E(created.id()).inV())); - results = resultSet.all(); - assertThat(results.size()).isEqualTo(1); - Vertex lop = results.get(0).asVertex(); - - assertThat(lop).hasLabel("software").hasProperty("name", "lop").hasProperty("lang", "java"); - } - } - - /** - * A sanity check that a returned {@link Vertex}'s id is a {@link Map}. This test could break in - * the future if the format of a vertex ID changes from a Map to something else in DSE. - * - * @test_category dse:graph - */ - @Test - public void should_deserialize_vertex_id_as_map() { - GraphResultSet resultSet = - session() - .execute( - newInstance(graphTraversalSource().V().hasLabel("person").has("name", "marko"))); - - List results = resultSet.all(); - assertThat(results.size()).isEqualTo(1); - - Vertex marko = results.get(0).asVertex(); - - if (isGraphBinary()) { - assertThat(((String) marko.id())).contains("marko"); - assertThat(marko.label()).isEqualTo("person"); - } else { - assertThat(marko).hasProperty("name", "marko"); - @SuppressWarnings("unchecked") - Map id = (Map) marko.id(); - assertThat(id) - .hasSize(3) - .containsEntry("~label", "person") - .containsKey("community_id") - .containsKey("member_id"); - } - } - - /** - * Ensures that a traversal that returns a result of mixed types is interpreted as a {@link Map} - * with {@link Object} values. Also uses {@link - * org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal#by(org.apache.tinkerpop.gremlin.process.traversal.Traversal)} - * with an anonymous traversal to get inbound 'created' edges and folds them into a list. - * - *

Executes a vertex traversal that binds label 'a' and 'b' to vertex properties and label 'c' - * to vertices that have edges from that vertex. - * - * @test_category dse:graph - */ - @Test - public void should_handle_result_object_of_mixed_types() { - // find all software vertices and select name, language, and find all vertices that created such - // software. - GraphResultSet rs = - session() - .execute( - newInstance( - graphTraversalSource() - .V() - .hasLabel("software") - .as("a", "b", "c") - .select("a", "b", "c") - .by("name") - .by("lang") - .by(__.in("created").fold()))); - - List results = rs.all(); - assertThat(results.size()).isEqualTo(2); - - // Ensure that we got 'lop' and 'ripple' for property a. - assertThat(results) - .extracting(m -> m.getByKey("a").as(Object.class)) - .containsOnly("lop", "ripple"); - - for (GraphNode result : results) { - // The row should represent a map with a, b, and c keys. - assertThat(ImmutableList.copyOf(result.keys())).containsOnlyOnce("a", "b", "c"); - // 'e' should not exist, thus it should be null. - assertThat(result.getByKey("e")).isNull(); - // both software are written in java. - assertThat(result.getByKey("b").isNull()).isFalse(); - assertThat(result.getByKey("b").asString()).isEqualTo("java"); - GraphNode c = result.getByKey("c"); - assertThat(c.isList()).isTrue(); - if (result.getByKey("a").asString().equals("lop")) { - if (isGraphBinary()) { - // should contain three vertices - Assertions.assertThat(c.size()).isEqualTo(3); - } else { - // 'c' should contain marko, josh, peter. - // Ensure we have three vertices. - assertThat(c.size()).isEqualTo(3); - List vertices = - Lists.newArrayList( - c.getByIndex(0).asVertex(), - c.getByIndex(1).asVertex(), - c.getByIndex(2).asVertex()); - assertThat(vertices) - .extracting(vertex -> vertex.property("name").value()) - .containsOnly("marko", "josh", "peter"); - } - } else { - if (isGraphBinary()) { - // has only one label - Assertions.assertThat(c.size()).isEqualTo(1); - } else { - // ripple, 'c' should contain josh. - // Ensure we have 1 vertex. - assertThat(c.size()).isEqualTo(1); - Vertex vertex = c.getByIndex(0).asVertex(); - assertThat(vertex).hasProperty("name", "josh"); - } - } - } - } - - /** - * Ensures a traversal that yields no results is properly retrieved and is empty. - * - * @test_category dse:graph - */ - @Test - public void should_return_zero_results() { - if (isGraphBinary()) { - assertThatThrownBy( - () -> - session().execute(newInstance(graphTraversalSource().V().hasLabel("notALabel")))) - .isInstanceOf(InvalidQueryException.class) - .hasMessageContaining("Unknown vertex label 'notALabel'"); - } else { - GraphResultSet rs = - session().execute(newInstance(graphTraversalSource().V().hasLabel("notALabel"))); - assertThat(rs.all().size()).isZero(); - } - } - - /** - * Ensures a traversal that yields no results is properly retrieved and is empty, using GraphSON2 - * and the TinkerPop transform results function. - * - * @test_category dse:graph - */ - @Test - public void should_return_zero_results_graphson_2() { - Assumptions.assumeThat(isGraphBinary()).isFalse(); - - GraphStatement simpleGraphStatement = - ScriptGraphStatement.newInstance("g.V().hasLabel('notALabel')"); - - GraphResultSet rs = session().execute(simpleGraphStatement); - assertThat(rs.one()).isNull(); - } - - /** - * Validates that a traversal using lambda operations with anonymous traversals are applied - * appropriately and return the expected results. - * - *

Traversal that filters 'person'-labeled vertices by name 'marko' and flatMaps outgoing - * vertices on the 'knows' relationship by their outgoing 'created' vertices and then maps by - * their 'name' property and folds them into one list. - * - *

Note: This does not validate lambdas with functions as those can't be interpreted and - * sent remotely. - * - * @test_category dse:graph - */ - @Test - public void should_handle_lambdas() { - // Find all people marko knows and the software they created. - GraphResultSet result = - session() - .execute( - newInstance( - graphTraversalSource() - .V() - .hasLabel("person") - .filter(__.has("name", "marko")) - .out("knows") - .flatMap(__.out("created")) - .map(__.values("name")) - .fold())); - - // Marko only knows josh and vadas, of which josh created lop and ripple. - List software = result.one().as(GenericType.listOf(String.class)); - assertThat(software).containsOnly("lop", "ripple"); - } - - /** - * Validates that when traversing a path and labeling some of the elements during the traversal - * that the output elements are properly labeled. - * - * @test_category dse:graph - */ - @Test - public void should_resolve_path_with_some_labels() { - GraphResultSet rs = - session() - .execute( - newInstance( - graphTraversalSource() - .V() - .hasLabel("person") - .has("name", "marko") - .as("a") - .outE("knows") - .inV() - .as("c", "d") - .outE("created") - .as("e", "f", "g") - .inV() - .path())); - - List results = rs.all(); - assertThat(results.size()).isEqualTo(2); - for (GraphNode result : results) { - Path path = result.asPath(); - validatePathObjects(path); - assertThat(path.labels()).hasSize(5); - assertThat(path) - .hasLabel(0, "a") - .hasNoLabel(1) - .hasLabel(2, "c", "d") - .hasLabel(3, "e", "f", "g") - .hasNoLabel(4); - } - } - - /** - * Validates that when traversing a path and labeling all of the elements during the traversal - * that the output elements are properly labeled. - * - * @test_category dse:graph - */ - @Test - public void should_resolve_path_with_labels() { - GraphResultSet rs = - session() - .execute( - newInstance( - graphTraversalSource() - .V() - .hasLabel("person") - .has("name", "marko") - .as("a") - .outE("knows") - .as("b") - .inV() - .as("c", "d") - .outE("created") - .as("e", "f", "g") - .inV() - .as("h") - .path())); - List results = rs.all(); - assertThat(results.size()).isEqualTo(2); - for (GraphNode result : results) { - Path path = result.asPath(); - validatePathObjects(path); - assertThat(path.labels()).hasSize(5); - assertThat(path) - .hasLabel(0, "a") - .hasLabel(1, "b") - .hasLabel(2, "c", "d") - .hasLabel(3, "e", "f", "g") - .hasLabel(4, "h"); - } - } - - /** - * Validates that when traversing a path and labeling none of the elements during the traversal - * that all the labels are empty in the result. - * - * @test_category dse:graph - */ - @Test - public void should_resolve_path_without_labels() { - GraphResultSet rs = - session() - .execute( - newInstance( - graphTraversalSource() - .V() - .hasLabel("person") - .has("name", "marko") - .outE("knows") - .inV() - .outE("created") - .inV() - .path())); - List results = rs.all(); - assertThat(results.size()).isEqualTo(2); - for (GraphNode result : results) { - Path path = result.asPath(); - validatePathObjects(path); - assertThat(path.labels()).hasSize(5); - for (int i = 0; i < 5; i++) assertThat(path).hasNoLabel(i); - } - } - - /** - * Validates that a traversal returning a Tree structure is returned appropriately with the - * expected contents. - * - *

Retrieves trees of people marko knows and the software they created. - * - * @test_category dse:graph - */ - @Test - public void should_parse_tree() { - // Get a tree structure showing the paths from mark to people he knows to software they've - // created. - GraphResultSet rs = - session() - .execute( - newInstance( - graphTraversalSource() - .V() - .hasLabel("person") - .out("knows") - .out("created") - .tree() - .by("name"))); - - List results = rs.all(); - assertThat(results.size()).isEqualTo(1); - - // [{key=marko, value=[{key=josh, value=[{key=ripple, value=[]}, {key=lop, value=[]}]}]}] - GraphNode result = results.get(0); - - @SuppressWarnings("unchecked") - Tree tree = result.as(Tree.class); - - assertThat(tree).tree("marko").tree("josh").tree("lop").isLeaf(); - - assertThat(tree).tree("marko").tree("josh").tree("ripple").isLeaf(); - } - - /** - * Ensures that a traversal that returns a sub graph can be retrieved. - * - *

The subgraph is all members in a knows relationship, thus is all people who marko knows and - * the edges that connect them. - */ - @Test - public void should_handle_subgraph_graphson() { - Assumptions.assumeThat(isGraphBinary()).isFalse(); - GraphResultSet rs = - session() - .execute( - newInstance( - graphTraversalSource() - .E() - .hasLabel("knows") - .subgraph("subGraph") - .cap("subGraph"))); - - List results = rs.all(); - assertThat(results.size()).isEqualTo(1); - - Graph graph = results.get(0).as(Graph.class); - - assertThat(graph.edges()).toIterable().hasSize(2); - assertThat(graph.vertices()).toIterable().hasSize(3); - } - - /** - * Ensures that a traversal that returns a sub graph can be retrieved. - * - *

The subgraph is all members in a knows relationship, thus is all people who marko knows and - * the edges that connect them. - */ - @Test - public void should_handle_subgraph_grap_binary() { - Assumptions.assumeThat(isGraphBinary()).isTrue(); - GraphResultSet rs = - session() - .execute( - newInstance( - graphTraversalSource() - .E() - .hasLabel("knows") - .subgraph("subGraph") - .cap("subGraph"))); - - List results = rs.all(); - assertThat(results.size()).isEqualTo(1); - - String graph = results.get(0).as(String.class); - - assertThat(graph).contains("vertices:3").contains("edges:2"); - } - - /** - * A simple smoke test to ensure that a user can supply a custom {@link GraphTraversalSource} for - * use with DSLs. - * - * @test_category dse:graph - */ - @Test - public void should_allow_use_of_dsl_graphson() throws Exception { - Assumptions.assumeThat(isGraphBinary()).isFalse(); - SocialTraversalSource gSocial = socialTraversalSource(); - - GraphStatement gs = newInstance(gSocial.persons("marko").knows("vadas")); - - GraphResultSet rs = session().execute(gs); - List results = rs.all(); - - assertThat(results.size()).isEqualTo(1); - assertThat(results.get(0).asVertex()) - .hasProperty("name", "marko") - .hasProperty("age", 29) - .hasLabel("person"); - } - - /** - * A simple smoke test to ensure that a user can supply a custom {@link GraphTraversalSource} for - * use with DSLs. - * - * @test_category dse:graph - */ - @Test - public void should_allow_use_of_dsl_graph_binary() throws Exception { - Assumptions.assumeThat(isGraphBinary()).isTrue(); - SocialTraversalSource gSocial = socialTraversalSource(); - - GraphStatement gs = - newInstance(gSocial.persons("marko").knows("vadas").elementMap("name", "age")); - - GraphResultSet rs = session().execute(gs); - List results = rs.all(); - - assertThat(results.size()).isEqualTo(1); - assertThatContainsProperties(results.get(0).asMap(), "name", "marko", "age", 29); - Assertions.assertThat(results.get(0).asMap().values()).contains("person"); - } - - /** - * Ensures that traversals with barriers (which return results bulked) contain the correct amount - * of end results. - * - *

This will fail if ran against DSE < 5.0.9 or DSE < 5.1.2. - */ - @Test - public void should_return_correct_results_when_bulked() { - Assumptions.assumeThat( - CcmBridge.isDistributionOf( - BackendType.DSE, (dist, cass) -> dist.compareTo(Version.parse("5.1.2")) > 0)) - .isTrue(); - - GraphResultSet rs = - session().execute(newInstance(graphTraversalSource().E().label().barrier())); - - List results = - rs.all().stream().map(GraphNode::asString).sorted().collect(Collectors.toList()); - - assertThat(results) - .hasSize(6) - .containsSequence("created", "created", "created", "created") - .containsSequence("knows", "knows"); - } - - @Test - public void should_handle_asynchronous_execution_graphson() { - Assumptions.assumeThat(isGraphBinary()).isFalse(); - StringBuilder names = new StringBuilder(); - - CompletionStage future = - session() - .executeAsync( - FluentGraphStatement.newInstance(graphTraversalSource().V().hasLabel("person"))); - - try { - // dumb processing to make sure the completable future works correctly and correct results are - // returned - Iterable results = - future.thenApply(AsyncGraphResultSet::currentPage).toCompletableFuture().get(); - for (GraphNode gn : results) { - names.append(gn.asVertex().property("name").value()); - } - } catch (InterruptedException | ExecutionException e) { - fail("Shouldn't have thrown an exception waiting for the result to complete"); - } - - assertThat(names.toString()).contains("peter", "marko", "vadas", "josh"); - } - - @Test - public void should_handle_asynchronous_execution_graph_binary() { - Assumptions.assumeThat(isGraphBinary()).isTrue(); - StringBuilder names = new StringBuilder(); - - CompletionStage future = - session() - .executeAsync( - FluentGraphStatement.newInstance(graphTraversalSource().V().hasLabel("person"))); - - try { - // dumb processing to make sure the completable future works correctly and correct results are - // returned - Iterable results = - future.thenApply(AsyncGraphResultSet::currentPage).toCompletableFuture().get(); - for (GraphNode gn : results) { - names.append(gn.asVertex().id()); - } - } catch (InterruptedException | ExecutionException e) { - fail("Shouldn't have thrown an exception waiting for the result to complete"); - } - - assertThat(names.toString()).contains("peter", "marko", "vadas", "josh"); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/GraphTraversalMetaPropertiesIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/GraphTraversalMetaPropertiesIT.java deleted file mode 100644 index d8058cbf59e..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/GraphTraversalMetaPropertiesIT.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph.statement; - -// INFO: meta props are going away in NGDG - -import static com.datastax.dse.driver.api.core.graph.DseGraph.g; -import static com.datastax.dse.driver.api.core.graph.FluentGraphStatement.newInstance; -import static com.datastax.dse.driver.api.core.graph.SampleGraphScripts.ALLOW_SCANS; -import static com.datastax.dse.driver.api.core.graph.SampleGraphScripts.MAKE_STRICT; -import static com.datastax.dse.driver.api.core.graph.TinkerGraphAssertions.assertThat; - -import com.datastax.dse.driver.api.core.graph.GraphResultSet; -import com.datastax.dse.driver.api.core.graph.GraphTestSupport; -import com.datastax.dse.driver.api.core.graph.ScriptGraphStatement; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.apache.tinkerpop.gremlin.structure.VertexProperty; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; - -// INFO: meta props are going away in NGDG - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "5.0.3", - description = "DSE 5.0.3 required for remote TinkerPop support") -public class GraphTraversalMetaPropertiesIT { - - private static final CustomCcmRule CCM_RULE = GraphTestSupport.GRAPH_CCM_RULE_BUILDER.build(); - - private static final SessionRule SESSION_RULE = - GraphTestSupport.getClassicGraphSessionBuilder(CCM_RULE).build(); - - @ClassRule - public static final TestRule CHAIN = RuleChain.outerRule(CCM_RULE).around(SESSION_RULE); - - /** Builds a simple schema that provides for a vertex with a property with sub properties. */ - private static final String META_PROPS = - MAKE_STRICT - + ALLOW_SCANS - + "schema.propertyKey('sub_prop').Text().create()\n" - + "schema.propertyKey('sub_prop2').Text().create()\n" - + "schema.propertyKey('meta_prop').Text().properties('sub_prop', 'sub_prop2').create()\n" - + "schema.vertexLabel('meta_v').properties('meta_prop').create()"; - - /** - * Ensures that a traversal that yields a vertex with a property that has its own properties that - * is appropriately parsed and made accessible via {@link VertexProperty#property(String)}. - * - * @test_category dse:graph - */ - @Test - public void should_parse_meta_properties() { - SESSION_RULE.session().execute(ScriptGraphStatement.newInstance(META_PROPS)); - - GraphResultSet result = - SESSION_RULE - .session() - .execute( - newInstance( - g.addV("meta_v") - .property("meta_prop", "hello", "sub_prop", "hi", "sub_prop2", "hi2"))); - - Vertex v = result.one().asVertex(); - assertThat(v).hasProperty("meta_prop"); - - VertexProperty metaProp = v.property("meta_prop"); - assertThat(metaProp) - .hasValue("hello") - .hasProperty("sub_prop", "hi") - .hasProperty("sub_prop2", "hi2"); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/GraphTraversalMultiPropertiesIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/GraphTraversalMultiPropertiesIT.java deleted file mode 100644 index c30e770f40e..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/graph/statement/GraphTraversalMultiPropertiesIT.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.graph.statement; - -import static com.datastax.dse.driver.api.core.graph.DseGraph.g; -import static com.datastax.dse.driver.api.core.graph.FluentGraphStatement.newInstance; -import static com.datastax.dse.driver.api.core.graph.SampleGraphScripts.ALLOW_SCANS; -import static com.datastax.dse.driver.api.core.graph.SampleGraphScripts.MAKE_STRICT; -import static com.datastax.dse.driver.api.core.graph.TinkerGraphAssertions.assertThat; - -import com.datastax.dse.driver.api.core.graph.GraphResultSet; -import com.datastax.dse.driver.api.core.graph.GraphTestSupport; -import com.datastax.dse.driver.api.core.graph.ScriptGraphStatement; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import java.util.Iterator; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.apache.tinkerpop.gremlin.structure.VertexProperty; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; - -// INFO: multi props are not supported in Core -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "5.0.3", - description = "DSE 5.0.3 required for remote TinkerPop support") -public class GraphTraversalMultiPropertiesIT { - - private static final CustomCcmRule CCM_RULE = GraphTestSupport.GRAPH_CCM_RULE_BUILDER.build(); - - private static final SessionRule SESSION_RULE = - GraphTestSupport.getClassicGraphSessionBuilder(CCM_RULE).build(); - - @ClassRule - public static final TestRule CHAIN = RuleChain.outerRule(CCM_RULE).around(SESSION_RULE); - - /** Builds a simple schema that provides for a vertex with a multi-cardinality property. */ - private static final String MULTI_PROPS = - MAKE_STRICT - + ALLOW_SCANS - + "schema.propertyKey('multi_prop').Text().multiple().create()\n" - + "schema.vertexLabel('multi_v').properties('multi_prop').create()\n"; - - /** - * Ensures that a traversal that yields a vertex with a property name that is present multiple - * times that the properties are parsed and made accessible via {@link - * Vertex#properties(String...)}. - * - * @test_category dse:graph - */ - @Test - public void should_parse_multiple_cardinality_properties() { - // given a schema that defines multiple cardinality properties. - SESSION_RULE.session().execute(ScriptGraphStatement.newInstance(MULTI_PROPS)); - - // when adding a vertex with a multiple cardinality property - GraphResultSet result = - SESSION_RULE - .session() - .execute( - newInstance( - g.addV("multi_v") - .property("multi_prop", "Hello") - .property("multi_prop", "Sweet") - .property("multi_prop", "World"))); - - Vertex v = result.one().asVertex(); - assertThat(v).hasProperty("multi_prop"); - - Iterator> multiProp = v.properties("multi_prop"); - assertThat(multiProp) - .toIterable() - .extractingResultOf("value") - .containsExactly("Hello", "Sweet", "World"); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/insights/InsightsClientIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/insights/InsightsClientIT.java deleted file mode 100644 index 0296908be44..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/insights/InsightsClientIT.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.insights; - -import com.datastax.dse.driver.internal.core.insights.InsightsClient; -import com.datastax.dse.driver.internal.core.insights.configuration.InsightsConfiguration; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import com.datastax.oss.driver.internal.core.context.InternalDriverContext; -import io.netty.util.concurrent.DefaultEventExecutor; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; - -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "6.7.0", - description = "DSE 6.7.0 required for Insights support") -public class InsightsClientIT { - private static final StackTraceElement[] EMPTY_STACK_TRACE = {}; - - private static CustomCcmRule ccmRule = - CustomCcmRule.builder() - .withNodes(1) - .withJvmArgs( - "-Dinsights.service_options_enabled=true", - "-Dinsights.default_mode=ENABLED_WITH_LOCAL_STORAGE") - .build(); - - private static SessionRule sessionRule = SessionRule.builder(ccmRule).build(); - - @ClassRule public static TestRule chain = RuleChain.outerRule(ccmRule).around(sessionRule); - - @Test - public void should_send_insights_startup_event_using_client() - throws ExecutionException, InterruptedException, TimeoutException { - // given - InsightsClient insightsClient = - InsightsClient.createInsightsClient( - new InsightsConfiguration(true, 300000L, new DefaultEventExecutor()), - (InternalDriverContext) sessionRule.session().getContext(), - EMPTY_STACK_TRACE); - - // when - insightsClient.sendStartupMessage().toCompletableFuture().get(1000, TimeUnit.SECONDS); - - // then no exception - } - - @Test - public void should_send_insights_status_event_using_client() - throws ExecutionException, InterruptedException, TimeoutException { - // given - InsightsClient insightsClient = - InsightsClient.createInsightsClient( - new InsightsConfiguration(true, 300000L, new DefaultEventExecutor()), - (InternalDriverContext) sessionRule.session().getContext(), - EMPTY_STACK_TRACE); - - // when - insightsClient.sendStatusMessage().toCompletableFuture().get(1000, TimeUnit.SECONDS); - - // then no exception - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/metadata/schema/AbstractMetadataIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/metadata/schema/AbstractMetadataIT.java deleted file mode 100644 index ea28dc6449e..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/metadata/schema/AbstractMetadataIT.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.metadata.schema; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.cql.SimpleStatement; -import com.datastax.oss.driver.api.core.metadata.schema.KeyspaceMetadata; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import com.datastax.oss.driver.categories.ParallelizableTests; -import java.util.Optional; -import org.junit.experimental.categories.Category; - -/* Abstract class to hold common methods for Metadata Schema tests. */ -@Category(ParallelizableTests.class) -public abstract class AbstractMetadataIT { - - /* Convenience method for executing a CQL statement using the test's Session Rule. */ - public void execute(String cql) { - getSessionRule() - .session() - .execute( - SimpleStatement.builder(cql) - .setExecutionProfile(getSessionRule().slowProfile()) - .build()); - } - - /** - * Convenience method for retrieving the Keyspace metadata from this test's Session Rule. Also - * asserts the Keyspace exists and has the expected name. - */ - public DseKeyspaceMetadata getKeyspace() { - Optional keyspace = - getSessionRule().session().getMetadata().getKeyspace(getSessionRule().keyspace()); - assertThat(keyspace) - .isPresent() - .hasValueSatisfying( - ks -> { - assertThat(ks).isInstanceOf(DseKeyspaceMetadata.class); - assertThat(ks.getName()).isEqualTo(getSessionRule().keyspace()); - }); - return ((DseKeyspaceMetadata) keyspace.get()); - } - - /* Concrete ITs should return their ClassRule SessionRule. */ - protected abstract SessionRule getSessionRule(); -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/metadata/schema/DseAggregateMetadataIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/metadata/schema/DseAggregateMetadataIT.java deleted file mode 100644 index 8ba752d3a24..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/metadata/schema/DseAggregateMetadataIT.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.metadata.schema; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assumptions.assumeThat; - -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.Version; -import com.datastax.oss.driver.api.core.metadata.schema.AggregateMetadata; -import com.datastax.oss.driver.api.core.type.DataTypes; -import com.datastax.oss.driver.api.testinfra.ccm.CcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import com.datastax.oss.driver.categories.ParallelizableTests; -import java.util.Objects; -import java.util.Optional; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; - -@Category(ParallelizableTests.class) -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "5.0", - description = "DSE 5.0+ required function/aggregate support") -public class DseAggregateMetadataIT extends AbstractMetadataIT { - - private static final CcmRule CCM_RULE = CcmRule.getInstance(); - - private static final SessionRule SESSION_RULE = SessionRule.builder(CCM_RULE).build(); - - @ClassRule - public static final TestRule CHAIN = RuleChain.outerRule(CCM_RULE).around(SESSION_RULE); - - private static final Version DSE_6_0_0 = Objects.requireNonNull(Version.parse("6.0.0")); - - @Override - protected SessionRule getSessionRule() { - return DseAggregateMetadataIT.SESSION_RULE; - } - - @Test - public void should_parse_aggregate_without_deterministic() { - String cqlFunction = - "CREATE FUNCTION nondetf(i int) RETURNS NULL ON NULL INPUT RETURNS int LANGUAGE java AS 'return new java.util.Random().nextInt(i);';"; - String cqlAggregate = "CREATE AGGREGATE nondeta() SFUNC nondetf STYPE int INITCOND 0;"; - execute(cqlFunction); - execute(cqlAggregate); - DseKeyspaceMetadata keyspace = getKeyspace(); - Optional aggregateOpt = keyspace.getAggregate("nondeta"); - assertThat(aggregateOpt.map(DseAggregateMetadata.class::cast)) - .hasValueSatisfying( - aggregate -> { - if (isDse6OrHigher()) { - assertThat(aggregate.getDeterministic()).contains(false); - } else { - assertThat(aggregate.getDeterministic()).isEmpty(); - } - assertThat(aggregate.getStateType()).isEqualTo(DataTypes.INT); - assertThat(aggregate.describe(false)) - .isEqualTo( - String.format( - "CREATE AGGREGATE \"%s\".\"nondeta\"() SFUNC \"nondetf\" STYPE int INITCOND 0;", - keyspace.getName().asInternal())); - }); - } - - @Test - public void should_parse_aggregate_with_deterministic() { - assumeThat(isDse6OrHigher()).describedAs("DSE 6.0+ required for DETERMINISTIC").isTrue(); - String cqlFunction = - "CREATE FUNCTION detf(i int, y int) RETURNS NULL ON NULL INPUT RETURNS int LANGUAGE java AS 'return i+y;';"; - String cqlAggregate = - "CREATE AGGREGATE deta(int) SFUNC detf STYPE int INITCOND 0 DETERMINISTIC;"; - execute(cqlFunction); - execute(cqlAggregate); - DseKeyspaceMetadata keyspace = getKeyspace(); - Optional aggregateOpt = keyspace.getAggregate("deta", DataTypes.INT); - assertThat(aggregateOpt.map(DseAggregateMetadata.class::cast)) - .hasValueSatisfying( - aggregate -> { - assertThat(aggregate.getDeterministic()).contains(true); - assertThat(aggregate.getStateType()).isEqualTo(DataTypes.INT); - assertThat(aggregate.describe(false)) - .isEqualTo( - String.format( - "CREATE AGGREGATE \"%s\".\"deta\"(int) SFUNC \"detf\" STYPE int INITCOND 0 DETERMINISTIC;", - keyspace.getName().asInternal())); - }); - } - - private static boolean isDse6OrHigher() { - assumeThat(CCM_RULE.isDistributionOf(BackendType.DSE)) - .describedAs("DSE required for DseFunctionMetadata tests") - .isTrue(); - return CCM_RULE.getDistributionVersion().compareTo(DSE_6_0_0) >= 0; - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/metadata/schema/DseFunctionMetadataIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/metadata/schema/DseFunctionMetadataIT.java deleted file mode 100644 index 13c2a0fa4b2..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/metadata/schema/DseFunctionMetadataIT.java +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.metadata.schema; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assumptions.assumeThat; - -import com.datastax.dse.driver.api.core.metadata.schema.DseFunctionMetadata.Monotonicity; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.Version; -import com.datastax.oss.driver.api.core.metadata.schema.FunctionMetadata; -import com.datastax.oss.driver.api.core.type.DataTypes; -import com.datastax.oss.driver.api.testinfra.ccm.CcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import com.datastax.oss.driver.categories.ParallelizableTests; -import java.util.Objects; -import java.util.Optional; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; - -@Category(ParallelizableTests.class) -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "5.0", - description = "DSE 5.0+ required function/aggregate support") -public class DseFunctionMetadataIT extends AbstractMetadataIT { - - private static final CcmRule CCM_RULE = CcmRule.getInstance(); - - private static final SessionRule SESSION_RULE = SessionRule.builder(CCM_RULE).build(); - - @ClassRule - public static final TestRule CHAIN = RuleChain.outerRule(CCM_RULE).around(SESSION_RULE); - - private static final Version DSE_6_0_0 = Objects.requireNonNull(Version.parse("6.0.0")); - - @Override - public SessionRule getSessionRule() { - return DseFunctionMetadataIT.SESSION_RULE; - } - - @Test - public void should_parse_function_without_deterministic_or_monotonic() { - String cqlFunction = - "CREATE FUNCTION nondetf(i int) RETURNS NULL ON NULL INPUT RETURNS int LANGUAGE java AS 'return new java.util.Random().nextInt(i);';"; - execute(cqlFunction); - DseKeyspaceMetadata keyspace = getKeyspace(); - Optional functionOpt = keyspace.getFunction("nondetf", DataTypes.INT); - assertThat(functionOpt.map(DseFunctionMetadata.class::cast)) - .hasValueSatisfying( - function -> { - if (isDse6OrHigher()) { - assertThat(function.getDeterministic()).contains(false); - assertThat(function.getMonotonicity()).contains(Monotonicity.NOT_MONOTONIC); - } else { - assertThat(function.getDeterministic()).isEmpty(); - assertThat(function.getMonotonicity()).isEmpty(); - } - assertThat(function.getMonotonicArgumentNames()).isEmpty(); - assertThat(function.getLanguage()).isEqualTo("java"); - assertThat(function.getReturnType()).isEqualTo(DataTypes.INT); - assertThat(function.getBody()).isEqualTo("return new java.util.Random().nextInt(i);"); - assertThat(function.describe(false)) - .isEqualTo( - String.format( - "CREATE FUNCTION \"%s\".\"nondetf\"(\"i\" int) RETURNS NULL ON NULL INPUT RETURNS int LANGUAGE java AS 'return new java.util.Random().nextInt(i);';", - keyspace.getName().asInternal())); - }); - } - - @Test - public void should_parse_function_with_deterministic() { - assumeThat(isDse6OrHigher()) - .describedAs("DSE 6.0+ required for DETERMINISTIC / MONOTONIC") - .isTrue(); - String cqlFunction = - "CREATE FUNCTION detf(i int, y int) RETURNS NULL ON NULL INPUT RETURNS int DETERMINISTIC LANGUAGE java AS 'return i+y;';"; - execute(cqlFunction); - DseKeyspaceMetadata keyspace = getKeyspace(); - Optional functionOpt = - keyspace.getFunction("detf", DataTypes.INT, DataTypes.INT); - assertThat(functionOpt.map(DseFunctionMetadata.class::cast)) - .hasValueSatisfying( - function -> { - assertThat(function.getDeterministic()).contains(true); - assertThat(function.getMonotonicity()).contains(Monotonicity.NOT_MONOTONIC); - assertThat(function.getMonotonicArgumentNames()).isEmpty(); - assertThat(function.getLanguage()).isEqualTo("java"); - assertThat(function.getReturnType()).isEqualTo(DataTypes.INT); - assertThat(function.getBody()).isEqualTo("return i+y;"); - assertThat(function.describe(false)) - .isEqualTo( - String.format( - "CREATE FUNCTION \"%s\".\"detf\"(\"i\" int,\"y\" int) RETURNS NULL ON NULL INPUT RETURNS int DETERMINISTIC LANGUAGE java AS 'return i+y;';", - keyspace.getName().asInternal())); - }); - } - - @Test - public void should_parse_function_with_monotonic() { - assumeThat(isDse6OrHigher()) - .describedAs("DSE 6.0+ required for DETERMINISTIC / MONOTONIC") - .isTrue(); - String cqlFunction = - "CREATE FUNCTION monotonic(dividend int, divisor int) CALLED ON NULL INPUT RETURNS int MONOTONIC LANGUAGE java AS 'return dividend / divisor;';"; - execute(cqlFunction); - DseKeyspaceMetadata keyspace = getKeyspace(); - Optional functionOpt = - keyspace.getFunction("monotonic", DataTypes.INT, DataTypes.INT); - assertThat(functionOpt.map(DseFunctionMetadata.class::cast)) - .hasValueSatisfying( - function -> { - assertThat(function.getDeterministic()).contains(false); - assertThat(function.getMonotonicity()).contains(Monotonicity.FULLY_MONOTONIC); - assertThat(function.getMonotonicArgumentNames()) - .containsExactly( - CqlIdentifier.fromCql("dividend"), CqlIdentifier.fromCql("divisor")); - assertThat(function.getLanguage()).isEqualTo("java"); - assertThat(function.getReturnType()).isEqualTo(DataTypes.INT); - assertThat(function.getBody()).isEqualTo("return dividend / divisor;"); - assertThat(function.describe(false)) - .isEqualTo( - String.format( - "CREATE FUNCTION \"%s\".\"monotonic\"(\"dividend\" int,\"divisor\" int) CALLED ON NULL INPUT RETURNS int MONOTONIC LANGUAGE java AS 'return dividend / divisor;';", - keyspace.getName().asInternal())); - }); - } - - @Test - public void should_parse_function_with_monotonic_on() { - assumeThat(isDse6OrHigher()) - .describedAs("DSE 6.0+ required for DETERMINISTIC / MONOTONIC") - .isTrue(); - String cqlFunction = - "CREATE FUNCTION monotonic_on(dividend int, divisor int) CALLED ON NULL INPUT RETURNS int MONOTONIC ON \"dividend\" LANGUAGE java AS 'return dividend / divisor;';"; - execute(cqlFunction); - DseKeyspaceMetadata keyspace = getKeyspace(); - Optional functionOpt = - keyspace.getFunction("monotonic_on", DataTypes.INT, DataTypes.INT); - assertThat(functionOpt.map(DseFunctionMetadata.class::cast)) - .hasValueSatisfying( - function -> { - assertThat(function.getDeterministic()).contains(false); - assertThat(function.getMonotonicity()).contains(Monotonicity.PARTIALLY_MONOTONIC); - assertThat(function.getMonotonicArgumentNames()) - .containsExactly(CqlIdentifier.fromCql("dividend")); - assertThat(function.getLanguage()).isEqualTo("java"); - assertThat(function.getReturnType()).isEqualTo(DataTypes.INT); - assertThat(function.getBody()).isEqualTo("return dividend / divisor;"); - assertThat(function.describe(false)) - .isEqualTo( - String.format( - "CREATE FUNCTION \"%s\".\"monotonic_on\"(\"dividend\" int,\"divisor\" int) CALLED ON NULL INPUT RETURNS int MONOTONIC ON \"dividend\" LANGUAGE java AS 'return dividend / divisor;';", - keyspace.getName().asInternal())); - }); - } - - @Test - public void should_parse_function_with_deterministic_and_monotonic() { - assumeThat(isDse6OrHigher()) - .describedAs("DSE 6.0+ required for DETERMINISTIC / MONOTONIC") - .isTrue(); - String cqlFunction = - "CREATE FUNCTION det_and_monotonic(dividend int, divisor int) CALLED ON NULL INPUT RETURNS int DETERMINISTIC MONOTONIC LANGUAGE java AS 'return dividend / divisor;';"; - execute(cqlFunction); - DseKeyspaceMetadata keyspace = getKeyspace(); - Optional functionOpt = - keyspace.getFunction("det_and_monotonic", DataTypes.INT, DataTypes.INT); - assertThat(functionOpt.map(DseFunctionMetadata.class::cast)) - .hasValueSatisfying( - function -> { - assertThat(function.getDeterministic()).contains(true); - assertThat(function.getMonotonicity()).contains(Monotonicity.FULLY_MONOTONIC); - assertThat(function.getMonotonicArgumentNames()) - .containsExactly( - CqlIdentifier.fromCql("dividend"), CqlIdentifier.fromCql("divisor")); - assertThat(function.getLanguage()).isEqualTo("java"); - assertThat(function.getReturnType()).isEqualTo(DataTypes.INT); - assertThat(function.getBody()).isEqualTo("return dividend / divisor;"); - assertThat(function.describe(false)) - .isEqualTo( - String.format( - "CREATE FUNCTION \"%s\".\"det_and_monotonic\"(\"dividend\" int,\"divisor\" int) CALLED ON NULL INPUT RETURNS int DETERMINISTIC MONOTONIC LANGUAGE java AS 'return dividend / divisor;';", - keyspace.getName().asInternal())); - }); - } - - @Test - public void should_parse_function_with_deterministic_and_monotonic_on() { - assumeThat(isDse6OrHigher()) - .describedAs("DSE 6.0+ required for DETERMINISTIC / MONOTONIC") - .isTrue(); - String cqlFunction = - "CREATE FUNCTION det_and_monotonic_on(dividend int, divisor int) CALLED ON NULL INPUT RETURNS int DETERMINISTIC MONOTONIC ON \"dividend\" LANGUAGE java AS 'return dividend / divisor;';"; - execute(cqlFunction); - DseKeyspaceMetadata keyspace = getKeyspace(); - Optional functionOpt = - keyspace.getFunction("det_and_monotonic_on", DataTypes.INT, DataTypes.INT); - assertThat(functionOpt.map(DseFunctionMetadata.class::cast)) - .hasValueSatisfying( - function -> { - assertThat(function.getDeterministic()).contains(true); - assertThat(function.getMonotonicity()).contains(Monotonicity.PARTIALLY_MONOTONIC); - assertThat(function.getMonotonicArgumentNames()) - .containsExactly(CqlIdentifier.fromCql("dividend")); - assertThat(function.getLanguage()).isEqualTo("java"); - assertThat(function.getReturnType()).isEqualTo(DataTypes.INT); - assertThat(function.getBody()).isEqualTo("return dividend / divisor;"); - assertThat(function.describe(false)) - .isEqualTo( - String.format( - "CREATE FUNCTION \"%s\".\"det_and_monotonic_on\"(\"dividend\" int,\"divisor\" int) CALLED ON NULL INPUT RETURNS int DETERMINISTIC MONOTONIC ON \"dividend\" LANGUAGE java AS 'return dividend / divisor;';", - keyspace.getName().asInternal())); - }); - } - - private static boolean isDse6OrHigher() { - assumeThat(CCM_RULE.isDistributionOf(BackendType.DSE)) - .describedAs("DSE required for DseFunctionMetadata tests") - .isTrue(); - return CCM_RULE.getDistributionVersion().compareTo(DSE_6_0_0) >= 0; - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/metadata/schema/KeyspaceGraphMetadataIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/metadata/schema/KeyspaceGraphMetadataIT.java deleted file mode 100644 index 49aba3adb40..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/metadata/schema/KeyspaceGraphMetadataIT.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.metadata.schema; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.metadata.Metadata; -import com.datastax.oss.driver.api.testinfra.ccm.CcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.CqlSessionRuleBuilder; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import com.datastax.oss.driver.categories.ParallelizableTests; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; - -@Category(ParallelizableTests.class) -@BackendRequirement(type = BackendType.DSE, minInclusive = "6.8") -public class KeyspaceGraphMetadataIT { - - private static final CcmRule CCM_RULE = CcmRule.getInstance(); - - private static final SessionRule SESSION_RULE = - new CqlSessionRuleBuilder(CCM_RULE).build(); - - @ClassRule - public static final TestRule CHAIN = RuleChain.outerRule(CCM_RULE).around(SESSION_RULE); - - @Test - public void should_expose_graph_engine_if_set() { - CqlSession session = SESSION_RULE.session(); - session.execute( - "CREATE KEYSPACE keyspace_metadata_it_graph_engine " - + "WITH replication = {'class': 'NetworkTopologyStrategy', 'dc1': 1} " - + "AND graph_engine = 'Core'"); - Metadata metadata = session.getMetadata(); - assertThat(metadata.getKeyspace("keyspace_metadata_it_graph_engine")) - .hasValueSatisfying( - keyspaceMetadata -> - assertThat(((DseGraphKeyspaceMetadata) keyspaceMetadata).getGraphEngine()) - .hasValue("Core")); - } - - @Test - public void should_expose_graph_engine_if_keyspace_altered() { - CqlSession session = SESSION_RULE.session(); - session.execute( - "CREATE KEYSPACE keyspace_metadata_it_graph_engine_alter " - + "WITH replication = {'class': 'NetworkTopologyStrategy', 'dc1': 1}"); - assertThat(session.getMetadata().getKeyspace("keyspace_metadata_it_graph_engine_alter")) - .hasValueSatisfying( - keyspaceMetadata -> - assertThat(((DseGraphKeyspaceMetadata) keyspaceMetadata).getGraphEngine()) - .isEmpty()); - - session.execute( - "ALTER KEYSPACE keyspace_metadata_it_graph_engine_alter WITH graph_engine = 'Core'"); - assertThat(session.getMetadata().getKeyspace("keyspace_metadata_it_graph_engine_alter")) - .hasValueSatisfying( - keyspaceMetadata -> - assertThat(((DseGraphKeyspaceMetadata) keyspaceMetadata).getGraphEngine()) - .hasValue("Core")); - } - - @Test - public void should_not_allow_classic_graph_engine_to_be_specified_on_keyspace() { - CqlSession session = SESSION_RULE.session(); - assertThatThrownBy( - () -> - session.execute( - "CREATE KEYSPACE keyspace_metadata_it_graph_engine_classic " - + "WITH replication = {'class': 'NetworkTopologyStrategy', 'dc1': 1} " - + "AND graph_engine = 'Classic'")) - .hasMessageContaining("Invalid/unknown graph engine name 'Classic'"); - } - - @Test - public void should_expose_core_graph_engine_if_set() { - CqlSession session = SESSION_RULE.session(); - session.execute( - "CREATE KEYSPACE keyspace_metadata_it_graph_engine_core " - + "WITH replication = {'class': 'NetworkTopologyStrategy', 'dc1': 1} " - + "AND graph_engine = 'Core'"); - Metadata metadata = session.getMetadata(); - assertThat(metadata.getKeyspace("keyspace_metadata_it_graph_engine_core")) - .hasValueSatisfying( - keyspaceMetadata -> - assertThat(((DseGraphKeyspaceMetadata) keyspaceMetadata).getGraphEngine()) - .hasValue("Core")); - } - - @Test - public void should_expose_empty_graph_engine_if_not_set() { - // The default keyspace created by CcmRule has no graph engine - Metadata metadata = SESSION_RULE.session().getMetadata(); - assertThat(metadata.getKeyspace(SESSION_RULE.keyspace())) - .hasValueSatisfying( - keyspaceMetadata -> - assertThat(((DseGraphKeyspaceMetadata) keyspaceMetadata).getGraphEngine()) - .isEmpty()); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/metadata/schema/TableGraphMetadataCaseSensitiveIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/metadata/schema/TableGraphMetadataCaseSensitiveIT.java deleted file mode 100644 index 35242294302..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/metadata/schema/TableGraphMetadataCaseSensitiveIT.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.metadata.schema; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.metadata.Metadata; -import com.datastax.oss.driver.api.testinfra.ccm.CcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.CqlSessionRuleBuilder; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import com.datastax.oss.driver.categories.ParallelizableTests; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; - -/** - * A regression test for a specific case of schema parsing for graphs built from tables containing - * case-sensitive column names in its tables. See JAVA-2492 for more information. - */ -@Category(ParallelizableTests.class) -@BackendRequirement(type = BackendType.DSE, minInclusive = "6.8") -public class TableGraphMetadataCaseSensitiveIT { - - private static final CcmRule CCM_RULE = CcmRule.getInstance(); - - private static final SessionRule SESSION_RULE = - new CqlSessionRuleBuilder(CCM_RULE).build(); - - @ClassRule - public static final TestRule CHAIN = RuleChain.outerRule(CCM_RULE).around(SESSION_RULE); - - @BeforeClass - public static void createTables() { - CqlSession session = SESSION_RULE.session(); - - session.execute( - "CREATE TABLE \"Person\" (\"Name\" varchar, \"Age\" int, PRIMARY KEY ((\"Name\"), \"Age\")) WITH VERTEX LABEL"); - session.execute( - "CREATE TABLE \"Software\" (\"Name\" varchar, \"Complexity\" int, PRIMARY KEY ((\"Name\"), \"Complexity\")) WITH VERTEX LABEL"); - session.execute( - "CREATE TABLE \"Created\"" - + " (\"PersonName\" varchar, \"SoftwareName\" varchar, \"PersonAge\" int, \"SoftwareComplexity\" int, weight int," - + " primary key ((\"PersonName\"), \"SoftwareName\", weight)) WITH EDGE LABEL\n" - + " FROM \"Person\"((\"PersonName\"),\"PersonAge\")" - + " TO \"Software\"((\"SoftwareName\"),\"SoftwareComplexity\");"); - } - - @Test - public void should_expose_case_sensitive_edge_metadata() { - CqlSession session = SESSION_RULE.session(); - Metadata metadata = session.getMetadata(); - assertThat(metadata.getKeyspace(SESSION_RULE.keyspace())) - .hasValueSatisfying( - keyspaceMetadata -> - assertThat(keyspaceMetadata.getTable(CqlIdentifier.fromInternal("Created"))) - .hasValueSatisfying( - created -> { - DseGraphTableMetadata dseCreated = (DseGraphTableMetadata) created; - assertThat(dseCreated.getEdge()) - .hasValueSatisfying( - edge -> { - assertThat(edge.getFromPartitionKeyColumns()) - .isEqualTo( - ImmutableList.of( - CqlIdentifier.fromInternal("PersonName"))); - assertThat(edge.getToPartitionKeyColumns()) - .isEqualTo( - ImmutableList.of( - CqlIdentifier.fromInternal("SoftwareName"))); - assertThat(edge.getFromClusteringColumns()) - .isEqualTo( - ImmutableList.of( - CqlIdentifier.fromInternal("PersonAge"))); - assertThat(edge.getToClusteringColumns()) - .isEqualTo( - ImmutableList.of( - CqlIdentifier.fromInternal("SoftwareComplexity"))); - }); - })); - } -} diff --git a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/metadata/schema/TableGraphMetadataIT.java b/integration-tests/src/test/java/com/datastax/dse/driver/api/core/metadata/schema/TableGraphMetadataIT.java deleted file mode 100644 index 51a2204800e..00000000000 --- a/integration-tests/src/test/java/com/datastax/dse/driver/api/core/metadata/schema/TableGraphMetadataIT.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.core.metadata.schema; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.metadata.Metadata; -import com.datastax.oss.driver.api.testinfra.ccm.CcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.CqlSessionRuleBuilder; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import com.datastax.oss.driver.categories.ParallelizableTests; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; - -@Category(ParallelizableTests.class) -@BackendRequirement(type = BackendType.DSE, minInclusive = "6.8") -public class TableGraphMetadataIT { - - private static final CcmRule CCM_RULE = CcmRule.getInstance(); - - private static final SessionRule SESSION_RULE = - new CqlSessionRuleBuilder(CCM_RULE).build(); - - @ClassRule - public static final TestRule CHAIN = RuleChain.outerRule(CCM_RULE).around(SESSION_RULE); - - @BeforeClass - public static void createTables() { - CqlSession session = SESSION_RULE.session(); - - session.execute("CREATE TABLE person (name text PRIMARY KEY) WITH VERTEX LABEL"); - session.execute( - "CREATE TABLE software (company text, name text, version int, " - + "PRIMARY KEY ((company, name), version)) " - + "WITH VERTEX LABEL soft"); - session.execute( - "CREATE TABLE contributors (contributor text, company_name text, software_name text, " - + "software_version int, " - + "PRIMARY KEY(contributor, company_name, software_name, software_version)) " - + "WITH EDGE LABEL contrib " - + "FROM person(contributor) " - + "TO soft((company_name, software_name), software_version)"); - } - - @Test - public void should_expose_vertex_and_edge_metadata() { - CqlSession session = SESSION_RULE.session(); - Metadata metadata = session.getMetadata(); - assertThat(metadata.getKeyspace(SESSION_RULE.keyspace())) - .hasValueSatisfying( - keyspaceMetadata -> { - assertThat(keyspaceMetadata.getTable("person")) - .hasValueSatisfying( - person -> { - DseGraphTableMetadata dsePerson = (DseGraphTableMetadata) person; - assertThat(dsePerson.getVertex()) - .hasValueSatisfying( - vertex -> - assertThat(vertex.getLabelName()) - .isEqualTo(CqlIdentifier.fromInternal("person"))); - assertThat(dsePerson.getEdge()).isEmpty(); - }); - - assertThat(keyspaceMetadata.getTable("software")) - .hasValueSatisfying( - software -> { - DseGraphTableMetadata dseSoftware = (DseGraphTableMetadata) software; - assertThat(dseSoftware.getVertex()) - .hasValueSatisfying( - vertex -> - assertThat(vertex.getLabelName()) - .isEqualTo(CqlIdentifier.fromInternal("soft"))); - assertThat(dseSoftware.getEdge()).isEmpty(); - }); - - assertThat(keyspaceMetadata.getTable("contributors")) - .hasValueSatisfying( - contributors -> { - DseGraphTableMetadata dseContributors = - (DseGraphTableMetadata) contributors; - assertThat(dseContributors.getVertex()).isEmpty(); - assertThat(dseContributors.getEdge()) - .hasValueSatisfying( - edge -> { - assertThat(edge.getLabelName()) - .isEqualTo(CqlIdentifier.fromInternal("contrib")); - - assertThat(edge.getFromTable().asInternal()).isEqualTo("person"); - assertThat(edge.getFromLabel()) - .isEqualTo(CqlIdentifier.fromInternal("person")); - assertThat(edge.getFromPartitionKeyColumns()) - .containsExactly(CqlIdentifier.fromInternal("contributor")); - assertThat(edge.getFromClusteringColumns()).isEmpty(); - - assertThat(edge.getToTable().asInternal()).isEqualTo("software"); - assertThat(edge.getToLabel()) - .isEqualTo(CqlIdentifier.fromInternal("soft")); - assertThat(edge.getToPartitionKeyColumns()) - .containsExactly( - CqlIdentifier.fromInternal("company_name"), - CqlIdentifier.fromInternal("software_name")); - assertThat(edge.getToClusteringColumns()) - .containsExactly( - CqlIdentifier.fromInternal("software_version")); - }); - }); - }); - } -} diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/api/core/cloud/CloudIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/api/core/cloud/CloudIT.java deleted file mode 100644 index 81a191779ba..00000000000 --- a/integration-tests/src/test/java/com/datastax/oss/driver/api/core/cloud/CloudIT.java +++ /dev/null @@ -1,500 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.oss.driver.api.core.cloud; - -import static com.datastax.oss.driver.internal.core.util.LoggerTest.setupTestLogger; -import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; -import static com.github.tomakehurst.wiremock.client.WireMock.any; -import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; -import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; -import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.timeout; -import static org.mockito.Mockito.verify; - -import ch.qos.logback.classic.Level; -import ch.qos.logback.classic.spi.ILoggingEvent; -import com.datastax.oss.driver.api.core.AllNodesFailedException; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.auth.AuthenticationException; -import com.datastax.oss.driver.api.core.config.DefaultDriverOption; -import com.datastax.oss.driver.api.core.config.DriverConfigLoader; -import com.datastax.oss.driver.api.core.cql.ResultSet; -import com.datastax.oss.driver.api.core.session.SessionBuilder; -import com.datastax.oss.driver.api.testinfra.session.SessionUtils; -import com.datastax.oss.driver.categories.IsolatedTests; -import com.datastax.oss.driver.internal.core.config.cloud.CloudConfigFactory; -import com.datastax.oss.driver.internal.core.ssl.DefaultSslEngineFactory; -import com.datastax.oss.driver.internal.core.util.LoggerTest; -import com.github.tomakehurst.wiremock.junit.WireMockRule; -import java.io.IOException; -import java.io.InputStream; -import java.net.InetSocketAddress; -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Path; -import java.security.NoSuchAlgorithmException; -import java.util.Collections; -import java.util.List; -import javax.net.ssl.SSLContext; -import org.junit.ClassRule; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; -import org.junit.experimental.categories.Category; - -@Category(IsolatedTests.class) -@Ignore("Disabled because it is causing trouble in Jenkins CI") -public class CloudIT { - - private static final String BUNDLE_URL_PATH = "/certs/bundles/creds.zip"; - - @ClassRule public static SniProxyRule proxyRule = new SniProxyRule(); - - // Used only to host the secure connect bundle, for tests that require external URLs - @Rule - public WireMockRule wireMockRule = - new WireMockRule(wireMockConfig().dynamicPort().dynamicHttpsPort()); - - @Test - public void should_connect_to_proxy_using_path() { - ResultSet set; - Path bundle = proxyRule.getProxy().getDefaultBundlePath(); - try (CqlSession session = - CqlSession.builder() - .withAuthCredentials("cassandra", "cassandra") - .withCloudSecureConnectBundle(bundle) - .build()) { - set = session.execute("select * from system.local where key='local'"); - } - assertThat(set).isNotNull(); - } - - @Test - public void should_connect_and_log_info_that_config_json_with_username_password_was_provided() { - ResultSet set; - Path bundle = proxyRule.getProxy().getDefaultBundlePath(); - LoggerTest.LoggerSetup logger = setupTestLogger(CloudConfigFactory.class, Level.INFO); - - try (CqlSession session = - CqlSession.builder() - .withAuthCredentials("cassandra", "cassandra") - .withCloudSecureConnectBundle(bundle) - .build()) { - set = session.execute("select * from system.local where key='local'"); - verify(logger.appender, timeout(500).atLeast(1)) - .doAppend(logger.loggingEventCaptor.capture()); - assertThat( - logger.loggingEventCaptor.getAllValues().stream() - .map(ILoggingEvent::getFormattedMessage)) - .contains( - "The bundle contains config.json with username and/or password. Providing it in the bundle is deprecated and ignored."); - } - assertThat(set).isNotNull(); - } - - @Test - public void - should_fail_with_auth_error_when_connecting_using_bundle_with_username_password_in_config_json() { - Path bundle = proxyRule.getProxy().getDefaultBundlePath(); - - // fails with auth error because username/password from config.json is ignored - AllNodesFailedException exception = null; - try { - CqlSession.builder().withCloudSecureConnectBundle(bundle).build(); - } catch (AllNodesFailedException ex) { - exception = ex; - } - assertThat(exception).isNotNull(); - List errors = exception.getAllErrors().values().iterator().next(); - Throwable firstError = errors.get(0); - assertThat(firstError).isInstanceOf(AuthenticationException.class); - } - - @Test - public void should_connect_to_proxy_without_credentials() { - ResultSet set; - Path bundle = proxyRule.getProxy().getBundleWithoutCredentialsPath(); - try (CqlSession session = - CqlSession.builder() - .withCloudSecureConnectBundle(bundle) - .withAuthCredentials("cassandra", "cassandra") - .build()) { - set = session.execute("select * from system.local where key='local'"); - } - assertThat(set).isNotNull(); - } - - @Test - public void should_connect_to_proxy_using_non_normalized_path() { - Path bundle = proxyRule.getProxy().getBundlesRootPath().resolve("../bundles/creds-v1.zip"); - ResultSet set; - try (CqlSession session = - CqlSession.builder() - .withAuthCredentials("cassandra", "cassandra") - .withCloudSecureConnectBundle(bundle) - .build()) { - set = session.execute("select * from system.local where key='local'"); - } - assertThat(set).isNotNull(); - } - - @Test - public void should_connect_to_proxy_using_input_stream() throws IOException { - InputStream bundle = Files.newInputStream(proxyRule.getProxy().getDefaultBundlePath()); - ResultSet set; - try (CqlSession session = - CqlSession.builder() - .withAuthCredentials("cassandra", "cassandra") - .withCloudSecureConnectBundle(bundle) - .build()) { - set = session.execute("select * from system.local where key='local'"); - } - assertThat(set).isNotNull(); - } - - @Test - public void should_connect_to_proxy_using_URL() throws IOException { - // given - byte[] bundle = Files.readAllBytes(proxyRule.getProxy().getDefaultBundlePath()); - stubFor( - any(urlEqualTo(BUNDLE_URL_PATH)) - .willReturn( - aResponse() - .withStatus(200) - .withHeader("Content-Type", "application/octet-stream") - .withBody(bundle))); - URL bundleUrl = - new URL(String.format("http://localhost:%d%s", wireMockRule.port(), BUNDLE_URL_PATH)); - - // when - ResultSet set; - try (CqlSession session = - CqlSession.builder() - .withAuthCredentials("cassandra", "cassandra") - .withCloudSecureConnectBundle(bundleUrl) - .build()) { - - // then - set = session.execute("select * from system.local where key='local'"); - } - assertThat(set).isNotNull(); - } - - @Test - public void should_connect_to_proxy_using_absolute_path_provided_in_the_session_setting() { - // given - String bundle = proxyRule.getProxy().getDefaultBundlePath().toString(); - DriverConfigLoader loader = - DriverConfigLoader.programmaticBuilder() - .withString(DefaultDriverOption.CLOUD_SECURE_CONNECT_BUNDLE, bundle) - .build(); - // when - ResultSet set; - try (CqlSession session = - CqlSession.builder() - .withAuthCredentials("cassandra", "cassandra") - .withConfigLoader(loader) - .build()) { - - // then - set = session.execute("select * from system.local where key='local'"); - } - assertThat(set).isNotNull(); - } - - @Test - public void should_connect_to_proxy_using_non_normalized_path_provided_in_the_session_setting() { - // given - String bundle = - proxyRule.getProxy().getBundlesRootPath().resolve("../bundles/creds-v1.zip").toString(); - DriverConfigLoader loader = - DriverConfigLoader.programmaticBuilder() - .withString(DefaultDriverOption.CLOUD_SECURE_CONNECT_BUNDLE, bundle) - .build(); - // when - ResultSet set; - try (CqlSession session = - CqlSession.builder() - .withAuthCredentials("cassandra", "cassandra") - .withConfigLoader(loader) - .build()) { - - // then - set = session.execute("select * from system.local where key='local'"); - } - assertThat(set).isNotNull(); - } - - @Test - public void - should_connect_to_proxy_using_url_with_file_protocol_provided_in_the_session_setting() { - // given - String bundle = proxyRule.getProxy().getDefaultBundlePath().toString(); - DriverConfigLoader loader = - DriverConfigLoader.programmaticBuilder() - .withString(DefaultDriverOption.CLOUD_SECURE_CONNECT_BUNDLE, bundle) - .build(); - // when - ResultSet set; - try (CqlSession session = - CqlSession.builder() - .withAuthCredentials("cassandra", "cassandra") - .withConfigLoader(loader) - .build()) { - - // then - set = session.execute("select * from system.local where key='local'"); - } - assertThat(set).isNotNull(); - } - - @Test - public void should_connect_to_proxy_using_url_with_http_protocol_provided_in_the_session_setting() - throws IOException { - // given - byte[] bundle = Files.readAllBytes(proxyRule.getProxy().getDefaultBundlePath()); - stubFor( - any(urlEqualTo(BUNDLE_URL_PATH)) - .willReturn( - aResponse() - .withStatus(200) - .withHeader("Content-Type", "application/octet-stream") - .withBody(bundle))); - String bundleUrl = String.format("http://localhost:%d%s", wireMockRule.port(), BUNDLE_URL_PATH); - DriverConfigLoader loader = - DriverConfigLoader.programmaticBuilder() - .withString(DefaultDriverOption.CLOUD_SECURE_CONNECT_BUNDLE, bundleUrl) - .build(); - // when - ResultSet set; - try (CqlSession session = - CqlSession.builder() - .withAuthCredentials("cassandra", "cassandra") - .withConfigLoader(loader) - .build()) { - - // then - set = session.execute("select * from system.local where key='local'"); - } - assertThat(set).isNotNull(); - } - - @Test - public void - should_connect_and_log_info_when_contact_points_and_secure_bundle_used_programmatic() { - // given - LoggerTest.LoggerSetup logger = setupTestLogger(SessionBuilder.class, Level.INFO); - - Path bundle = proxyRule.getProxy().getBundleWithoutCredentialsPath(); - - try (CqlSession session = - CqlSession.builder() - .withCloudSecureConnectBundle(bundle) - .addContactPoint(new InetSocketAddress("127.0.0.1", 9042)) - .withAuthCredentials("cassandra", "cassandra") - .build(); ) { - - // when - ResultSet set = session.execute("select * from system.local where key='local'"); - // then - assertThat(set).isNotNull(); - verify(logger.appender, timeout(500).atLeast(1)) - .doAppend(logger.loggingEventCaptor.capture()); - assertThat( - logger.loggingEventCaptor.getAllValues().stream() - .map(ILoggingEvent::getFormattedMessage)) - .contains( - "Both a secure connect bundle and contact points were provided. These are mutually exclusive. The contact points from the secure bundle will have priority."); - - } finally { - logger.close(); - } - } - - @Test - public void should_connect_and_log_info_when_contact_points_and_secure_bundle_used_config() { - // given - LoggerTest.LoggerSetup logger = setupTestLogger(SessionBuilder.class, Level.INFO); - - DriverConfigLoader loader = - SessionUtils.configLoaderBuilder() - .withStringList( - DefaultDriverOption.CONTACT_POINTS, Collections.singletonList("localhost:9042")) - .build(); - - Path bundle = proxyRule.getProxy().getBundleWithoutCredentialsPath(); - - try (CqlSession session = - CqlSession.builder() - .withConfigLoader(loader) - .withCloudSecureConnectBundle(bundle) - .withAuthCredentials("cassandra", "cassandra") - .build(); ) { - - // when - ResultSet set = session.execute("select * from system.local where key='local'"); - // then - assertThat(set).isNotNull(); - verify(logger.appender, timeout(500).atLeast(1)) - .doAppend(logger.loggingEventCaptor.capture()); - assertThat( - logger.loggingEventCaptor.getAllValues().stream() - .map(ILoggingEvent::getFormattedMessage)) - .contains( - "Both a secure connect bundle and contact points were provided. These are mutually exclusive. The contact points from the secure bundle will have priority."); - - } finally { - logger.close(); - } - } - - @Test - public void should_connect_and_log_info_when_ssl_context_and_secure_bundle_used_programmatic() - throws NoSuchAlgorithmException { - // given - LoggerTest.LoggerSetup logger = setupTestLogger(SessionBuilder.class, Level.INFO); - - Path bundle = proxyRule.getProxy().getBundleWithoutCredentialsPath(); - - try (CqlSession session = - CqlSession.builder() - .withCloudSecureConnectBundle(bundle) - .withAuthCredentials("cassandra", "cassandra") - .withSslContext(SSLContext.getInstance("SSL")) - .build()) { - // when - ResultSet set = session.execute("select * from system.local where key='local'"); - // then - assertThat(set).isNotNull(); - verify(logger.appender, timeout(500).atLeast(1)) - .doAppend(logger.loggingEventCaptor.capture()); - assertThat( - logger.loggingEventCaptor.getAllValues().stream() - .map(ILoggingEvent::getFormattedMessage)) - .contains( - "Both a secure connect bundle and SSL options were provided. They are mutually exclusive. The SSL options from the secure bundle will have priority."); - } finally { - logger.close(); - } - } - - @Test - public void should_error_when_ssl_context_and_secure_bundle_used_config() - throws NoSuchAlgorithmException { - // given - LoggerTest.LoggerSetup logger = setupTestLogger(SessionBuilder.class, Level.INFO); - - DriverConfigLoader loader = - SessionUtils.configLoaderBuilder() - .withBoolean(DefaultDriverOption.RECONNECT_ON_INIT, true) - .withClass(DefaultDriverOption.SSL_ENGINE_FACTORY_CLASS, DefaultSslEngineFactory.class) - .build(); - - Path bundle = proxyRule.getProxy().getBundleWithoutCredentialsPath(); - - try (CqlSession session = - CqlSession.builder() - .withConfigLoader(loader) - .withCloudSecureConnectBundle(bundle) - .withAuthCredentials("cassandra", "cassandra") - .build()) { - // when - ResultSet set = session.execute("select * from system.local where key='local'"); - // then - assertThat(set).isNotNull(); - verify(logger.appender, timeout(500).atLeast(1)) - .doAppend(logger.loggingEventCaptor.capture()); - assertThat( - logger.loggingEventCaptor.getAllValues().stream() - .map(ILoggingEvent::getFormattedMessage)) - .contains( - "Both a secure connect bundle and SSL options were provided. They are mutually exclusive. The SSL options from the secure bundle will have priority."); - } finally { - logger.close(); - } - } - - @Test - public void - should_connect_and_log_info_when_local_data_center_and_secure_bundle_used_programmatic() { - // given - LoggerTest.LoggerSetup logger = setupTestLogger(SessionBuilder.class, Level.INFO); - - DriverConfigLoader loader = - SessionUtils.configLoaderBuilder() - .withString(DefaultDriverOption.LOAD_BALANCING_LOCAL_DATACENTER, "dc-ignore") - .build(); - - Path bundle = proxyRule.getProxy().getBundleWithoutCredentialsPath(); - - try (CqlSession session = - CqlSession.builder() - .withCloudSecureConnectBundle(bundle) - .withConfigLoader(loader) - .withAuthCredentials("cassandra", "cassandra") - .build(); ) { - - // when - ResultSet set = session.execute("select * from system.local where key='local'"); - // then - assertThat(set).isNotNull(); - verify(logger.appender, timeout(500).atLeast(1)) - .doAppend(logger.loggingEventCaptor.capture()); - assertThat( - logger.loggingEventCaptor.getAllValues().stream() - .map(ILoggingEvent::getFormattedMessage)) - .contains( - "Both a secure connect bundle and a local datacenter were provided. They are mutually exclusive. The local datacenter from the secure bundle will have priority."); - - } finally { - logger.close(); - } - } - - @Test - public void should_connect_and_log_info_when_local_data_center_and_secure_bundle_used_config() { - // given - LoggerTest.LoggerSetup logger = setupTestLogger(SessionBuilder.class, Level.INFO); - - Path bundle = proxyRule.getProxy().getBundleWithoutCredentialsPath(); - - try (CqlSession session = - CqlSession.builder() - .withCloudSecureConnectBundle(bundle) - .withLocalDatacenter("dc-ignored") - .withAuthCredentials("cassandra", "cassandra") - .build(); ) { - - // when - ResultSet set = session.execute("select * from system.local where key='local'"); - // then - assertThat(set).isNotNull(); - verify(logger.appender, timeout(500).atLeast(1)) - .doAppend(logger.loggingEventCaptor.capture()); - assertThat( - logger.loggingEventCaptor.getAllValues().stream() - .map(ILoggingEvent::getFormattedMessage)) - .contains( - "Both a secure connect bundle and a local datacenter were provided. They are mutually exclusive. The local datacenter from the secure bundle will have priority."); - - } finally { - logger.close(); - } - } -} diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/api/core/cloud/SniProxyRule.java b/integration-tests/src/test/java/com/datastax/oss/driver/api/core/cloud/SniProxyRule.java deleted file mode 100644 index fa009de78ae..00000000000 --- a/integration-tests/src/test/java/com/datastax/oss/driver/api/core/cloud/SniProxyRule.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.oss.driver.api.core.cloud; - -import org.junit.rules.ExternalResource; - -public class SniProxyRule extends ExternalResource { - - private final SniProxyServer proxy; - - public SniProxyRule() { - proxy = new SniProxyServer(); - } - - @Override - protected void before() { - proxy.startProxy(); - } - - @Override - protected void after() { - proxy.stopProxy(); - } - - public SniProxyServer getProxy() { - return proxy; - } -} diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/api/core/cloud/SniProxyServer.java b/integration-tests/src/test/java/com/datastax/oss/driver/api/core/cloud/SniProxyServer.java deleted file mode 100644 index 809354a7daf..00000000000 --- a/integration-tests/src/test/java/com/datastax/oss/driver/api/core/cloud/SniProxyServer.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.oss.driver.api.core.cloud; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.concurrent.TimeUnit; -import org.apache.commons.exec.CommandLine; -import org.apache.commons.exec.DefaultExecutor; -import org.apache.commons.exec.ExecuteStreamHandler; -import org.apache.commons.exec.ExecuteWatchdog; -import org.apache.commons.exec.Executor; -import org.apache.commons.exec.LogOutputStream; -import org.apache.commons.exec.PumpStreamHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class SniProxyServer { - - private static final Logger LOG = LoggerFactory.getLogger(SniProxyServer.class); - - private final Path proxyPath; - private final Path bundlesRootPath; - private final Path defaultBundlePath; - private final Path bundleWithoutCredentialsPath; - private final Path bundleWithoutClientCertificatesPath; - private final Path bundleWithInvalidCAPath; - private final Path bundleWithUnreachableMetadataServicePath; - - private volatile boolean running = false; - - public SniProxyServer() { - this(Paths.get(System.getProperty("proxy.path", "./"))); - } - - public SniProxyServer(Path proxyPath) { - this.proxyPath = proxyPath.normalize().toAbsolutePath(); - bundlesRootPath = proxyPath.resolve("certs/bundles/"); - defaultBundlePath = bundlesRootPath.resolve("creds-v1.zip"); - bundleWithoutCredentialsPath = bundlesRootPath.resolve("creds-v1-wo-creds.zip"); - bundleWithoutClientCertificatesPath = bundlesRootPath.resolve("creds-v1-wo-cert.zip"); - bundleWithInvalidCAPath = bundlesRootPath.resolve("creds-v1-invalid-ca.zip"); - bundleWithUnreachableMetadataServicePath = bundlesRootPath.resolve("creds-v1-unreachable.zip"); - } - - public void startProxy() { - CommandLine run = CommandLine.parse(proxyPath + "/run.sh"); - execute(run); - running = true; - } - - public void stopProxy() { - if (running) { - CommandLine findImageId = - CommandLine.parse("docker ps -a -q --filter ancestor=single_endpoint"); - String id = execute(findImageId); - CommandLine stop = CommandLine.parse("docker kill " + id); - execute(stop); - running = false; - } - } - - /** @return The root folder of the SNI proxy server docker image. */ - public Path getProxyPath() { - return proxyPath; - } - - /** - * @return The root folder where secure connect bundles exposed by this SNI proxy for testing - * purposes can be found. - */ - public Path getBundlesRootPath() { - return bundlesRootPath; - } - - /** - * @return The default secure connect bundle. It contains credentials and all certificates - * required to connect. - */ - public Path getDefaultBundlePath() { - return defaultBundlePath; - } - - /** @return A secure connect bundle without credentials in config.json. */ - public Path getBundleWithoutCredentialsPath() { - return bundleWithoutCredentialsPath; - } - - /** @return A secure connect bundle without client certificates (no identity.jks). */ - public Path getBundleWithoutClientCertificatesPath() { - return bundleWithoutClientCertificatesPath; - } - - /** @return A secure connect bundle with an invalid Certificate Authority. */ - public Path getBundleWithInvalidCAPath() { - return bundleWithInvalidCAPath; - } - - /** @return A secure connect bundle with an invalid address for the Proxy Metadata Service. */ - public Path getBundleWithUnreachableMetadataServicePath() { - return bundleWithUnreachableMetadataServicePath; - } - - private String execute(CommandLine cli) { - LOG.debug("Executing: " + cli); - ExecuteWatchdog watchDog = new ExecuteWatchdog(TimeUnit.MINUTES.toMillis(10)); - ByteArrayOutputStream outStream = new ByteArrayOutputStream(); - try (LogOutputStream errStream = - new LogOutputStream() { - @Override - protected void processLine(String line, int logLevel) { - LOG.error("sniendpointerr> {}", line); - } - }) { - Executor executor = new DefaultExecutor(); - ExecuteStreamHandler streamHandler = new PumpStreamHandler(outStream, errStream); - executor.setStreamHandler(streamHandler); - executor.setWatchdog(watchDog); - executor.setWorkingDirectory(proxyPath.toFile()); - int retValue = executor.execute(cli); - if (retValue != 0) { - LOG.error("Non-zero exit code ({}) returned from executing ccm command: {}", retValue, cli); - } - return outStream.toString(); - } catch (IOException ex) { - if (watchDog.killedProcess()) { - throw new RuntimeException("The command '" + cli + "' was killed after 10 minutes"); - } else { - throw new RuntimeException("The command '" + cli + "' failed to execute", ex); - } - } - } -} diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/core/ProtocolVersionInitialNegotiationIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/core/ProtocolVersionInitialNegotiationIT.java index a05eff528af..8ae8d4a6cb9 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/core/ProtocolVersionInitialNegotiationIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/core/ProtocolVersionInitialNegotiationIT.java @@ -26,7 +26,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; -import com.datastax.dse.driver.api.core.DseProtocolVersion; import com.datastax.oss.driver.api.core.AllNodesFailedException; import com.datastax.oss.driver.api.core.CqlSession; import com.datastax.oss.driver.api.core.DefaultProtocolVersion; @@ -54,10 +53,6 @@ public class ProtocolVersionInitialNegotiationIT { minInclusive = "2.1", maxExclusive = "2.2", description = "Only C* in [2.1,2.2[ has V3 as its highest version") - @BackendRequirement( - type = BackendType.DSE, - maxExclusive = "5.0", - description = "Only DSE in [*,5.0[ has V3 as its highest version") @Test public void should_downgrade_to_v3() { try (CqlSession session = SessionUtils.newSession(ccm)) { @@ -71,11 +66,6 @@ public void should_downgrade_to_v3() { minInclusive = "2.2", maxExclusive = "4.0-rc1", description = "Only C* in [2.2,4.0-rc1[ has V4 as its highest version") - @BackendRequirement( - type = BackendType.DSE, - minInclusive = "5.0", - maxExclusive = "5.1", - description = "Only DSE in [5.0,5.1[ has V4 as its highest version") @BackendRequirement(type = BackendType.SCYLLA) @Test public void should_downgrade_to_v4() { @@ -97,27 +87,10 @@ public void should_downgrade_to_v5_oss() { } } - @BackendRequirement( - type = BackendType.DSE, - minInclusive = "5.1", - maxExclusive = "6.0", - description = "Only DSE in [5.1,6.0[ has DSE_V1 as its highest version") - @Test - public void should_downgrade_to_dse_v1() { - try (CqlSession session = SessionUtils.newSession(ccm)) { - assertThat(session.getContext().getProtocolVersion()).isEqualTo(DseProtocolVersion.DSE_V1); - session.execute("select * from system.local where key='local'"); - } - } - @BackendRequirement( type = BackendType.CASSANDRA, maxExclusive = "2.2", description = "Only C* in [*,2.2[ has V4 unsupported") - @BackendRequirement( - type = BackendType.DSE, - maxExclusive = "5.0", - description = "Only DSE in [*,5.0[ has V4 unsupported") @Test public void should_fail_if_provided_v4_is_not_supported() { DriverConfigLoader loader = @@ -141,10 +114,6 @@ public void should_fail_if_provided_v4_is_not_supported() { minInclusive = "2.1", maxExclusive = "4.0-rc1", description = "Only C* in [2.1,4.0-rc1[ has V5 unsupported or supported as beta") - @BackendRequirement( - type = BackendType.DSE, - maxExclusive = "7.0", - description = "Only DSE in [*,7.0[ has V5 unsupported or supported as beta") @Test public void should_fail_if_provided_v5_is_not_supported() { DriverConfigLoader loader = @@ -163,50 +132,6 @@ public void should_fail_if_provided_v5_is_not_supported() { } } - @BackendRequirement( - type = BackendType.DSE, - maxExclusive = "5.1", - description = "Only DSE in [*,5.1[ has DSE_V1 unsupported") - @Test - public void should_fail_if_provided_dse_v1_is_not_supported() { - DriverConfigLoader loader = - SessionUtils.configLoaderBuilder() - .withString(DefaultDriverOption.PROTOCOL_VERSION, "DSE_V1") - .build(); - try (CqlSession ignored = SessionUtils.newSession(ccm, loader)) { - fail("Expected an AllNodesFailedException"); - } catch (AllNodesFailedException anfe) { - Throwable cause = anfe.getAllErrors().values().iterator().next().get(0); - assertThat(cause).isInstanceOf(UnsupportedProtocolVersionException.class); - UnsupportedProtocolVersionException unsupportedException = - (UnsupportedProtocolVersionException) cause; - assertThat(unsupportedException.getAttemptedVersions()) - .containsOnly(DseProtocolVersion.DSE_V1); - } - } - - @BackendRequirement( - type = BackendType.DSE, - maxExclusive = "6.0", - description = "Only DSE in [*,6.0[ has DSE_V2 unsupported") - @Test - public void should_fail_if_provided_dse_v2_is_not_supported() { - DriverConfigLoader loader = - SessionUtils.configLoaderBuilder() - .withString(DefaultDriverOption.PROTOCOL_VERSION, "DSE_V2") - .build(); - try (CqlSession ignored = SessionUtils.newSession(ccm, loader)) { - fail("Expected an AllNodesFailedException"); - } catch (AllNodesFailedException anfe) { - Throwable cause = anfe.getAllErrors().values().iterator().next().get(0); - assertThat(cause).isInstanceOf(UnsupportedProtocolVersionException.class); - UnsupportedProtocolVersionException unsupportedException = - (UnsupportedProtocolVersionException) cause; - assertThat(unsupportedException.getAttemptedVersions()) - .containsOnly(DseProtocolVersion.DSE_V2); - } - } - /** Note that this test will need to be updated as new protocol versions are introduced. */ @BackendRequirement( type = BackendType.CASSANDRA, @@ -221,26 +146,10 @@ public void should_not_downgrade_if_server_supports_latest_version() { } /** Note that this test will need to be updated as new protocol versions are introduced. */ - @BackendRequirement( - type = BackendType.DSE, - minInclusive = "6.0", - description = "Only DSE in [6.0,*[ has DSE_V2 supported") - @Test - public void should_not_downgrade_if_server_supports_latest_version_dse() { - try (CqlSession session = SessionUtils.newSession(ccm)) { - assertThat(session.getContext().getProtocolVersion()).isEqualTo(ProtocolVersion.DSE_V2); - session.execute("select * from system.local where key='local'"); - } - } - @BackendRequirement( type = BackendType.CASSANDRA, minInclusive = "2.1", description = "Only C* in [2.1,*[ has V3 supported") - @BackendRequirement( - type = BackendType.DSE, - minInclusive = "4.8", - description = "Only DSE in [4.8,*[ has V3 supported") @BackendRequirement(type = BackendType.SCYLLA) @Test public void should_use_explicitly_provided_v3() { @@ -258,10 +167,6 @@ public void should_use_explicitly_provided_v3() { type = BackendType.CASSANDRA, minInclusive = "2.2", description = "Only C* in [2.2,*[ has V4 supported") - @BackendRequirement( - type = BackendType.DSE, - minInclusive = "5.0", - description = "Only DSE in [5.0,*[ has V4 supported") @BackendRequirement(type = BackendType.SCYLLA) @Test public void should_use_explicitly_provided_v4() { @@ -279,10 +184,6 @@ public void should_use_explicitly_provided_v4() { type = BackendType.CASSANDRA, minInclusive = "4.0", description = "Only C* in [4.0,*[ has V5 supported") - @BackendRequirement( - type = BackendType.DSE, - minInclusive = "7.0", - description = "Only DSE in [7.0,*[ has V5 supported") @Test public void should_use_explicitly_provided_v5() { DriverConfigLoader loader = @@ -294,36 +195,4 @@ public void should_use_explicitly_provided_v5() { session.execute("select * from system.local where key='local'"); } } - - @BackendRequirement( - type = BackendType.DSE, - minInclusive = "5.1", - description = "Only DSE in [5.1,*[ has DSE_V1 supported") - @Test - public void should_use_explicitly_provided_dse_v1() { - DriverConfigLoader loader = - SessionUtils.configLoaderBuilder() - .withString(DefaultDriverOption.PROTOCOL_VERSION, "DSE_V1") - .build(); - try (CqlSession session = SessionUtils.newSession(ccm, loader)) { - assertThat(session.getContext().getProtocolVersion()).isEqualTo(DseProtocolVersion.DSE_V1); - session.execute("select * from system.local where key='local'"); - } - } - - @BackendRequirement( - type = BackendType.DSE, - minInclusive = "6.0", - description = "Only DSE in [6.0,*[ has DSE_V2 supported") - @Test - public void should_use_explicitly_provided_dse_v2() { - DriverConfigLoader loader = - SessionUtils.configLoaderBuilder() - .withString(DefaultDriverOption.PROTOCOL_VERSION, "DSE_V2") - .build(); - try (CqlSession session = SessionUtils.newSession(ccm, loader)) { - assertThat(session.getContext().getProtocolVersion()).isEqualTo(DseProtocolVersion.DSE_V2); - session.execute("select * from system.local where key='local'"); - } - } } diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/core/compression/DirectCompressionIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/core/compression/DirectCompressionIT.java index 3dad08f4de6..60a8f117aa0 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/core/compression/DirectCompressionIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/core/compression/DirectCompressionIT.java @@ -77,8 +77,7 @@ public void should_execute_queries_with_snappy_compression() throws Exception { Assume.assumeTrue( "Snappy is not supported in OSS C* 4.0+ with protocol v5", !CCM_RULE.isDistributionOf(BackendType.HCD) - && (CCM_RULE.isDistributionOf(BackendType.DSE) - || CCM_RULE.getCassandraVersion().nextStable().compareTo(Version.V4_0_0) < 0)); + && CCM_RULE.getCassandraVersion().nextStable().compareTo(Version.V4_0_0) < 0); createAndCheckCluster("snappy"); } diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/core/compression/HeapCompressionIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/core/compression/HeapCompressionIT.java index 5624fa74f60..55c6453a6e0 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/core/compression/HeapCompressionIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/core/compression/HeapCompressionIT.java @@ -29,7 +29,6 @@ import com.datastax.oss.driver.api.core.cql.Row; import com.datastax.oss.driver.api.core.cql.SimpleStatement; import com.datastax.oss.driver.api.testinfra.ccm.CcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; import com.datastax.oss.driver.api.testinfra.session.SessionRule; import com.datastax.oss.driver.api.testinfra.session.SessionUtils; import com.datastax.oss.driver.categories.ParallelizableTests; @@ -80,8 +79,7 @@ public static void setup() { public void should_execute_queries_with_snappy_compression() throws Exception { Assume.assumeTrue( "Snappy is not supported in OSS C* 4.0+ with protocol v5", - CCM_RULE.isDistributionOf(BackendType.DSE) - || CCM_RULE.getCassandraVersion().nextStable().compareTo(Version.V4_0_0) < 0); + CCM_RULE.getCassandraVersion().nextStable().compareTo(Version.V4_0_0) < 0); createAndCheckCluster("snappy"); } diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/core/config/DriverConfigReportingSimulacronIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/core/config/DriverConfigReportingSimulacronIT.java index 262459f84a4..579ca96847a 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/core/config/DriverConfigReportingSimulacronIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/core/config/DriverConfigReportingSimulacronIT.java @@ -66,9 +66,9 @@ *

Assertions are scoped to the session's real connections, identified by the {@code CLIENT_ID} * startup option that the driver always sends (independently of config reporting). This excludes * the short-lived connections opened by protocol-version negotiation: when the protocol version is - * not pinned (the default), the driver first tries higher versions (DSE_V2, DSE_V1, V5) that - * ScyllaDB rejects before the handshake completes, and Simulacron records each such rejected - * attempt as a bare {@code STARTUP} ({@code CQL_VERSION} only) that carries no driver identity. + * not pinned (the default), the driver first tries V5, which ScyllaDB rejects before the handshake + * completes, and Simulacron records each such rejected attempt as a bare {@code STARTUP} ({@code + * CQL_VERSION} only) that carries no driver identity. */ @Category(ParallelizableTests.class) public class DriverConfigReportingSimulacronIT { diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/core/connection/NettyResourceLeakDetectionIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/core/connection/NettyResourceLeakDetectionIT.java index 98abec7b1f7..be0d3b73695 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/core/connection/NettyResourceLeakDetectionIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/core/connection/NettyResourceLeakDetectionIT.java @@ -126,9 +126,6 @@ public void should_not_leak_compressed_lz4() { } } - @BackendRequirement( - type = BackendType.DSE, - description = "Snappy is not supported in OSS C* 4.0+ with protocol v5") @BackendRequirement( type = BackendType.CASSANDRA, maxExclusive = "4.0.0", diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/core/cql/BoundStatementCcmIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/core/cql/BoundStatementCcmIT.java index c3520c72734..114d689f818 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/core/cql/BoundStatementCcmIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/core/cql/BoundStatementCcmIT.java @@ -311,7 +311,6 @@ public void should_use_page_size() { @Test @ScyllaSkip(description = "scylladb/scylla-driver#567 - fails by unknown reason") @BackendRequirement(type = BackendType.CASSANDRA) - @BackendRequirement(type = BackendType.DSE) public void should_propagate_attributes_when_preparing_a_simple_statement() { CqlSession session = sessionRule.session(); diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/core/cql/NowInSecondsIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/core/cql/NowInSecondsIT.java index 534eacb462c..faf67b74e96 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/core/cql/NowInSecondsIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/core/cql/NowInSecondsIT.java @@ -43,11 +43,6 @@ @Category(ParallelizableTests.class) @BackendRequirement(type = BackendType.CASSANDRA, minInclusive = "4.0") -// Use next version -- not sure if it will be in by then, but as a reminder to check -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "7.0", - description = "Feature not available in DSE yet") @ScyllaSkip(description = "scylladb/java-driver#573 - to be enabled") public class NowInSecondsIT { diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/core/cql/PreparedStatementIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/core/cql/PreparedStatementIT.java index bf22a59ae8b..6e9929e8c17 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/core/cql/PreparedStatementIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/core/cql/PreparedStatementIT.java @@ -590,12 +590,6 @@ public void should_create_separate_instances_for_different_statement_parameters( } } - // Add version bounds to the DSE requirement if there is a version containing fix for - // CASSANDRA-15252 - - @BackendRequirement( - type = BackendType.DSE, - description = "No DSE version contains fix for CASSANDRA-15252") @BackendRequirement(type = BackendType.CASSANDRA, minInclusive = "3.0.0", maxExclusive = "3.0.26") @BackendRequirement( type = BackendType.CASSANDRA, diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/core/cql/QueryTraceIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/core/cql/QueryTraceIT.java index c7a4602ef95..79318b78c3a 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/core/cql/QueryTraceIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/core/cql/QueryTraceIT.java @@ -90,7 +90,6 @@ public void should_fetch_trace_when_tracing_enabled() { InetAddress nodeAddress = ((InetSocketAddress) contactPoint.resolve()).getAddress(); boolean expectPorts = CCM_RULE.getCassandraVersion().nextStable().compareTo(Version.V4_0_0) >= 0 - && !CCM_RULE.isDistributionOf(BackendType.DSE) && !CCM_RULE.isDistributionOf(BackendType.SCYLLA); QueryTrace queryTrace = executionInfo.getQueryTrace(); diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/core/metadata/CaseSensitiveUdtIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/core/metadata/CaseSensitiveUdtIT.java index dae94221c46..053afdc5b85 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/core/metadata/CaseSensitiveUdtIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/core/metadata/CaseSensitiveUdtIT.java @@ -57,7 +57,6 @@ @Category(ParallelizableTests.class) @ScyllaSkip(description = "java-based UDFs are not supported") @BackendRequirement(type = BackendType.CASSANDRA) -@BackendRequirement(type = BackendType.DSE) public class CaseSensitiveUdtIT { private static final CcmRule CCM_RULE = CcmRule.getInstance(); diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/core/metadata/DescribeIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/core/metadata/DescribeIT.java index 0a298167b36..f315971fd06 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/core/metadata/DescribeIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/core/metadata/DescribeIT.java @@ -26,8 +26,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; -import com.datastax.dse.driver.internal.core.metadata.schema.DefaultDseKeyspaceMetadata; -import com.datastax.dse.driver.internal.core.metadata.schema.DefaultDseTableMetadata; import com.datastax.oss.driver.api.core.CqlSession; import com.datastax.oss.driver.api.core.Version; import com.datastax.oss.driver.api.core.config.DefaultDriverOption; @@ -68,7 +66,6 @@ @Category(ParallelizableTests.class) @ScyllaSkip(description = "scylladb/java-driver#566 - needs to be adopted to scylla") @BackendRequirement(type = BackendType.CASSANDRA) -@BackendRequirement(type = BackendType.DSE) public class DescribeIT { private static final Logger LOG = LoggerFactory.getLogger(DescribeIT.class); @@ -97,7 +94,6 @@ public class DescribeIT { private static final Map scriptFileForBackend = ImmutableMap.builder() .put(BackendType.CASSANDRA, "DescribeIT/oss") - .put(BackendType.DSE, "DescribeIT/dse") .put(BackendType.HCD, "DescribeIT/hcd") .build(); @@ -138,9 +134,8 @@ public void describe_output_should_match_creation_script() throws Exception { .isEqualTo(scriptContents); } - private boolean atLeastVersion(Version dseVersion, Version ossVersion) { - Version comparison = CCM_RULE.isDistributionOf(BackendType.DSE) ? dseVersion : ossVersion; - return serverVersion.compareTo(comparison) >= 0; + private boolean atLeastVersion(Version version) { + return serverVersion.compareTo(version) >= 0; } @Test @@ -152,15 +147,15 @@ public void keyspace_metadata_should_be_serializable() throws Exception { session.getMetadata().getKeyspace(session.getKeyspace().get()); assertThat(ksOption).isPresent(); KeyspaceMetadata ks = ksOption.get(); - assertThat(ks).isInstanceOfAny(DefaultKeyspaceMetadata.class, DefaultDseKeyspaceMetadata.class); + assertThat(ks).isInstanceOf(DefaultKeyspaceMetadata.class); /* Validate that the keyspace metadata is fully populated */ assertThat(ks.getUserDefinedTypes()).isNotEmpty(); assertThat(ks.getTables()).isNotEmpty(); - if (atLeastVersion(Version.V5_0_0, Version.V3_0_0)) { + if (atLeastVersion(Version.V3_0_0)) { assertThat(ks.getViews()).isNotEmpty(); } - if (atLeastVersion(Version.V5_0_0, Version.V2_2_0)) { + if (atLeastVersion(Version.V2_2_0)) { assertThat(ks.getFunctions()).isNotEmpty(); assertThat(ks.getAggregates()).isNotEmpty(); } @@ -169,7 +164,7 @@ public void keyspace_metadata_should_be_serializable() throws Exception { Optional tableOption = ks.getTable("rank_by_year_and_name"); assertThat(tableOption).isPresent(); TableMetadata table = tableOption.get(); - assertThat(table).isInstanceOfAny(DefaultTableMetadata.class, DefaultDseTableMetadata.class); + assertThat(table).isInstanceOf(DefaultTableMetadata.class); /* Validate that the table metadata is fully populated */ assertThat(table.getPartitionKey()).isNotEmpty(); diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/core/metadata/NodeMetadataIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/core/metadata/NodeMetadataIT.java index a45b6b2ea32..8eccc3f1f11 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/core/metadata/NodeMetadataIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/core/metadata/NodeMetadataIT.java @@ -26,14 +26,12 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.awaitility.Awaitility.await; -import com.datastax.dse.driver.api.core.metadata.DseNodeProperties; import com.datastax.oss.driver.api.core.CqlSession; import com.datastax.oss.driver.api.core.loadbalancing.NodeDistance; import com.datastax.oss.driver.api.core.metadata.Node; import com.datastax.oss.driver.api.core.metadata.NodeState; import com.datastax.oss.driver.api.testinfra.ccm.CcmBridge; import com.datastax.oss.driver.api.testinfra.ccm.CcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; import com.datastax.oss.driver.api.testinfra.requirement.BackendType; import com.datastax.oss.driver.api.testinfra.session.SessionUtils; import com.datastax.oss.driver.categories.ParallelizableTests; @@ -42,7 +40,6 @@ import com.datastax.oss.driver.internal.core.metadata.TopologyEvent; import java.net.InetSocketAddress; import java.util.Collection; -import java.util.Set; import java.util.concurrent.TimeUnit; import org.junit.Rule; import org.junit.Test; @@ -73,8 +70,7 @@ public void should_expose_node_metadata() { assertThat(node.getRack()).isEqualTo("r1"); } if (CcmBridge.isDistributionOf(BackendType.CASSANDRA)) { - // CcmBridge does not report accurate C* versions for other distributions (e.g. DSE), only - // approximated values + // CcmBridge reports exact Cassandra versions only for the Cassandra distribution. assertThat(node.getCassandraVersion()).isEqualTo(ccmRule.getCassandraVersion()); } assertThat(node.getState()).isSameAs(NodeState.UP); @@ -103,26 +99,6 @@ public void should_expose_node_metadata() { } } - @Test - @BackendRequirement(type = BackendType.DSE, minInclusive = "5.1") - public void should_expose_dse_node_properties() { - try (CqlSession session = SessionUtils.newSession(ccmRule)) { - - Node node = getUniqueNode(session); - - // Basic checks as we want something that will work with a large range of DSE versions: - assertThat(node.getExtras()) - .containsKeys( - DseNodeProperties.DSE_VERSION, - DseNodeProperties.DSE_WORKLOADS, - DseNodeProperties.SERVER_ID); - assertThat(node.getExtras().get(DseNodeProperties.DSE_VERSION)) - .isEqualTo(ccmRule.getDistributionVersion()); - assertThat(node.getExtras().get(DseNodeProperties.SERVER_ID)).isInstanceOf(String.class); - assertThat(node.getExtras().get(DseNodeProperties.DSE_WORKLOADS)).isInstanceOf(Set.class); - } - } - private static Node getUniqueNode(CqlSession session) { Collection nodes = session.getMetadata().getNodes().values(); assertThat(nodes).hasSize(1); diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/core/metadata/RandomTokenIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/core/metadata/RandomTokenIT.java index af5cfae0763..d1e79e16eb9 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/core/metadata/RandomTokenIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/core/metadata/RandomTokenIT.java @@ -40,7 +40,6 @@ @ScyllaSkip(description = "scylladb/java-driver#568 - fails to start scylla") @BackendRequirement(type = BackendType.CASSANDRA) -@BackendRequirement(type = BackendType.DSE) public class RandomTokenIT extends TokenITBase { private static final CustomCcmRule CCM_RULE = diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/core/metadata/SchemaChangesIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/core/metadata/SchemaChangesIT.java index 79cc53e5695..e522a3c782d 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/core/metadata/SchemaChangesIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/core/metadata/SchemaChangesIT.java @@ -61,10 +61,7 @@ public class SchemaChangesIT { static { CustomCcmRule.Builder builder = CustomCcmRule.builder(); - if (!CcmBridge.isDistributionOf( - BackendType.DSE, (dist, cass) -> cass.nextStable().compareTo(Version.V4_0_0) >= 0)) { - builder.withCassandraConfiguration("enable_materialized_views", true); - } + builder.withCassandraConfiguration("enable_materialized_views", true); CCM_RULE = builder.build(); } diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/core/metadata/SchemaIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/core/metadata/SchemaIT.java index c6a0b1d0434..3d99ed7229c 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/core/metadata/SchemaIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/core/metadata/SchemaIT.java @@ -28,7 +28,6 @@ import com.datastax.oss.driver.api.core.CqlIdentifier; import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.Version; import com.datastax.oss.driver.api.core.config.DefaultDriverOption; import com.datastax.oss.driver.api.core.config.DriverConfigLoader; import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; @@ -50,9 +49,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.Map; -import java.util.Objects; import java.util.concurrent.TimeUnit; -import org.junit.AssumptionViolatedException; import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; @@ -62,9 +59,6 @@ @Category(ParallelizableTests.class) public class SchemaIT { - private static final Version DSE_MIN_VIRTUAL_TABLES = - Objects.requireNonNull(Version.parse("6.7.0")); - private final CcmRule ccmRule = CcmRule.getInstance(); private final SessionRule sessionRule = SessionRule.builder(ccmRule).build(); @@ -200,8 +194,6 @@ public void should_refresh_schema_manually() { description = "virtual tables introduced in 4.0") @Test public void should_get_virtual_metadata() { - skipIfDse60(); - DriverConfigLoader loader = SessionUtils.configLoaderBuilder() .withStringList( @@ -238,8 +230,8 @@ public void should_get_virtual_metadata() { assertThat(tm).isNotNull(); assertThat(tm.getName().toString()).isEqualTo("sstable_tasks"); assertThat(tm.isVirtual()).isTrue(); - // DSE 6.8+ reports 7 columns, Cassandra 4+ reports 8 columns - assertThat(tm.getColumns().size()).isGreaterThanOrEqualTo(7); + // Cassandra 4.0 reports 8 columns; newer versions add more. + assertThat(tm.getColumns().size()).isGreaterThanOrEqualTo(8); assertThat(tm.getIndexes().size()).isEqualTo(0); assertThat(tm.getPartitionKey().size()).isEqualTo(1); assertThat(tm.getPartitionKey().get(0).getName().toString()).isEqualTo("keyspace_name"); @@ -249,17 +241,6 @@ public void should_get_virtual_metadata() { assertThat(tm.getKeyspace()).isEqualTo(kmd.getName()); assertThat(tm.describe(true)) .isIn( - // DSE 6.8+ - "/* VIRTUAL TABLE system_views.sstable_tasks (\n" - + " keyspace_name text,\n" - + " table_name text,\n" - + " task_id uuid,\n" - + " kind text,\n" - + " progress bigint,\n" - + " total bigint,\n" - + " unit text,\n" - + " PRIMARY KEY (keyspace_name, table_name, task_id)\n" - + "); */", // Cassandra 4.0 "/* VIRTUAL TABLE system_views.sstable_tasks (\n" + " keyspace_name text,\n" @@ -314,8 +295,6 @@ public void should_get_virtual_metadata() { description = "virtual tables introduced in 4.0") @Test public void should_exclude_virtual_keyspaces_from_token_map() { - skipIfDse60(); - DriverConfigLoader loader = SessionUtils.configLoaderBuilder() .withStringList( @@ -338,12 +317,4 @@ public void should_exclude_virtual_keyspaces_from_token_map() { assertThat(tokenMap.getReplicasList(sessionRule.keyspace(), partitionKey)).isNotEmpty(); } } - - private void skipIfDse60() { - // Special case: DSE 6.0 reports C* 4.0 but does not support virtual tables - if (!ccmRule.isDistributionOf( - BackendType.DSE, (dist, cass) -> dist.compareTo(DSE_MIN_VIRTUAL_TABLES) >= 0)) { - throw new AssumptionViolatedException("DSE 6.0 does not support virtual tables"); - } - } } diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/core/session/RemovedNodeIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/core/session/RemovedNodeIT.java index e0f33291544..a58c35eac1c 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/core/session/RemovedNodeIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/core/session/RemovedNodeIT.java @@ -40,8 +40,7 @@ public class RemovedNodeIT { @ClassRule public static final CustomCcmRule CCM_RULE = CustomCcmRule.builder() - // We need 4 nodes to run this test against DSE, because it requires at least 3 nodes to - // maintain RF=3 for keyspace system_distributed + // Keep at least 3 nodes available to maintain RF=3 for keyspace system_distributed. .withNodes(4) .build(); diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/internal/core/util/concurrent/DriverBlockHoundIntegrationCcmIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/internal/core/util/concurrent/DriverBlockHoundIntegrationCcmIT.java deleted file mode 100644 index e0f058b00d0..00000000000 --- a/integration-tests/src/test/java/com/datastax/oss/driver/internal/core/util/concurrent/DriverBlockHoundIntegrationCcmIT.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.oss.driver.internal.core.util.concurrent; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Fail.fail; - -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.dse.driver.api.core.cql.continuous.ContinuousAsyncResultSet; -import com.datastax.dse.driver.api.core.cql.continuous.ContinuousPagingITBase; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.DriverTimeoutException; -import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; -import com.datastax.oss.driver.api.core.cql.Row; -import com.datastax.oss.driver.api.core.cql.SimpleStatement; -import com.datastax.oss.driver.api.testinfra.ccm.CustomCcmRule; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.api.testinfra.session.SessionRule; -import com.datastax.oss.driver.categories.IsolatedTests; -import java.time.Duration; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.ExecutionException; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import reactor.blockhound.BlockHound; -import reactor.core.publisher.Flux; -import reactor.core.scheduler.Schedulers; -import reactor.test.StepVerifier; - -/** - * This test exercises the driver with BlockHound installed and tests that the rules defined in - * {@link DriverBlockHoundIntegration} are being applied, and especially when continuous paging is - * used. - */ -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "5.1.0", - description = "Continuous paging is only available from 5.1.0 onwards") -@Category(IsolatedTests.class) -public class DriverBlockHoundIntegrationCcmIT extends ContinuousPagingITBase { - - private static final Logger LOGGER = - LoggerFactory.getLogger(DriverBlockHoundIntegrationCcmIT.class); - - private static final CustomCcmRule CCM_RULE = CustomCcmRule.builder().build(); - - // Note: Insights monitoring will be detected by BlockHound, but the error is swallowed and - // logged by DefaultSession.SingleThreaded.notifyListeners, so it's not necessary to explicitly - // disable Insights here. - private static final SessionRule SESSION_RULE = SessionRule.builder(CCM_RULE).build(); - - @ClassRule public static TestRule chain = RuleChain.outerRule(CCM_RULE).around(SESSION_RULE); - - @BeforeClass - public static void setUp() { - try { - BlockHound.install(); - } catch (Throwable t) { - LOGGER.error("BlockHound could not be installed", t); - fail("BlockHound could not be installed", t); - } - initialize(SESSION_RULE.session(), SESSION_RULE.slowProfile()); - } - - @Test - public void should_not_detect_blocking_call_with_continuous_paging() { - CqlSession session = SESSION_RULE.session(); - SimpleStatement statement = SimpleStatement.newInstance("SELECT v from test where k=?", KEY); - Flux rows = - Flux.range(0, 10) - .flatMap( - i -> - Flux.fromIterable(session.executeContinuously(statement)) - .subscribeOn(Schedulers.parallel())); - StepVerifier.create(rows).expectNextCount(1000).expectComplete().verify(); - } - - /** Copied from com.datastax.dse.driver.api.core.cql.continuous.ContinuousPagingIT. */ - @Test - public void should_not_detect_blocking_call_with_continuous_paging_when_timeout() - throws Exception { - CqlSession session = SESSION_RULE.session(); - SimpleStatement statement = SimpleStatement.newInstance("SELECT v from test where k=?", KEY); - // Throttle server at a page per second and set client timeout much lower so that the client - // will experience a timeout. - // Note that this might not be perfect if there are pauses in the JVM and the timeout - // doesn't fire soon enough. - DriverExecutionProfile profile = - session - .getContext() - .getConfig() - .getDefaultProfile() - .withInt(DseDriverOption.CONTINUOUS_PAGING_PAGE_SIZE, 10) - .withInt(DseDriverOption.CONTINUOUS_PAGING_MAX_PAGES_PER_SECOND, 1) - .withDuration( - DseDriverOption.CONTINUOUS_PAGING_TIMEOUT_OTHER_PAGES, Duration.ofMillis(100)); - CompletionStage future = - session.executeContinuouslyAsync(statement.setExecutionProfile(profile)); - ContinuousAsyncResultSet pagingResult = CompletableFutures.getUninterruptibly(future); - try { - pagingResult.fetchNextPage().toCompletableFuture().get(); - fail("Expected a timeout"); - } catch (ExecutionException e) { - assertThat(e.getCause()) - .isInstanceOf(DriverTimeoutException.class) - .hasMessageContaining("Timed out waiting for page 2"); - } - } -} diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/mapper/DefaultKeyspaceIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/mapper/DefaultKeyspaceIT.java index 512da133f7c..ce97baef8cd 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/mapper/DefaultKeyspaceIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/mapper/DefaultKeyspaceIT.java @@ -129,7 +129,7 @@ public void should_fail_to_insert_if_default_ks_and_dao_ks_not_provided() { mapper.productDaoDefaultKsNotSet(); }) .isInstanceOf(InvalidQueryException.class); - // don't check the error message, as it's not consistent across Cassandra/DSE versions + // Don't check the error message because it varies across server versions. } @Test diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/mapper/DeleteReactiveIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/mapper/DeleteReactiveIT.java index 673a1283f47..fe410520303 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/mapper/DeleteReactiveIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/mapper/DeleteReactiveIT.java @@ -57,7 +57,7 @@ public class DeleteReactiveIT extends InventoryITBase { @ClassRule public static TestRule chain = RuleChain.outerRule(ccmRule).around(sessionRule); - private static DseProductDao dao; + private static ProductDao dao; @BeforeClass public static void setup() { @@ -68,8 +68,7 @@ public static void setup() { SimpleStatement.builder(query).setExecutionProfile(sessionRule.slowProfile()).build()); } - DseInventoryMapper inventoryMapper = - new DeleteReactiveIT_DseInventoryMapperBuilder(session).build(); + InventoryMapper inventoryMapper = new DeleteReactiveIT_InventoryMapperBuilder(session).build(); dao = inventoryMapper.productDao(sessionRule.keyspace()); } @@ -153,14 +152,14 @@ public void should_delete_with_condition_reactive() { } @Mapper - public interface DseInventoryMapper { + public interface InventoryMapper { @DaoFactory - DseProductDao productDao(@DaoKeyspace CqlIdentifier keyspace); + ProductDao productDao(@DaoKeyspace CqlIdentifier keyspace); } @Dao @DefaultNullSavingStrategy(NullSavingStrategy.SET_TO_NULL) - public interface DseProductDao { + public interface ProductDao { @Delete ReactiveResultSet deleteEntityReactive(Product product); diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/mapper/InsertReactiveIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/mapper/InsertReactiveIT.java index e9b9879fcb8..18308712c73 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/mapper/InsertReactiveIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/mapper/InsertReactiveIT.java @@ -55,7 +55,7 @@ public class InsertReactiveIT extends InventoryITBase { @ClassRule public static TestRule chain = RuleChain.outerRule(ccmRule).around(sessionRule); - private static DseProductDao dao; + private static ProductDao dao; @BeforeClass public static void setup() { @@ -66,9 +66,8 @@ public static void setup() { SimpleStatement.builder(query).setExecutionProfile(sessionRule.slowProfile()).build()); } - DseInventoryMapper dseInventoryMapper = - new InsertReactiveIT_DseInventoryMapperBuilder(session).build(); - dao = dseInventoryMapper.productDao(sessionRule.keyspace()); + InventoryMapper inventoryMapper = new InsertReactiveIT_InventoryMapperBuilder(session).build(); + dao = inventoryMapper.productDao(sessionRule.keyspace()); } @Before @@ -116,15 +115,15 @@ public void should_insert_entity_if_not_exists_reactive() { } @Mapper - public interface DseInventoryMapper { + public interface InventoryMapper { @DaoFactory - DseProductDao productDao(@DaoKeyspace CqlIdentifier keyspace); + ProductDao productDao(@DaoKeyspace CqlIdentifier keyspace); } @Dao @DefaultNullSavingStrategy(NullSavingStrategy.SET_TO_NULL) - public interface DseProductDao { + public interface ProductDao { @Insert ReactiveResultSet saveReactive(Product product); diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/mapper/InventoryITBase.java b/integration-tests/src/test/java/com/datastax/oss/driver/mapper/InventoryITBase.java index 5844b7dd5bb..20ff3c6226b 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/mapper/InventoryITBase.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/mapper/InventoryITBase.java @@ -82,7 +82,7 @@ protected static List createStatements(BaseCcmRule ccmRule, boolean requ "CREATE TABLE product_sale(id uuid, day text, ts uuid, customer_id int, price " + "double, count int, PRIMARY KEY ((id, day), customer_id, ts))"); - if (requiresSasiIndex && supportsSASI(ccmRule) && !isSasiBroken(ccmRule)) { + if (requiresSasiIndex && supportsSASI(ccmRule)) { builder.add( "CREATE CUSTOM INDEX product_description ON product(description) " + "USING 'org.apache.cassandra.index.sasi.SASIIndex' " @@ -102,13 +102,6 @@ protected static List createStatements(BaseCcmRule ccmRule, boolean requ private static final Version MINIMUM_SASI_VERSION = Objects.requireNonNull(Version.parse("3.4.0")); - private static final Version BROKEN_SASI_VERSION = Objects.requireNonNull(Version.parse("6.8.0")); - - protected static boolean isSasiBroken(BaseCcmRule ccmRule) { - // creating SASI indexes is broken in DSE 6.8.0 - return ccmRule.isDistributionOf( - BackendType.DSE, (dist, cass) -> dist.compareTo(BROKEN_SASI_VERSION) == 0); - } protected static boolean supportsSASI(BaseCcmRule ccmRule) { return ccmRule.getCassandraVersion().compareTo(MINIMUM_SASI_VERSION) >= 0 diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/mapper/QueryReactiveIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/mapper/QueryReactiveIT.java index d04ab5150ec..80cb23838b7 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/mapper/QueryReactiveIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/mapper/QueryReactiveIT.java @@ -57,7 +57,7 @@ public class QueryReactiveIT { @ClassRule public static TestRule chain = RuleChain.outerRule(ccmRule).around(sessionRule); - private static DseTestDao dao; + private static TestDao dao; @BeforeClass public static void setup() { @@ -98,12 +98,12 @@ public void should_query_reactive_mapped() { public interface TestMapper { @DaoFactory - DseTestDao productDao(@DaoKeyspace CqlIdentifier keyspace); + TestDao productDao(@DaoKeyspace CqlIdentifier keyspace); } @Dao @DefaultNullSavingStrategy(NullSavingStrategy.SET_TO_NULL) - public interface DseTestDao { + public interface TestDao { @Insert void insert(TestEntity entity); diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/mapper/SelectCustomWhereClauseIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/mapper/SelectCustomWhereClauseIT.java index dbe33c4be70..20d513920a7 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/mapper/SelectCustomWhereClauseIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/mapper/SelectCustomWhereClauseIT.java @@ -25,7 +25,6 @@ import static com.datastax.oss.driver.assertions.Assertions.assertThat; import static org.awaitility.Awaitility.await; -import static org.junit.Assume.assumeFalse; import com.datastax.oss.driver.api.core.CqlIdentifier; import com.datastax.oss.driver.api.core.CqlSession; @@ -73,10 +72,6 @@ public class SelectCustomWhereClauseIT extends InventoryITBase { @BeforeClass public static void setup() { - // SASI index creation is broken in DSE 6.8.0 - // All tests in this class require SASI, so ensure it's working - assumeFalse(InventoryITBase.isSasiBroken(CCM_RULE)); - CqlSession session = SESSION_RULE.session(); SchemaChangeSynchronizer.withLock( diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/mapper/SelectReactiveIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/mapper/SelectReactiveIT.java index 79e4d2b33ea..738028ab1a0 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/mapper/SelectReactiveIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/mapper/SelectReactiveIT.java @@ -56,7 +56,7 @@ public class SelectReactiveIT extends InventoryITBase { @ClassRule public static TestRule chain = RuleChain.outerRule(ccmRule).around(sessionRule); - private static DseProductDao dao; + private static ProductDao dao; @BeforeClass public static void setup() { @@ -72,8 +72,7 @@ public static void setup() { } }); - DseInventoryMapper inventoryMapper = - new SelectReactiveIT_DseInventoryMapperBuilder(session).build(); + InventoryMapper inventoryMapper = new SelectReactiveIT_InventoryMapperBuilder(session).build(); dao = inventoryMapper.productDao(sessionRule.keyspace()); } @@ -96,15 +95,15 @@ public void should_select_by_primary_key_reactive() { } @Mapper - public interface DseInventoryMapper { + public interface InventoryMapper { @DaoFactory - DseProductDao productDao(@DaoKeyspace CqlIdentifier keyspace); + ProductDao productDao(@DaoKeyspace CqlIdentifier keyspace); } @Dao @DefaultNullSavingStrategy(NullSavingStrategy.SET_TO_NULL) - public interface DseProductDao { + public interface ProductDao { @Select MappedReactiveResultSet findByIdReactive(UUID productId); diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/mapper/UpdateReactiveIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/mapper/UpdateReactiveIT.java index c52e80562d9..a5875ee620b 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/mapper/UpdateReactiveIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/mapper/UpdateReactiveIT.java @@ -68,7 +68,7 @@ public class UpdateReactiveIT extends InventoryITBase { @ClassRule public static TestRule chain = RuleChain.outerRule(ccmRule).around(sessionRule); - private static DseProductDao dao; + private static ProductDao dao; @BeforeClass public static void setup() { @@ -79,9 +79,8 @@ public static void setup() { SimpleStatement.builder(query).setExecutionProfile(sessionRule.slowProfile()).build()); } - DseInventoryMapper dseInventoryMapper = - new UpdateReactiveIT_DseInventoryMapperBuilder(session).build(); - dao = dseInventoryMapper.productDao(sessionRule.keyspace()); + InventoryMapper inventoryMapper = new UpdateReactiveIT_InventoryMapperBuilder(session).build(); + dao = inventoryMapper.productDao(sessionRule.keyspace()); } @Before @@ -152,15 +151,15 @@ public void should_not_update_entity_if_condition_is_not_met_reactive() { } @Mapper - public interface DseInventoryMapper { + public interface InventoryMapper { @DaoFactory - DseProductDao productDao(@DaoKeyspace CqlIdentifier keyspace); + ProductDao productDao(@DaoKeyspace CqlIdentifier keyspace); } @Dao @DefaultNullSavingStrategy(NullSavingStrategy.SET_TO_NULL) - public interface DseProductDao { + public interface ProductDao { @Update ReactiveResultSet updateReactive(Product product); diff --git a/integration-tests/src/test/resources/DescribeIT/dse/4.8.cql b/integration-tests/src/test/resources/DescribeIT/dse/4.8.cql deleted file mode 100644 index ea6ca93bcbf..00000000000 --- a/integration-tests/src/test/resources/DescribeIT/dse/4.8.cql +++ /dev/null @@ -1,67 +0,0 @@ - -CREATE KEYSPACE ks_0 WITH replication = { 'class' : 'org.apache.cassandra.locator.SimpleStrategy', 'replication_factor': '1' } AND durable_writes = true; - -CREATE TYPE ks_0.btype ( - a text -); - -CREATE TYPE ks_0.xtype ( - d text -); - -CREATE TYPE ks_0.ztype ( - c text, - a int -); - -CREATE TYPE ks_0.ctype ( - z frozen, - x frozen -); - -CREATE TYPE ks_0.atype ( - c frozen -); - -CREATE TABLE ks_0.rank_by_year_and_name ( - race_year int, - race_name text, - rank int, - cyclist_name text, - PRIMARY KEY ((race_year, race_name), rank) -) WITH CLUSTERING ORDER BY (rank DESC) - AND bloom_filter_fp_chance = 0.01 - AND caching = '{"keys":"ALL", "rows_per_partition":"NONE"}' - AND comment = '' - AND compaction = {'class':'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'} - AND compression = {'sstable_compression':'org.apache.cassandra.io.compress.LZ4Compressor'} - AND default_time_to_live = 0 - AND gc_grace_seconds = 864000 - AND dclocal_read_repair_chance = 0.1 - AND max_index_interval = 2048 - AND memtable_flush_period_in_ms = 0 - AND min_index_interval = 128 - AND read_repair_chance = 0.0 - AND speculative_retry = '99.0PERCENTILE'; - -CREATE INDEX ryear ON ks_0.rank_by_year_and_name (race_year); - -CREATE INDEX rrank ON ks_0.rank_by_year_and_name (rank); - -CREATE TABLE ks_0.ztable ( - zkey text, - a frozen, - PRIMARY KEY (zkey) -) WITH bloom_filter_fp_chance = 0.1 - AND caching = '{"keys":"ALL", "rows_per_partition":"NONE"}' - AND comment = '' - AND compaction = {'class':'org.apache.cassandra.db.compaction.LeveledCompactionStrategy','sstable_size_in_mb':'95'} - AND compression = {'sstable_compression':'org.apache.cassandra.io.compress.LZ4Compressor'} - AND default_time_to_live = 0 - AND gc_grace_seconds = 864000 - AND dclocal_read_repair_chance = 0.1 - AND max_index_interval = 2048 - AND memtable_flush_period_in_ms = 0 - AND min_index_interval = 128 - AND read_repair_chance = 0.0 - AND speculative_retry = '99.0PERCENTILE'; diff --git a/integration-tests/src/test/resources/DescribeIT/dse/5.0.cql b/integration-tests/src/test/resources/DescribeIT/dse/5.0.cql deleted file mode 100644 index 2572df52e24..00000000000 --- a/integration-tests/src/test/resources/DescribeIT/dse/5.0.cql +++ /dev/null @@ -1,189 +0,0 @@ - -CREATE KEYSPACE ks_0 WITH replication = { 'class' : 'org.apache.cassandra.locator.SimpleStrategy', 'replication_factor': '1' } AND durable_writes = true; - -CREATE TYPE ks_0.btype ( - a text -); - -CREATE TYPE ks_0.xtype ( - d text -); - -CREATE TYPE ks_0.ztype ( - c text, - a int -); - -CREATE TYPE ks_0.ctype ( - z frozen, - x frozen -); - -CREATE TYPE ks_0.atype ( - c frozen -); - -CREATE TABLE ks_0.cyclist_mv ( - cid uuid, - age int, - birthday date, - country text, - name text, - PRIMARY KEY (cid) -) WITH bloom_filter_fp_chance = 0.01 - AND caching = {'keys':'ALL','rows_per_partition':'NONE'} - AND comment = '' - AND compaction = {'class':'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy','max_threshold':'32','min_threshold':'4'} - AND compression = {'chunk_length_in_kb':'64','class':'org.apache.cassandra.io.compress.LZ4Compressor'} - AND crc_check_chance = 1.0 - AND dclocal_read_repair_chance = 0.1 - AND default_time_to_live = 0 - AND extensions = {} - AND gc_grace_seconds = 864000 - AND max_index_interval = 2048 - AND memtable_flush_period_in_ms = 0 - AND min_index_interval = 128 - AND read_repair_chance = 0.0 - AND speculative_retry = '99PERCENTILE'; - -CREATE INDEX cyclist_by_country ON ks_0.cyclist_mv (country); - -CREATE TABLE ks_0.rank_by_year_and_name ( - race_year int, - race_name text, - rank int, - cyclist_name text, - PRIMARY KEY ((race_year, race_name), rank) -) WITH CLUSTERING ORDER BY (rank DESC) - AND bloom_filter_fp_chance = 0.01 - AND caching = {'keys':'ALL','rows_per_partition':'NONE'} - AND comment = '' - AND compaction = {'class':'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy','max_threshold':'32','min_threshold':'4'} - AND compression = {'chunk_length_in_kb':'64','class':'org.apache.cassandra.io.compress.LZ4Compressor'} - AND crc_check_chance = 1.0 - AND dclocal_read_repair_chance = 0.1 - AND default_time_to_live = 0 - AND extensions = {} - AND gc_grace_seconds = 864000 - AND max_index_interval = 2048 - AND memtable_flush_period_in_ms = 0 - AND min_index_interval = 128 - AND read_repair_chance = 0.0 - AND speculative_retry = '99PERCENTILE'; - -CREATE INDEX rrank ON ks_0.rank_by_year_and_name (rank); - -CREATE INDEX ryear ON ks_0.rank_by_year_and_name (race_year); - -CREATE TABLE ks_0.ztable ( - zkey text, - a frozen, - PRIMARY KEY (zkey) -) WITH bloom_filter_fp_chance = 0.1 - AND caching = {'keys':'ALL','rows_per_partition':'NONE'} - AND comment = '' - AND compaction = {'class':'org.apache.cassandra.db.compaction.LeveledCompactionStrategy','sstable_size_in_mb':'95'} - AND compression = {'chunk_length_in_kb':'64','class':'org.apache.cassandra.io.compress.LZ4Compressor'} - AND crc_check_chance = 1.0 - AND dclocal_read_repair_chance = 0.1 - AND default_time_to_live = 0 - AND extensions = {} - AND gc_grace_seconds = 864000 - AND max_index_interval = 2048 - AND memtable_flush_period_in_ms = 0 - AND min_index_interval = 128 - AND read_repair_chance = 0.0 - AND speculative_retry = '99PERCENTILE'; - -CREATE MATERIALIZED VIEW ks_0.cyclist_by_a_age AS -SELECT * FROM ks_0.cyclist_mv -WHERE age IS NOT NULL AND cid IS NOT NULL -PRIMARY KEY (age, cid) WITH bloom_filter_fp_chance = 0.01 - AND caching = {'keys':'ALL','rows_per_partition':'NONE'} - AND comment = '' - AND compaction = {'class':'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy','max_threshold':'32','min_threshold':'4'} - AND compression = {'chunk_length_in_kb':'64','class':'org.apache.cassandra.io.compress.LZ4Compressor'} - AND crc_check_chance = 1.0 - AND dclocal_read_repair_chance = 0.1 - AND default_time_to_live = 0 - AND extensions = {} - AND gc_grace_seconds = 864000 - AND max_index_interval = 2048 - AND memtable_flush_period_in_ms = 0 - AND min_index_interval = 128 - AND read_repair_chance = 0.0 - AND speculative_retry = '99PERCENTILE'; - -CREATE MATERIALIZED VIEW ks_0.cyclist_by_age AS -SELECT - age, - cid, - birthday, - country, - name -FROM ks_0.cyclist_mv -WHERE age IS NOT NULL AND cid IS NOT NULL -PRIMARY KEY (age, cid) WITH bloom_filter_fp_chance = 0.01 - AND caching = {'keys':'ALL','rows_per_partition':'NONE'} - AND comment = 'simple view' - AND compaction = {'class':'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy','max_threshold':'32','min_threshold':'4'} - AND compression = {'chunk_length_in_kb':'64','class':'org.apache.cassandra.io.compress.LZ4Compressor'} - AND crc_check_chance = 1.0 - AND dclocal_read_repair_chance = 0.1 - AND default_time_to_live = 0 - AND extensions = {} - AND gc_grace_seconds = 864000 - AND max_index_interval = 2048 - AND memtable_flush_period_in_ms = 0 - AND min_index_interval = 128 - AND read_repair_chance = 0.0 - AND speculative_retry = '99PERCENTILE'; - -CREATE MATERIALIZED VIEW ks_0.cyclist_by_r_age AS -SELECT - age, - cid, - birthday, - country, - name -FROM ks_0.cyclist_mv -WHERE age IS NOT NULL AND cid IS NOT NULL -PRIMARY KEY (age, cid) WITH bloom_filter_fp_chance = 0.01 - AND caching = {'keys':'ALL','rows_per_partition':'NONE'} - AND comment = '' - AND compaction = {'class':'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy','max_threshold':'32','min_threshold':'4'} - AND compression = {'chunk_length_in_kb':'64','class':'org.apache.cassandra.io.compress.LZ4Compressor'} - AND crc_check_chance = 1.0 - AND dclocal_read_repair_chance = 0.1 - AND default_time_to_live = 0 - AND extensions = {} - AND gc_grace_seconds = 864000 - AND max_index_interval = 2048 - AND memtable_flush_period_in_ms = 0 - AND min_index_interval = 128 - AND read_repair_chance = 0.0 - AND speculative_retry = '99PERCENTILE'; - -CREATE FUNCTION ks_0.avgfinal(state tuple) - CALLED ON NULL INPUT - RETURNS double - LANGUAGE java - AS 'double r = 0; if (state.getInt(0) == 0) return null; r = state.getLong(1); r /= state.getInt(0); return Double.valueOf(r);'; - -CREATE FUNCTION ks_0.avgstate(state tuple,val int) - CALLED ON NULL INPUT - RETURNS tuple - LANGUAGE java - AS 'if (val !=null) { state.setInt(0, state.getInt(0)+1); state.setLong(1, state.getLong(1)+val.intValue()); } return state;'; - -CREATE AGGREGATE ks_0.average(int) - SFUNC avgstate - STYPE tuple - FINALFUNC avgfinal - INITCOND (0,0); - -CREATE AGGREGATE ks_0.mean(int) - SFUNC avgstate - STYPE tuple - FINALFUNC avgfinal - INITCOND (0,0); diff --git a/integration-tests/src/test/resources/DescribeIT/dse/5.1.cql b/integration-tests/src/test/resources/DescribeIT/dse/5.1.cql deleted file mode 100644 index 2572df52e24..00000000000 --- a/integration-tests/src/test/resources/DescribeIT/dse/5.1.cql +++ /dev/null @@ -1,189 +0,0 @@ - -CREATE KEYSPACE ks_0 WITH replication = { 'class' : 'org.apache.cassandra.locator.SimpleStrategy', 'replication_factor': '1' } AND durable_writes = true; - -CREATE TYPE ks_0.btype ( - a text -); - -CREATE TYPE ks_0.xtype ( - d text -); - -CREATE TYPE ks_0.ztype ( - c text, - a int -); - -CREATE TYPE ks_0.ctype ( - z frozen, - x frozen -); - -CREATE TYPE ks_0.atype ( - c frozen -); - -CREATE TABLE ks_0.cyclist_mv ( - cid uuid, - age int, - birthday date, - country text, - name text, - PRIMARY KEY (cid) -) WITH bloom_filter_fp_chance = 0.01 - AND caching = {'keys':'ALL','rows_per_partition':'NONE'} - AND comment = '' - AND compaction = {'class':'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy','max_threshold':'32','min_threshold':'4'} - AND compression = {'chunk_length_in_kb':'64','class':'org.apache.cassandra.io.compress.LZ4Compressor'} - AND crc_check_chance = 1.0 - AND dclocal_read_repair_chance = 0.1 - AND default_time_to_live = 0 - AND extensions = {} - AND gc_grace_seconds = 864000 - AND max_index_interval = 2048 - AND memtable_flush_period_in_ms = 0 - AND min_index_interval = 128 - AND read_repair_chance = 0.0 - AND speculative_retry = '99PERCENTILE'; - -CREATE INDEX cyclist_by_country ON ks_0.cyclist_mv (country); - -CREATE TABLE ks_0.rank_by_year_and_name ( - race_year int, - race_name text, - rank int, - cyclist_name text, - PRIMARY KEY ((race_year, race_name), rank) -) WITH CLUSTERING ORDER BY (rank DESC) - AND bloom_filter_fp_chance = 0.01 - AND caching = {'keys':'ALL','rows_per_partition':'NONE'} - AND comment = '' - AND compaction = {'class':'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy','max_threshold':'32','min_threshold':'4'} - AND compression = {'chunk_length_in_kb':'64','class':'org.apache.cassandra.io.compress.LZ4Compressor'} - AND crc_check_chance = 1.0 - AND dclocal_read_repair_chance = 0.1 - AND default_time_to_live = 0 - AND extensions = {} - AND gc_grace_seconds = 864000 - AND max_index_interval = 2048 - AND memtable_flush_period_in_ms = 0 - AND min_index_interval = 128 - AND read_repair_chance = 0.0 - AND speculative_retry = '99PERCENTILE'; - -CREATE INDEX rrank ON ks_0.rank_by_year_and_name (rank); - -CREATE INDEX ryear ON ks_0.rank_by_year_and_name (race_year); - -CREATE TABLE ks_0.ztable ( - zkey text, - a frozen, - PRIMARY KEY (zkey) -) WITH bloom_filter_fp_chance = 0.1 - AND caching = {'keys':'ALL','rows_per_partition':'NONE'} - AND comment = '' - AND compaction = {'class':'org.apache.cassandra.db.compaction.LeveledCompactionStrategy','sstable_size_in_mb':'95'} - AND compression = {'chunk_length_in_kb':'64','class':'org.apache.cassandra.io.compress.LZ4Compressor'} - AND crc_check_chance = 1.0 - AND dclocal_read_repair_chance = 0.1 - AND default_time_to_live = 0 - AND extensions = {} - AND gc_grace_seconds = 864000 - AND max_index_interval = 2048 - AND memtable_flush_period_in_ms = 0 - AND min_index_interval = 128 - AND read_repair_chance = 0.0 - AND speculative_retry = '99PERCENTILE'; - -CREATE MATERIALIZED VIEW ks_0.cyclist_by_a_age AS -SELECT * FROM ks_0.cyclist_mv -WHERE age IS NOT NULL AND cid IS NOT NULL -PRIMARY KEY (age, cid) WITH bloom_filter_fp_chance = 0.01 - AND caching = {'keys':'ALL','rows_per_partition':'NONE'} - AND comment = '' - AND compaction = {'class':'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy','max_threshold':'32','min_threshold':'4'} - AND compression = {'chunk_length_in_kb':'64','class':'org.apache.cassandra.io.compress.LZ4Compressor'} - AND crc_check_chance = 1.0 - AND dclocal_read_repair_chance = 0.1 - AND default_time_to_live = 0 - AND extensions = {} - AND gc_grace_seconds = 864000 - AND max_index_interval = 2048 - AND memtable_flush_period_in_ms = 0 - AND min_index_interval = 128 - AND read_repair_chance = 0.0 - AND speculative_retry = '99PERCENTILE'; - -CREATE MATERIALIZED VIEW ks_0.cyclist_by_age AS -SELECT - age, - cid, - birthday, - country, - name -FROM ks_0.cyclist_mv -WHERE age IS NOT NULL AND cid IS NOT NULL -PRIMARY KEY (age, cid) WITH bloom_filter_fp_chance = 0.01 - AND caching = {'keys':'ALL','rows_per_partition':'NONE'} - AND comment = 'simple view' - AND compaction = {'class':'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy','max_threshold':'32','min_threshold':'4'} - AND compression = {'chunk_length_in_kb':'64','class':'org.apache.cassandra.io.compress.LZ4Compressor'} - AND crc_check_chance = 1.0 - AND dclocal_read_repair_chance = 0.1 - AND default_time_to_live = 0 - AND extensions = {} - AND gc_grace_seconds = 864000 - AND max_index_interval = 2048 - AND memtable_flush_period_in_ms = 0 - AND min_index_interval = 128 - AND read_repair_chance = 0.0 - AND speculative_retry = '99PERCENTILE'; - -CREATE MATERIALIZED VIEW ks_0.cyclist_by_r_age AS -SELECT - age, - cid, - birthday, - country, - name -FROM ks_0.cyclist_mv -WHERE age IS NOT NULL AND cid IS NOT NULL -PRIMARY KEY (age, cid) WITH bloom_filter_fp_chance = 0.01 - AND caching = {'keys':'ALL','rows_per_partition':'NONE'} - AND comment = '' - AND compaction = {'class':'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy','max_threshold':'32','min_threshold':'4'} - AND compression = {'chunk_length_in_kb':'64','class':'org.apache.cassandra.io.compress.LZ4Compressor'} - AND crc_check_chance = 1.0 - AND dclocal_read_repair_chance = 0.1 - AND default_time_to_live = 0 - AND extensions = {} - AND gc_grace_seconds = 864000 - AND max_index_interval = 2048 - AND memtable_flush_period_in_ms = 0 - AND min_index_interval = 128 - AND read_repair_chance = 0.0 - AND speculative_retry = '99PERCENTILE'; - -CREATE FUNCTION ks_0.avgfinal(state tuple) - CALLED ON NULL INPUT - RETURNS double - LANGUAGE java - AS 'double r = 0; if (state.getInt(0) == 0) return null; r = state.getLong(1); r /= state.getInt(0); return Double.valueOf(r);'; - -CREATE FUNCTION ks_0.avgstate(state tuple,val int) - CALLED ON NULL INPUT - RETURNS tuple - LANGUAGE java - AS 'if (val !=null) { state.setInt(0, state.getInt(0)+1); state.setLong(1, state.getLong(1)+val.intValue()); } return state;'; - -CREATE AGGREGATE ks_0.average(int) - SFUNC avgstate - STYPE tuple - FINALFUNC avgfinal - INITCOND (0,0); - -CREATE AGGREGATE ks_0.mean(int) - SFUNC avgstate - STYPE tuple - FINALFUNC avgfinal - INITCOND (0,0); diff --git a/integration-tests/src/test/resources/DescribeIT/dse/6.8.cql b/integration-tests/src/test/resources/DescribeIT/dse/6.8.cql deleted file mode 100644 index bdeb4737748..00000000000 --- a/integration-tests/src/test/resources/DescribeIT/dse/6.8.cql +++ /dev/null @@ -1,201 +0,0 @@ - -CREATE KEYSPACE ks_0 WITH replication = { 'class' : 'org.apache.cassandra.locator.SimpleStrategy', 'replication_factor': '1' } AND durable_writes = true; - -CREATE TYPE ks_0.btype ( - a text -); - -CREATE TYPE ks_0.xtype ( - d text -); - -CREATE TYPE ks_0.ztype ( - c text, - a int -); - -CREATE TYPE ks_0.ctype ( - z frozen, - x frozen -); - -CREATE TYPE ks_0.atype ( - c frozen -); - -CREATE TABLE ks_0.cyclist_mv ( - cid uuid, - age int, - birthday date, - country text, - name text, - PRIMARY KEY (cid) -) WITH additional_write_policy = '99PERCENTILE' - AND bloom_filter_fp_chance = 0.01 - AND caching = {'keys':'ALL','rows_per_partition':'NONE'} - AND comment = '' - AND compaction = {'class':'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy','max_threshold':'32','min_threshold':'4'} - AND compression = {'chunk_length_in_kb':'64','class':'org.apache.cassandra.io.compress.LZ4Compressor'} - AND crc_check_chance = 1.0 - AND dclocal_read_repair_chance = 0.0 - AND default_time_to_live = 0 - AND extensions = {} - AND gc_grace_seconds = 864000 - AND max_index_interval = 2048 - AND memtable_flush_period_in_ms = 0 - AND min_index_interval = 128 - AND read_repair = 'BLOCKING' - AND read_repair_chance = 0.0 - AND speculative_retry = '99PERCENTILE'; - -CREATE INDEX cyclist_by_country ON ks_0.cyclist_mv (country); - -CREATE TABLE ks_0.rank_by_year_and_name ( - race_year int, - race_name text, - rank int, - cyclist_name text, - PRIMARY KEY ((race_year, race_name), rank) -) WITH CLUSTERING ORDER BY (rank DESC) - AND additional_write_policy = '99PERCENTILE' - AND bloom_filter_fp_chance = 0.01 - AND caching = {'keys':'ALL','rows_per_partition':'NONE'} - AND comment = '' - AND compaction = {'class':'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy','max_threshold':'32','min_threshold':'4'} - AND compression = {'chunk_length_in_kb':'64','class':'org.apache.cassandra.io.compress.LZ4Compressor'} - AND crc_check_chance = 1.0 - AND dclocal_read_repair_chance = 0.0 - AND default_time_to_live = 0 - AND extensions = {} - AND gc_grace_seconds = 864000 - AND max_index_interval = 2048 - AND memtable_flush_period_in_ms = 0 - AND min_index_interval = 128 - AND read_repair = 'BLOCKING' - AND read_repair_chance = 0.0 - AND speculative_retry = '99PERCENTILE'; - -CREATE INDEX rrank ON ks_0.rank_by_year_and_name (rank); - -CREATE INDEX ryear ON ks_0.rank_by_year_and_name (race_year); - -CREATE TABLE ks_0.ztable ( - zkey text, - a frozen, - PRIMARY KEY (zkey) -) WITH additional_write_policy = '99PERCENTILE' - AND bloom_filter_fp_chance = 0.1 - AND caching = {'keys':'ALL','rows_per_partition':'NONE'} - AND comment = '' - AND compaction = {'class':'org.apache.cassandra.db.compaction.LeveledCompactionStrategy','max_threshold':'32','min_threshold':'4','sstable_size_in_mb':'95'} - AND compression = {'chunk_length_in_kb':'64','class':'org.apache.cassandra.io.compress.LZ4Compressor'} - AND crc_check_chance = 1.0 - AND dclocal_read_repair_chance = 0.0 - AND default_time_to_live = 0 - AND extensions = {} - AND gc_grace_seconds = 864000 - AND max_index_interval = 2048 - AND memtable_flush_period_in_ms = 0 - AND min_index_interval = 128 - AND read_repair = 'BLOCKING' - AND read_repair_chance = 0.0 - AND speculative_retry = '99PERCENTILE'; - -CREATE MATERIALIZED VIEW ks_0.cyclist_by_a_age AS -SELECT * FROM ks_0.cyclist_mv -WHERE age IS NOT NULL AND cid IS NOT NULL -PRIMARY KEY (age, cid) WITH additional_write_policy = '99PERCENTILE' - AND bloom_filter_fp_chance = 0.01 - AND caching = {'keys':'ALL','rows_per_partition':'NONE'} - AND comment = '' - AND compaction = {'class':'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy','max_threshold':'32','min_threshold':'4'} - AND compression = {'chunk_length_in_kb':'64','class':'org.apache.cassandra.io.compress.LZ4Compressor'} - AND crc_check_chance = 1.0 - AND dclocal_read_repair_chance = 0.0 - AND default_time_to_live = 0 - AND extensions = {} - AND gc_grace_seconds = 864000 - AND max_index_interval = 2048 - AND memtable_flush_period_in_ms = 0 - AND min_index_interval = 128 - AND read_repair = 'BLOCKING' - AND read_repair_chance = 0.0 - AND speculative_retry = '99PERCENTILE'; - -CREATE MATERIALIZED VIEW ks_0.cyclist_by_age AS -SELECT - age, - cid, - birthday, - country, - name -FROM ks_0.cyclist_mv -WHERE age IS NOT NULL AND cid IS NOT NULL -PRIMARY KEY (age, cid) WITH additional_write_policy = '99PERCENTILE' - AND bloom_filter_fp_chance = 0.01 - AND caching = {'keys':'ALL','rows_per_partition':'NONE'} - AND comment = 'simple view' - AND compaction = {'class':'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy','max_threshold':'32','min_threshold':'4'} - AND compression = {'chunk_length_in_kb':'64','class':'org.apache.cassandra.io.compress.LZ4Compressor'} - AND crc_check_chance = 1.0 - AND dclocal_read_repair_chance = 0.0 - AND default_time_to_live = 0 - AND extensions = {} - AND gc_grace_seconds = 864000 - AND max_index_interval = 2048 - AND memtable_flush_period_in_ms = 0 - AND min_index_interval = 128 - AND read_repair = 'BLOCKING' - AND read_repair_chance = 0.0 - AND speculative_retry = '99PERCENTILE'; - -CREATE MATERIALIZED VIEW ks_0.cyclist_by_r_age AS -SELECT - age, - cid, - birthday, - country, - name -FROM ks_0.cyclist_mv -WHERE age IS NOT NULL AND cid IS NOT NULL -PRIMARY KEY (age, cid) WITH additional_write_policy = '99PERCENTILE' - AND bloom_filter_fp_chance = 0.01 - AND caching = {'keys':'ALL','rows_per_partition':'NONE'} - AND comment = '' - AND compaction = {'class':'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy','max_threshold':'32','min_threshold':'4'} - AND compression = {'chunk_length_in_kb':'64','class':'org.apache.cassandra.io.compress.LZ4Compressor'} - AND crc_check_chance = 1.0 - AND dclocal_read_repair_chance = 0.0 - AND default_time_to_live = 0 - AND extensions = {} - AND gc_grace_seconds = 864000 - AND max_index_interval = 2048 - AND memtable_flush_period_in_ms = 0 - AND min_index_interval = 128 - AND read_repair = 'BLOCKING' - AND read_repair_chance = 0.0 - AND speculative_retry = '99PERCENTILE'; - -CREATE FUNCTION ks_0.avgfinal(state tuple) - CALLED ON NULL INPUT - RETURNS double - LANGUAGE java - AS 'double r = 0; if (state.getInt(0) == 0) return null; r = state.getLong(1); r /= state.getInt(0); return Double.valueOf(r);'; - -CREATE FUNCTION ks_0.avgstate(state tuple,val int) - CALLED ON NULL INPUT - RETURNS tuple - LANGUAGE java - AS 'if (val !=null) { state.setInt(0, state.getInt(0)+1); state.setLong(1, state.getLong(1)+val.intValue()); } return state;'; - -CREATE AGGREGATE ks_0.average(int) - SFUNC avgstate - STYPE tuple - FINALFUNC avgfinal - INITCOND (0,0); - -CREATE AGGREGATE ks_0.mean(int) - SFUNC avgstate - STYPE tuple - FINALFUNC avgfinal - INITCOND (0,0); diff --git a/integration-tests/src/test/resources/application.conf b/integration-tests/src/test/resources/application.conf index f3ab31bcb76..93ef32ccf97 100644 --- a/integration-tests/src/test/resources/application.conf +++ b/integration-tests/src/test/resources/application.conf @@ -27,7 +27,6 @@ datastax-java-driver { } config-reload-interval = 0 request.timeout = 10 seconds - graph.timeout = 10 seconds } advanced { connection { @@ -40,13 +39,6 @@ datastax-java-driver { trace.interval = 1 second warn-if-set-keyspace = false } - graph { - name = "demo" - } - continuous-paging.timeout { - first-page = 10 seconds - other-pages = 10 seconds - } metrics { // Raise histogram bounds because the tests execute DDL queries with a higher timeout session.cql_requests.highest_latency = 30 seconds diff --git a/integration-tests/src/test/resources/logback-test.xml b/integration-tests/src/test/resources/logback-test.xml index a2179e4357b..4cf4574efcd 100644 --- a/integration-tests/src/test/resources/logback-test.xml +++ b/integration-tests/src/test/resources/logback-test.xml @@ -27,9 +27,9 @@ - - + + diff --git a/manual/core/address_resolution/README.md b/manual/core/address_resolution/README.md index ae44feea3ea..543aeedbfee 100644 --- a/manual/core/address_resolution/README.md +++ b/manual/core/address_resolution/README.md @@ -130,9 +130,8 @@ Note that `OptionsMap`-based configuration does not support client routes — us API (`SessionBuilder.withClientRoutesConfig()`) instead, which can be combined with `OptionsMap` for all other driver options. -Client routes are **mutually exclusive** with: -- A custom `AddressTranslator` (if both are provided, an `IllegalStateException` is thrown) -- Cloud secure connect bundles (if both are provided, an `IllegalStateException` is thrown) +Client routes are **mutually exclusive** with a custom `AddressTranslator`; if both are provided, +an `IllegalStateException` is thrown. #### Quick start (programmatic) @@ -203,7 +202,7 @@ the JVM DNS cache TTL via the `networkaddress.cache.ttl` security property (e.g. - Requires ScyllaDB Enterprise ≥ 2026.1 with `system.client_routes` support (scylladb/scylladb#27323). Not yet available on ScyllaDB OSS. - Not supported on Apache Cassandra. -- Mutually exclusive with custom `AddressTranslator` and with cloud secure connect bundles. +- Mutually exclusive with a custom `AddressTranslator`. ### Fixed proxy hostname If your client applications access Cassandra through some kind of proxy (eg. with AWS PrivateLink when all Cassandra diff --git a/manual/core/authentication/README.md b/manual/core/authentication/README.md index 516e47f558f..49ff6b3e6ac 100644 --- a/manual/core/authentication/README.md +++ b/manual/core/authentication/README.md @@ -22,7 +22,7 @@ under the License. ### Quick overview * `advanced.auth-provider` in the configuration. -* disabled by default. Also available: plain-text credentials, GSSAPI (DSE only), or write your own. +* disabled by default. Use plain-text credentials or write a custom provider. * can also be defined programmatically: [CqlSession.builder().withAuthCredentials][SessionBuilder.withAuthCredentials] or [CqlSession.builder().withAuthProvider][SessionBuilder.withAuthProvider]. @@ -64,44 +64,6 @@ datastax-java-driver { } ``` -When connecting to DSE, an optional `authorization-id` can also be specified. It will be used for -proxy authentication (logging in as another user or role). If you try to use this feature with an -authenticator that doesn't support it, the authorization id will be ignored. - -``` -datastax-java-driver { - advanced.auth-provider { - class = PlainTextAuthProvider - username = user - password = pass - authorization-id = otherUserOrRole - } -} -``` - -Note that, for backward compatibility with previous driver versions, you can also use the class name -`DsePlainTextAuthProvider` to enable this provider. - -#### GSSAPI (DSE only) - -`DseGssApiAuthProvider` supports GSSAPI authentication against a DSE cluster secured with Kerberos: - -``` -datastax-java-driver { - advanced.auth-provider { - class = DseGssApiAuthProvider - login-configuration { - principal = "user principal here ex cassandra@DATASTAX.COM" - useKeyTab = "true" - refreshKrb5Config = "true" - keyTab = "Path to keytab file here" - } - } - } -``` - -See the comments in [reference.conf] for more details. - #### Custom You can also write your own provider; it must implement [AuthProvider] and declare a public @@ -140,19 +102,13 @@ CqlSession session = .build(); ``` -For convenience, there are shortcuts that take the credentials directly: +For convenience, the credentials can be passed directly: ```java CqlSession session = CqlSession.builder() .withAuthCredentials("user", "pass") .build(); - -// With proxy authentication (DSE only) -CqlSession session = - CqlSession.builder() - .withAuthCredentials("user", "pass", "otherUserOrRole") - .build(); ``` One downside of the driver's built-in authentication providers is that the credentials are stored in @@ -160,99 +116,12 @@ clear text in memory; this means they are vulnerable to an attacker who is able dumps. If this is not acceptable for you, consider writing your own [AuthProvider] implementation; [PlainTextAuthProviderBase] is a good starting point. -Similarly, [ProgrammaticDseGssApiAuthProvider] lets you configure GSSAPI programmatically: - -```java -import com.datastax.dse.driver.api.core.auth.DseGssApiAuthProviderBase.GssApiOptions; - -javax.security.auth.Subject subject = ...; // do your Kerberos configuration here - -GssApiOptions options = GssApiOptions.builder().withSubject(subject).build(); -CqlSession session = CqlSession.builder() - .withAuthProvider(new ProgrammaticDseGssApiAuthProvider(options)) - .build(); -``` - -For more complex needs (e.g. if building the options once and reusing them doesn't work for you), -you can subclass [DseGssApiAuthProviderBase]. - -### Proxy authentication - -DSE allows a user to connect as another user or role: - -``` --- Allow bob to connect as alice: -GRANT PROXY.LOGIN ON ROLE 'alice' TO 'bob' -``` - -Once connected, all authorization checks will be performed against the proxy role (alice in this -example). - -To use proxy authentication with the driver, you need to provide the **authorization-id**, in other -words the name of the role you want to connect as. - -Example for plain text authentication: - -``` -datastax-java-driver { - advanced.auth-provider { - class = PlainTextAuthProvider - username = bob - password = bob's password - authorization-id = alice - } - } -``` - -With the GSSAPI (Kerberos) provider: - -``` -datastax-java-driver { - advanced.auth-provider { - class = DseGssApiAuthProvider - authorization-id = alice - login-configuration { - principal = "user principal here ex bob@DATASTAX.COM" - useKeyTab = "true" - refreshKrb5Config = "true" - keyTab = "Path to keytab file here" - } - } - } -``` - -### Proxy execution - -Proxy execution is similar to proxy authentication, but it applies to a single query, not the whole -session. - -``` --- Allow bob to execute queries as alice: -GRANT PROXY.EXECUTE ON ROLE 'alice' TO 'bob' -``` - -For this scenario, you would **not** add the `authorization-id = alice` to your configuration. -Instead, use [ProxyAuthentication.executeAs] to wrap your query with the correct authorization for -the execution: - -```java -import com.datastax.dse.driver.api.core.auth.ProxyAuthentication; - -SimpleStatement statement = SimpleStatement.newInstance("some query"); -// executeAs returns a new instance, you need to re-assign -statement = ProxyAuthentication.executeAs("alice", statement); -session.execute(statement); -``` - [SASL]: https://en.wikipedia.org/wiki/Simple_Authentication_and_Security_Layer [AuthProvider]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/oss/driver/api/core/auth/AuthProvider.html [DriverContext]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/oss/driver/api/core/context/DriverContext.html [PlainTextAuthProviderBase]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/oss/driver/api/core/auth/PlainTextAuthProviderBase.html [ProgrammaticPlainTextAuthProvider]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/oss/driver/api/core/auth/ProgrammaticPlainTextAuthProvider.html -[DseGssApiAuthProviderBase]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/dse/driver/api/core/auth/DseGssApiAuthProviderBase.html -[ProgrammaticDseGssApiAuthProvider]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/dse/driver/api/core/auth/ProgrammaticDseGssApiAuthProvider.html -[ProxyAuthentication.executeAs]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/dse/driver/api/core/auth/ProxyAuthentication.html#executeAs-java.lang.String-StatementT- [SessionBuilder.withAuthCredentials]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/oss/driver/api/core/session/SessionBuilder.html#withAuthCredentials-java.lang.String-java.lang.String- [SessionBuilder.withAuthProvider]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/oss/driver/api/core/session/SessionBuilder.html#withAuthProvider-com.datastax.oss.driver.api.core.auth.AuthProvider- [reference.conf]: ../configuration/reference/ diff --git a/manual/core/graalvm/README.md b/manual/core/graalvm/README.md index a2fc20b0662..bbc70a7f306 100644 --- a/manual/core/graalvm/README.md +++ b/manual/core/graalvm/README.md @@ -28,9 +28,6 @@ under the License. * When using [Jackson](../integration#Jackson); * When using LZ4 [compression](../compression/); * Depending on the [logging backend](../logging) in use. -* DSE-specific features: - * Geospatial types are supported. - * DSE Graph is not officially supported, although it may work. * The [shaded jar](../shaded_jar) is not officially supported, although it may work. ----- @@ -251,83 +248,6 @@ The driver performs a few [native calls](../integration#native-libraries) using Starting with driver 4.7.0, native calls are also possible in a GraalVM native image, without any extra configuration. -### Using DataStax Enterprise (DSE) features - -#### DSE Geospatial types - -DSE [Geospatial types](../dse/geotypes) are supported on GraalVM native images; the following -configurations must be added: - -1. Create the following reflection.json file, or add the entry to an existing file: - -```json -[ - { "name": "com.esri.core.geometry.ogc.OGCGeometry" } -] -``` - -**Important**: when using the shaded jar – which is not officially supported on GraalVM native -images, as stated above – replace the above entry with the below one: - -```json -[ - { "name": "com.datastax.oss.driver.shaded.esri.core.geometry.ogc.OGCGeometry" } -] -``` - -2. When invoking the native image builder, add a `-H:ReflectionConfigurationFiles=reflection.json` - flag and point it to the file created above. - -#### DSE Graph - -**[DSE Graph](../dse/graph) is not officially supported on GraalVM native images.** - -The following configuration can be used as a starting point for users wishing to build a native -image for a DSE Graph application. DataStax does not guarantee however that the below configuration -will work in all cases. If the native image build fails, a good option is to use GraalVM's -[Tracing Agent](https://www.graalvm.org/reference-manual/native-image/Agent/) to understand why. - -1. Create the following reflection.json file, or add these entries to an existing file: - -```json -[ - { "name": "org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV3d0" }, - { "name": "org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal" }, - { "name": "org.apache.tinkerpop.gremlin.structure.Graph", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true - }, - { "name": "org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true - }, - { "name": " org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true - }, - { "name": "org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true - } -] -``` - -2. When invoking the native image builder, add the following flags: - -``` --H:ReflectionConfigurationFiles=reflection.json ---initialize-at-build-time=org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV3d0 ---initialize-at-build-time=org.apache.tinkerpop.shaded.jackson.databind.deser.std.StdDeserializer -``` - ### Using the shaded jar **The [shaded jar](../shaded_jar) is not officially supported in a GraalVM native image.** diff --git a/manual/core/integration/README.md b/manual/core/integration/README.md index 964e8388347..0ba0e071fcb 100644 --- a/manual/core/integration/README.md +++ b/manual/core/integration/README.md @@ -47,8 +47,8 @@ right dependencies: - Same as the above, but without explicit dependencies to Netty, - Jackson or ESRI. + Same as the above, but without explicit dependencies to Netty or + Jackson. java‑driver‑core‑shaded @@ -472,7 +472,6 @@ dependency: [Jackson](https://github.com/FasterXML/jackson) is used: -* when Insights monitoring is enabled; * when [Json codecs](../custom_codecs) are being used; * when driver configuration reporting is enabled — `advanced.driver-config-reporting.enabled`, which **defaults to true**. The report is serialized to JSON with Jackson. @@ -499,84 +498,6 @@ excluding Jackson turns it off without you having to opt out: the driver logs an at startup and does not send `DRIVER_CONFIG`. Nothing else changes — `SESSION_ID` is still sent on every connection, and connecting is unaffected. -#### Esri - -The geospatial types implementation is based on the [Esri Geometry -API](https://github.com/Esri/geometry-api-java). - -For driver versions >= 4.4.0 and < 4.14.0 Esri is declared as a required dependency, -although the driver can operate normally without it. If you don't use geospatial types -anywhere in your application you can exclude the dependency: - -```xml - - com.scylladb - java-driver-core - ${driver.version} - - - com.esri.geometry - * - - - -``` - -Starting with driver 4.14.0 Esri has been changed to an optional dependency. You no longer have to -explicitly exclude the dependency if it's not used, but if you do wish to make use of the Esri -library you must now explicitly specify it as a dependency : - -```xml - - com.esri.geometry - esri-geometry-api - ${esri.version} - -``` - -In the dependency specification above you should use any 1.2.x version of Esri (we recommend -1.2.1). These versions are older than the current 2.x versions of the library but they are -guaranteed to be fully compatible with DSE. - -#### TinkerPop - -[Apache TinkerPop™](http://tinkerpop.apache.org/) is used in the graph API. - -For driver versions ranging from 4.4.0 to 4.9.0 inclusive, TinkerPop is declared as a required -dependency, but the driver can operate normally without it. If you don't use the graph API at all, -you can exclude the TinkerPop dependencies: - -```xml - - com.scylladb - java-driver-core - ${driver.version} - - - org.apache.tinkerpop - * - - - -``` - -Starting with driver 4.10 however, TinkerPop switched to an optional dependency. Excluding TinkerPop -explicitly is not required anymore if you don't use it. _If you do use the graph API though, you now -need to explicitly include the dependencies below in your application_: - -```xml - - org.apache.tinkerpop - gremlin-core - ${tinkerpop.version} - - - org.apache.tinkerpop - tinkergraph-gremlin - ${tinkerpop.version} - -``` - #### Reactive Streams [Reactive Streams](https://www.reactive-streams.org/) types are referenced in our [reactive diff --git a/manual/core/metadata/node/README.md b/manual/core/metadata/node/README.md index dc5196b9878..6241af04e6c 100644 --- a/manual/core/metadata/node/README.md +++ b/manual/core/metadata/node/README.md @@ -69,14 +69,8 @@ nodes. The exact definition of `LOCAL` and `REMOTE` is left to the interpretatio but in general it represents the proximity to the client, and `LOCAL` nodes will be prioritized as coordinators. They also influence pooling options. -[Node#getExtras()] contains additional free-form properties. This is intended for future evolution -or custom driver extensions. In particular, if the driver is connected to DataStax Enterprise, the -map will contain additional information under the keys defined in [DseNodeProperties]: - -```java -Object rawDseVersion = node.getExtras().get(DseNodeProperties.DSE_VERSION); -Version dseVersion = (rawDseVersion == null) ? null : (Version) rawDseVersion; -``` +[Node#getExtras()] contains additional free-form properties intended for future evolution or custom +driver extensions. ### Notifications @@ -161,4 +155,3 @@ the source code. [NodeStateListener]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/oss/driver/api/core/metadata/NodeStateListener.html [NodeStateListenerBase]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/oss/driver/api/core/metadata/NodeStateListenerBase.html [SessionBuilder.addNodeStateListener]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/oss/driver/api/core/session/SessionBuilder.html#addNodeStateListener-com.datastax.oss.driver.api.core.metadata.NodeStateListener- -[DseNodeProperties]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/dse/driver/api/core/metadata/DseNodeProperties.html diff --git a/manual/core/metadata/schema/README.md b/manual/core/metadata/schema/README.md index ae119a20b57..5667af6bae0 100644 --- a/manual/core/metadata/schema/README.md +++ b/manual/core/metadata/schema/README.md @@ -54,38 +54,6 @@ immutable; if you need to get the latest schema, be sure to call reference). -### DSE - -All schema metadata interfaces accessible through `Metadata.getKeyspaces()` have a DSE-specific -subtype in the package [com.datastax.dse.driver.api.core.metadata.schema]. The objects returned by -the DSE driver implement those types, so you can safely cast: - -```java -for (KeyspaceMetadata keyspace : session.getMetadata().getKeyspaces().values()) { - DseKeyspaceMetadata dseKeyspace = (DseKeyspaceMetadata) keyspace; -} -``` - -If you're calling a method that returns an optional and want to keep the result wrapped, use this -pattern: - -```java -Optional f = - session - .getMetadata() - .getKeyspace("ks") - .flatMap(ks -> ks.getFunction("f")) - .map(DseFunctionMetadata.class::cast); -``` - -For future extensibility, there is a `DseXxxMetadata` subtype for every OSS type. But currently (DSE -6.7), the only types that really add extra information are: - -* [DseFunctionMetadata]: add support for the `DETERMINISTIC` and `MONOTONIC` keywords; -* [DseAggregateMetadata]: add support for the `MONOTONIC` keyword. - -All other types (keyspaces, tables, etc.) are identical to their OSS counterparts. - ### Notifications If you need to follow schema changes, you don't need to poll the metadata manually; instead, @@ -208,7 +176,7 @@ If an element is malformed, or if its regex has a syntax error, a warning is log element is ignored. The default configuration (see [reference.conf](../../configuration/reference/)) excludes all -Cassandra and DSE system keyspaces. +Cassandra system keyspaces. Try to use only exact name inclusions if possible. This allows the driver to filter on the server side with a `WHERE IN` clause. If you use any other rule, it has to fetch all system rows and filter @@ -347,9 +315,5 @@ take a look at the [Performance](../../performance/#schema-updates) page for a f [Session#checkSchemaAgreementAsync]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/oss/driver/api/core/session/Session.html#checkSchemaAgreementAsync-- [SessionBuilder#addSchemaChangeListener]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/oss/driver/api/core/session/SessionBuilder.html#addSchemaChangeListener-com.datastax.oss.driver.api.core.metadata.schema.SchemaChangeListener- [ExecutionInfo#isSchemaInAgreement]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/oss/driver/api/core/cql/ExecutionInfo.html#isSchemaInAgreement-- -[com.datastax.dse.driver.api.core.metadata.schema]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/dse/driver/api/core/metadata/schema/package-frame.html -[DseFunctionMetadata]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/dse/driver/api/core/metadata/schema/DseFunctionMetadata.html -[DseAggregateMetadata]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/dse/driver/api/core/metadata/schema/DseAggregateMetadata.html - [JAVA-750]: https://datastax-oss.atlassian.net/browse/JAVA-750 [java.util.regex.Pattern]: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/regex/Pattern.html diff --git a/manual/core/native_protocol/README.md b/manual/core/native_protocol/README.md index 42146e63f42..2793445f568 100644 --- a/manual/core/native_protocol/README.md +++ b/manual/core/native_protocol/README.md @@ -52,18 +52,6 @@ first node the driver connects to: *(1) for previous driver versions, see the [3.x documentation][driver3]* -Since version 4.5.0, the driver can also use DSE protocols when all nodes are running a version of -DSE. The table below shows the protocol matrix for these cases: - -| DSE version | Negotiated protocol version with driver 4 | -|---------------------|-------------------------------------------------| -| 4.7/4.8 | v3 | -| 5.0 | v4 | -| 5.1 | DSE_V1 ² | -| 6.0/6.7/6.8 | DSE_V2 ² | - -*(2) DSE Protocols are chosen before other Cassandra native protocols.* - ### Controlling the protocol version To find out which version you're currently using, use the following: diff --git a/manual/core/non_blocking/README.md b/manual/core/non_blocking/README.md index d6b98081645..cbb8cad3efb 100644 --- a/manual/core/non_blocking/README.md +++ b/manual/core/non_blocking/README.md @@ -85,22 +85,6 @@ the subscriber. [`ReactiveSession`]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/dse/driver/api/core/cql/reactive/ReactiveSession.html [`executeReactive`]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/dse/driver/api/core/cql/reactive/ReactiveSession.html#executeReactive-com.datastax.oss.driver.api.core.cql.Statement- -There is one exception though: continuous paging queries (a feature specific to DSE) have a special -execution model which uses internal locks for coordination. Although such locks are only held for -extremely brief periods of time, and never under high contention, this execution model doesn't -qualify as lock-free. - -As a consequence, all methods declared in [`ContinuousSession`] and [`ContinuousReactiveSession`] -cannot be considered as implemented 100% lock-free, even those built on top of the asynchronous or -reactive APIs like [`executeContinuouslyAsync`] and [`executeContinuouslyReactive`]. In practice -though, continuous paging is extremely efficient and can safely be used in most non-blocking -contexts, unless they require strict lock-freedom. - -[`ContinuousSession`]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/dse/driver/api/core/cql/continuous/ContinuousSession.html -[`ContinuousReactiveSession`]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/dse/driver/api/core/cql/continuous/reactive/ContinuousReactiveSession.html -[`executeContinuouslyAsync`]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/dse/driver/api/core/cql/continuous/ContinuousSession.html#executeContinuouslyAsync-com.datastax.oss.driver.api.core.cql.Statement- -[`executeContinuouslyReactive`]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/dse/driver/api/core/cql/continuous/reactive/ContinuousReactiveSession.html#executeContinuouslyReactive-com.datastax.oss.driver.api.core.cql.Statement- - #### Driver lock-free guarantees per session lifecycle phases The guarantees vary according to three possible session states: initializing, running, and closing. @@ -248,16 +232,6 @@ detectors. If that is the case, it is advised to disable hot-reloading by settin [`DriverConfigLoader`]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/oss/driver/api/core/config/DriverConfigLoader.html [hot-reloading]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/oss/driver/api/core/config/DriverConfigLoader.html#supportsReloading-- -#### Driver lock-free guarantees when connecting to DSE - -When connecting to clusters running recent DSE versions, the driver automatically enables periodic -status reporting. When preparing the status report, the driver has to hit the local filesystem, and -because of that, the status reporting process does not qualify as lock-free. - -If lock-freedom is being enforced, then automatic status reporting must be disabled by setting the -`datastax-java-driver.advanced.monitor-reporting.enabled` property to false in the driver -configuration. - ### Driver mechanism for detection of blocking calls The driver has its own mechanism for detecting blocking calls happening on an internal driver @@ -288,9 +262,8 @@ More specifically, the following items are currently declared to be allowed: * Loading of native libraries during startup (`TimestampGenerator`); * Locks held during startup only (`DefaultNettyOptions`, `LazyReference`, `ReplayingEventFilter`); -* Locks held during startup and topology and status events processing (`ChannelSet`, +* Locks held during startup and topology and status events processing (`ChannelSet`, `DistanceReporter`); -* Locks held when executing continuous paging queries; * Locks held during calls to `MutableCodecRegistry.register()` and `Uuids.timeBased()`. The following items are NOT declared to be allowed and are likely to be reported by BlockHound if diff --git a/manual/core/reactive/README.md b/manual/core/reactive/README.md index 3e9c496b219..d2f3343b2a5 100644 --- a/manual/core/reactive/README.md +++ b/manual/core/reactive/README.md @@ -30,8 +30,8 @@ Notes: all, it is possible to exclude it to minimize the number of runtime dependencies. If the library cannot be found at runtime, reactive queries won't be available, and a warning will be logged, but the driver will otherwise operate normally (this is also valid for OSGi deployments). -* For historical reasons, reactive-related driver types reside in a package prefixed with `dse`; - however, reactive queries also work with regular Cassandra. +* Reactive-related driver types keep their historical `dse` package prefix for API compatibility; + they are generic and supported with Cassandra and Scylla. * The reactive execution model is implemented in a non-blocking fashion: see the manual page on [non-blocking programming](../non_blocking) for details. diff --git a/manual/core/shaded_jar/README.md b/manual/core/shaded_jar/README.md index ecda22bf965..b10b4135452 100644 --- a/manual/core/shaded_jar/README.md +++ b/manual/core/shaded_jar/README.md @@ -23,8 +23,8 @@ The default `java-driver-core` JAR depends on a number of [third party libraries](../integration/#driver-dependencies). This can create conflicts if your application already uses other versions of those same dependencies. -To avoid this, we provide an alternative core artifact that shades [Netty](../integration/#netty), -[Jackson](../integration/#jackson) and [ESRI](../integration/#esri). To use it, replace the +To avoid this, we provide an alternative core artifact that shades [Netty](../integration/#netty) +and [Jackson](../integration/#jackson). To use it, replace the dependency to `java-driver-core` by: ```xml @@ -82,5 +82,5 @@ Notes: ``` - This only works with Netty: for Jackson and ESRI, only the exact version declared in the driver POM - is supported. + This only works with Netty: for Jackson, only the exact version declared in the driver POM is + supported. diff --git a/manual/core/statements/per_query_keyspace/README.md b/manual/core/statements/per_query_keyspace/README.md index 9a7ffa338c9..91b7975c191 100644 --- a/manual/core/statements/per_query_keyspace/README.md +++ b/manual/core/statements/per_query_keyspace/README.md @@ -23,7 +23,7 @@ under the License. Specify the keyspace separately instead of hardcoding it in the query string. -* Cassandra 4+ / DSE 6+. +* Cassandra 4+. * only works with simple statements. ----- diff --git a/manual/core/statements/prepared/README.md b/manual/core/statements/prepared/README.md index 9b1a1a75af8..ea12713eeff 100644 --- a/manual/core/statements/prepared/README.md +++ b/manual/core/statements/prepared/README.md @@ -29,7 +29,7 @@ queries that are used often. statements. * the session has a built-in cache, it's OK to prepare the same string twice. * values: `?` or `:name`, fill with `setXxx(int, ...)` or `setXxx(String, ...)` respectively. -* some values can be left unset with Cassandra 2.2+ / DSE 5+. +* some values can be left unset with Cassandra 2.2+ and Scylla. * built-in implementation is **immutable**. Setters always return a new object, don't ignore the result. @@ -254,7 +254,7 @@ those markers positionally, or name them apart yourself — `... and date > :fro #### Unset values With [native protocol](../../native_protocol/) V3, all variables must be bound. With native protocol -V4 (Cassandra 2.2 / DSE 5) or above, variables can be left unset, in which case they will be ignored +V4 (Cassandra 2.2) or above, variables can be left unset, in which case they will be ignored (no tombstones will be generated). If you're reusing a bound statement, you can use the `unset` method to unset variables that were previously set: diff --git a/manual/developer/native_protocol/README.md b/manual/developer/native_protocol/README.md index b96553fc51b..cc47aacba1d 100644 --- a/manual/developer/native_protocol/README.md +++ b/manual/developer/native_protocol/README.md @@ -84,8 +84,7 @@ creating a message instance. The code makes very few assumptions about how the messages will be used. Data is often represented in the most simple way. For example, `ProtocolConstants` uses simple integer constants to represent -protocol codes (enums wouldn't work at that level, because we need to add new codes in the DSE -driver); the driver generally rewraps them in more type-safe structures before exposing them to +protocol codes; the driver generally rewraps them in more type-safe structures before exposing them to higher-level layers. #### Encoding/decoding diff --git a/manual/developer/request_execution/README.md b/manual/developer/request_execution/README.md index 38a0a55fbd7..4b206af1558 100644 --- a/manual/developer/request_execution/README.md +++ b/manual/developer/request_execution/README.md @@ -178,8 +178,6 @@ ResultT)` combination defines an execution model, for example: | `Statement` | `ResultSet` | CQL, synchronous | | `Statement` | `CompletionStage` | CQL, asynchronous | | `Statement` | `ReactiveResultSet` | CQL, reactive | -| `GraphStatement` | `GraphResultSet` | DSE Graph, synchronous | -| `GraphStatement` | `CompletionStage` | DSE Graph, asynchronous | In general, regular client code doesn't use `Session.execute` directly. Instead, child interfaces expose more user-friendly shortcuts for a given result type: diff --git a/manual/query_builder/README.md b/manual/query_builder/README.md index f8897a25c8b..9eac2b5cf1a 100644 --- a/manual/query_builder/README.md +++ b/manual/query_builder/README.md @@ -210,8 +210,6 @@ For a complete tour of the API, browse the child pages in this manual: [QueryBuilder]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/oss/driver/api/querybuilder/QueryBuilder.html [SchemaBuilder]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/oss/driver/api/querybuilder/SchemaBuilder.html [CqlIdentifier]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/oss/driver/api/core/CqlIdentifier.html -[DseQueryBuilder]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/dse/driver/api/querybuilder/DseQueryBuilder.html -[DseSchemaBuilder]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/dse/driver/api/querybuilder/DseSchemaBuilder.html ```{eval-rst} .. toctree:: diff --git a/mapper-processor/pom.xml b/mapper-processor/pom.xml index 063dbeb7928..4100616c515 100644 --- a/mapper-processor/pom.xml +++ b/mapper-processor/pom.xml @@ -192,24 +192,6 @@ true - - maven-dependency-plugin - - - generate-dependency-list - - list - - generate-resources - - runtime - true - com.datastax.cassandra,com.datastax.dse - ${project.build.outputDirectory}/com/datastax/dse/driver/internal/mapper/processor/deps.txt - - - - diff --git a/mapper-processor/src/test/java/com/datastax/dse/driver/internal/mapper/processor/DependencyCheckTest.java b/mapper-processor/src/test/java/com/datastax/dse/driver/internal/mapper/processor/DependencyCheckTest.java deleted file mode 100644 index 7aa2accb1fe..00000000000 --- a/mapper-processor/src/test/java/com/datastax/dse/driver/internal/mapper/processor/DependencyCheckTest.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.mapper.processor; - -import com.datastax.dse.driver.internal.DependencyCheckTestBase; -import java.nio.file.Path; -import java.nio.file.Paths; - -public class DependencyCheckTest extends DependencyCheckTestBase { - - @Override - protected Path getDepsTxtPath() { - return Paths.get( - getBaseResourcePathString(), - "target", - "classes", - "com", - "datastax", - "dse", - "driver", - "internal", - "mapper", - "processor", - "deps.txt"); - } -} diff --git a/mapper-runtime/pom.xml b/mapper-runtime/pom.xml index 0456e0406a8..f7a8861fad6 100644 --- a/mapper-runtime/pom.xml +++ b/mapper-runtime/pom.xml @@ -192,30 +192,13 @@ optional for dependencies declared as non-optional in the pom files. -->org.reactivestreams.*;resolution:=optional, * - com.datastax.*.driver.*.mapper.* + + com.datastax.oss.driver.*.mapper.*, com.datastax.dse.driver.api.mapper.reactive, com.datastax.dse.driver.internal.mapper.reactive - - maven-dependency-plugin - - - generate-dependency-list - - list - - generate-resources - - runtime - true - com.datastax.cassandra,com.datastax.dse - ${project.build.outputDirectory}/com/datastax/dse/driver/internal/mapper/deps.txt - - - - diff --git a/mapper-runtime/src/main/java/com/datastax/dse/driver/api/mapper/reactive/MappedReactiveResultSet.java b/mapper-runtime/src/main/java/com/datastax/dse/driver/api/mapper/reactive/MappedReactiveResultSet.java index b4e6960ed66..1e24eebd765 100644 --- a/mapper-runtime/src/main/java/com/datastax/dse/driver/api/mapper/reactive/MappedReactiveResultSet.java +++ b/mapper-runtime/src/main/java/com/datastax/dse/driver/api/mapper/reactive/MappedReactiveResultSet.java @@ -38,8 +38,8 @@ * the driver and impact performance. Instead, they should asynchronously dispatch received signals * to their processing logic. * - *

This type is located in a {@code dse} package for historical reasons; reactive result sets - * work with both Cassandra and DSE. + *

This type keeps its historical {@code dse} namespace for API compatibility. Reactive result + * sets are generic and work with Cassandra and Scylla. * * @see ReactiveResultSet */ diff --git a/mapper-runtime/src/test/java/com/datastax/dse/driver/api/mapper/DependencyCheckTest.java b/mapper-runtime/src/test/java/com/datastax/dse/driver/api/mapper/DependencyCheckTest.java deleted file mode 100644 index 03c1e5bb24f..00000000000 --- a/mapper-runtime/src/test/java/com/datastax/dse/driver/api/mapper/DependencyCheckTest.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.mapper; - -import com.datastax.dse.driver.internal.DependencyCheckTestBase; -import java.nio.file.Path; -import java.nio.file.Paths; - -public class DependencyCheckTest extends DependencyCheckTestBase { - - @Override - protected Path getDepsTxtPath() { - return Paths.get( - getBaseResourcePathString(), - "target", - "classes", - "com", - "datastax", - "dse", - "driver", - "internal", - "mapper", - "deps.txt"); - } -} diff --git a/metrics/micrometer/src/main/java/com/datastax/oss/driver/internal/metrics/micrometer/MicrometerNodeMetricUpdater.java b/metrics/micrometer/src/main/java/com/datastax/oss/driver/internal/metrics/micrometer/MicrometerNodeMetricUpdater.java index cb8303de965..010ead90d75 100644 --- a/metrics/micrometer/src/main/java/com/datastax/oss/driver/internal/metrics/micrometer/MicrometerNodeMetricUpdater.java +++ b/metrics/micrometer/src/main/java/com/datastax/oss/driver/internal/metrics/micrometer/MicrometerNodeMetricUpdater.java @@ -17,8 +17,6 @@ */ package com.datastax.oss.driver.internal.metrics.micrometer; -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.dse.driver.api.core.metrics.DseNodeMetric; import com.datastax.oss.driver.api.core.config.DefaultDriverOption; import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; import com.datastax.oss.driver.api.core.metadata.Node; @@ -77,7 +75,6 @@ public MicrometerNodeMetricUpdater( initializeCounter(DefaultNodeMetric.AUTHENTICATION_ERRORS, profile); initializeTimer(DefaultNodeMetric.CQL_MESSAGES, profile); - initializeTimer(DseNodeMetric.GRAPH_MESSAGES, profile); } @Override @@ -116,22 +113,6 @@ protected Timer.Builder configureTimer(Timer.Builder builder, NodeMetric metric, configurePercentilesPublishIfDefined( builder, profile, DefaultDriverOption.METRICS_NODE_CQL_MESSAGES_PUBLISH_PERCENTILES); - } else if (metric == DseNodeMetric.GRAPH_MESSAGES) { - builder - .minimumExpectedValue( - profile.getDuration(DseDriverOption.METRICS_NODE_GRAPH_MESSAGES_LOWEST)) - .maximumExpectedValue( - profile.getDuration(DseDriverOption.METRICS_NODE_GRAPH_MESSAGES_HIGHEST)) - .serviceLevelObjectives( - profile.isDefined(DseDriverOption.METRICS_NODE_GRAPH_MESSAGES_SLO) - ? profile - .getDurationList(DseDriverOption.METRICS_NODE_GRAPH_MESSAGES_SLO) - .toArray(new Duration[0]) - : null) - .percentilePrecision(profile.getInt(DseDriverOption.METRICS_NODE_GRAPH_MESSAGES_DIGITS)); - - configurePercentilesPublishIfDefined( - builder, profile, DseDriverOption.METRICS_NODE_GRAPH_MESSAGES_PUBLISH_PERCENTILES); } return builder; } diff --git a/metrics/micrometer/src/main/java/com/datastax/oss/driver/internal/metrics/micrometer/MicrometerSessionMetricUpdater.java b/metrics/micrometer/src/main/java/com/datastax/oss/driver/internal/metrics/micrometer/MicrometerSessionMetricUpdater.java index 559054ab510..cf9cf2826c8 100644 --- a/metrics/micrometer/src/main/java/com/datastax/oss/driver/internal/metrics/micrometer/MicrometerSessionMetricUpdater.java +++ b/metrics/micrometer/src/main/java/com/datastax/oss/driver/internal/metrics/micrometer/MicrometerSessionMetricUpdater.java @@ -17,8 +17,6 @@ */ package com.datastax.oss.driver.internal.metrics.micrometer; -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.dse.driver.api.core.metrics.DseSessionMetric; import com.datastax.oss.driver.api.core.config.DefaultDriverOption; import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; import com.datastax.oss.driver.api.core.metrics.DefaultSessionMetric; @@ -49,12 +47,9 @@ public MicrometerSessionMetricUpdater( initializeCounter(DefaultSessionMetric.CQL_CLIENT_TIMEOUTS, profile); initializeCounter(DefaultSessionMetric.THROTTLING_ERRORS, profile); - initializeCounter(DseSessionMetric.GRAPH_CLIENT_TIMEOUTS, profile); initializeTimer(DefaultSessionMetric.CQL_REQUESTS, profile); initializeTimer(DefaultSessionMetric.THROTTLING_DELAY, profile); - initializeTimer(DseSessionMetric.CONTINUOUS_CQL_REQUESTS, profile); - initializeTimer(DseSessionMetric.GRAPH_REQUESTS, profile); } @Override @@ -104,51 +99,6 @@ protected Timer.Builder configureTimer(Timer.Builder builder, SessionMetric metr configurePercentilesPublishIfDefined( builder, profile, DefaultDriverOption.METRICS_SESSION_THROTTLING_PUBLISH_PERCENTILES); - } else if (metric == DseSessionMetric.CONTINUOUS_CQL_REQUESTS) { - builder - .minimumExpectedValue( - profile.getDuration( - DseDriverOption.CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_LOWEST)) - .maximumExpectedValue( - profile.getDuration( - DseDriverOption.CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_HIGHEST)) - .serviceLevelObjectives( - profile.isDefined(DseDriverOption.CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_SLO) - ? profile - .getDurationList( - DseDriverOption.CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_SLO) - .toArray(new Duration[0]) - : null) - .percentilePrecision( - profile.isDefined( - DseDriverOption.CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_DIGITS) - ? profile.getInt( - DseDriverOption.CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_DIGITS) - : null); - - configurePercentilesPublishIfDefined( - builder, - profile, - DseDriverOption.CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_PUBLISH_PERCENTILES); - } else if (metric == DseSessionMetric.GRAPH_REQUESTS) { - builder - .minimumExpectedValue( - profile.getDuration(DseDriverOption.METRICS_SESSION_GRAPH_REQUESTS_LOWEST)) - .maximumExpectedValue( - profile.getDuration(DseDriverOption.METRICS_SESSION_GRAPH_REQUESTS_HIGHEST)) - .serviceLevelObjectives( - profile.isDefined(DseDriverOption.METRICS_SESSION_GRAPH_REQUESTS_SLO) - ? profile - .getDurationList(DseDriverOption.METRICS_SESSION_GRAPH_REQUESTS_SLO) - .toArray(new Duration[0]) - : null) - .percentilePrecision( - profile.isDefined(DseDriverOption.METRICS_SESSION_GRAPH_REQUESTS_DIGITS) - ? profile.getInt(DseDriverOption.METRICS_SESSION_GRAPH_REQUESTS_DIGITS) - : null); - - configurePercentilesPublishIfDefined( - builder, profile, DseDriverOption.METRICS_SESSION_GRAPH_REQUESTS_PUBLISH_PERCENTILES); } return builder; } diff --git a/metrics/micrometer/src/test/java/com/datastax/oss/driver/internal/metrics/micrometer/MicrometerNodeMetricUpdaterTest.java b/metrics/micrometer/src/test/java/com/datastax/oss/driver/internal/metrics/micrometer/MicrometerNodeMetricUpdaterTest.java index 594c4166e98..de5d01a954e 100644 --- a/metrics/micrometer/src/test/java/com/datastax/oss/driver/internal/metrics/micrometer/MicrometerNodeMetricUpdaterTest.java +++ b/metrics/micrometer/src/test/java/com/datastax/oss/driver/internal/metrics/micrometer/MicrometerNodeMetricUpdaterTest.java @@ -25,8 +25,6 @@ import static org.mockito.Mockito.when; import ch.qos.logback.classic.Level; -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.dse.driver.api.core.metrics.DseNodeMetric; import com.datastax.oss.driver.api.core.config.DefaultDriverOption; import com.datastax.oss.driver.api.core.config.DriverConfig; import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; @@ -265,14 +263,6 @@ public static Object[][] timerMetrics() { DefaultDriverOption.METRICS_NODE_CQL_MESSAGES_SLO, DefaultDriverOption.METRICS_NODE_CQL_MESSAGES_PUBLISH_PERCENTILES, }, - { - DseNodeMetric.GRAPH_MESSAGES, - DseDriverOption.METRICS_NODE_GRAPH_MESSAGES_LOWEST, - DseDriverOption.METRICS_NODE_GRAPH_MESSAGES_HIGHEST, - DseDriverOption.METRICS_NODE_GRAPH_MESSAGES_DIGITS, - DseDriverOption.METRICS_NODE_GRAPH_MESSAGES_SLO, - DseDriverOption.METRICS_NODE_GRAPH_MESSAGES_PUBLISH_PERCENTILES, - }, }; } } diff --git a/metrics/micrometer/src/test/java/com/datastax/oss/driver/internal/metrics/micrometer/MicrometerSessionMetricUpdaterTest.java b/metrics/micrometer/src/test/java/com/datastax/oss/driver/internal/metrics/micrometer/MicrometerSessionMetricUpdaterTest.java index 79f7c3a8ff7..78cab7b830c 100644 --- a/metrics/micrometer/src/test/java/com/datastax/oss/driver/internal/metrics/micrometer/MicrometerSessionMetricUpdaterTest.java +++ b/metrics/micrometer/src/test/java/com/datastax/oss/driver/internal/metrics/micrometer/MicrometerSessionMetricUpdaterTest.java @@ -22,8 +22,6 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.dse.driver.api.core.metrics.DseSessionMetric; import com.datastax.oss.driver.api.core.config.DefaultDriverOption; import com.datastax.oss.driver.api.core.config.DriverConfig; import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; @@ -172,22 +170,6 @@ public static Object[][] timerMetrics() { DefaultDriverOption.METRICS_SESSION_CQL_REQUESTS_SLO, DefaultDriverOption.METRICS_SESSION_CQL_REQUESTS_PUBLISH_PERCENTILES, }, - { - DseSessionMetric.GRAPH_REQUESTS, - DseDriverOption.METRICS_SESSION_GRAPH_REQUESTS_LOWEST, - DseDriverOption.METRICS_SESSION_GRAPH_REQUESTS_HIGHEST, - DseDriverOption.METRICS_SESSION_GRAPH_REQUESTS_DIGITS, - DseDriverOption.METRICS_SESSION_GRAPH_REQUESTS_SLO, - DseDriverOption.METRICS_SESSION_GRAPH_REQUESTS_PUBLISH_PERCENTILES, - }, - { - DseSessionMetric.CONTINUOUS_CQL_REQUESTS, - DseDriverOption.CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_LOWEST, - DseDriverOption.CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_HIGHEST, - DseDriverOption.CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_DIGITS, - DseDriverOption.CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_SLO, - DseDriverOption.CONTINUOUS_PAGING_METRICS_SESSION_CQL_REQUESTS_PUBLISH_PERCENTILES - }, { DefaultSessionMetric.THROTTLING_DELAY, DefaultDriverOption.METRICS_SESSION_THROTTLING_LOWEST, diff --git a/metrics/microprofile/src/main/java/com/datastax/oss/driver/internal/metrics/microprofile/MicroProfileNodeMetricUpdater.java b/metrics/microprofile/src/main/java/com/datastax/oss/driver/internal/metrics/microprofile/MicroProfileNodeMetricUpdater.java index 8a2d235b59e..9aa055c2e75 100644 --- a/metrics/microprofile/src/main/java/com/datastax/oss/driver/internal/metrics/microprofile/MicroProfileNodeMetricUpdater.java +++ b/metrics/microprofile/src/main/java/com/datastax/oss/driver/internal/metrics/microprofile/MicroProfileNodeMetricUpdater.java @@ -17,7 +17,6 @@ */ package com.datastax.oss.driver.internal.metrics.microprofile; -import com.datastax.dse.driver.api.core.metrics.DseNodeMetric; import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; import com.datastax.oss.driver.api.core.metadata.Node; import com.datastax.oss.driver.api.core.metrics.DefaultNodeMetric; @@ -73,7 +72,6 @@ public MicroProfileNodeMetricUpdater( initializeCounter(DefaultNodeMetric.AUTHENTICATION_ERRORS, profile); initializeTimer(DefaultNodeMetric.CQL_MESSAGES, profile); - initializeTimer(DseNodeMetric.GRAPH_MESSAGES, profile); } @Override diff --git a/metrics/microprofile/src/main/java/com/datastax/oss/driver/internal/metrics/microprofile/MicroProfileSessionMetricUpdater.java b/metrics/microprofile/src/main/java/com/datastax/oss/driver/internal/metrics/microprofile/MicroProfileSessionMetricUpdater.java index f3c906e4422..df0e84c5af6 100644 --- a/metrics/microprofile/src/main/java/com/datastax/oss/driver/internal/metrics/microprofile/MicroProfileSessionMetricUpdater.java +++ b/metrics/microprofile/src/main/java/com/datastax/oss/driver/internal/metrics/microprofile/MicroProfileSessionMetricUpdater.java @@ -17,7 +17,6 @@ */ package com.datastax.oss.driver.internal.metrics.microprofile; -import com.datastax.dse.driver.api.core.metrics.DseSessionMetric; import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; import com.datastax.oss.driver.api.core.metrics.DefaultSessionMetric; import com.datastax.oss.driver.api.core.metrics.SessionMetric; @@ -45,12 +44,9 @@ public MicroProfileSessionMetricUpdater( initializeCounter(DefaultSessionMetric.CQL_CLIENT_TIMEOUTS, profile); initializeCounter(DefaultSessionMetric.THROTTLING_ERRORS, profile); - initializeCounter(DseSessionMetric.GRAPH_CLIENT_TIMEOUTS, profile); initializeTimer(DefaultSessionMetric.CQL_REQUESTS, profile); initializeTimer(DefaultSessionMetric.THROTTLING_DELAY, profile); - initializeTimer(DseSessionMetric.CONTINUOUS_CQL_REQUESTS, profile); - initializeTimer(DseSessionMetric.GRAPH_REQUESTS, profile); } @Override diff --git a/osgi-tests/README.md b/osgi-tests/README.md index 1ca6211d427..3401b5e84c1 100644 --- a/osgi-tests/README.md +++ b/osgi-tests/README.md @@ -53,7 +53,7 @@ OSGi ones, you can do so as follows: You can pass the following system properties to your tests: 1. `ccm.version`: the CCM version to use -2. `ccm.distribution`: choose target backend type (e.g. DSE, HCD) +2. `ccm.distribution`: choose target backend type (for example Cassandra, Scylla, or HCD) 3. `osgi.debug`: whether to enable remote debugging of the OSGi container (see below). diff --git a/osgi-tests/pom.xml b/osgi-tests/pom.xml index 3b5c1f4dc81..742e3857767 100644 --- a/osgi-tests/pom.xml +++ b/osgi-tests/pom.xml @@ -85,18 +85,6 @@ org.reactivestreams reactive-streams - - com.esri.geometry - esri-geometry-api - - - org.apache.tinkerpop - gremlin-core - - - org.apache.tinkerpop - tinkergraph-gremlin - org.osgi org.osgi.core @@ -227,7 +215,7 @@ com.datastax.oss.driver.internal.osgi.MailboxActivator com.datastax.oss.driver.api.osgi.* com.datastax.oss.driver.internal.osgi.* - !net.jcip.annotations.*,!edu.umd.cs.findbugs.annotations.*,org.apache.tinkerpop.*;resolution:=optional,* + !net.jcip.annotations.*,!edu.umd.cs.findbugs.annotations.*,* <_include>-osgi.bnd diff --git a/osgi-tests/src/main/java/com/datastax/oss/driver/api/osgi/service/geo/GeoMailboxMessage.java b/osgi-tests/src/main/java/com/datastax/oss/driver/api/osgi/service/geo/GeoMailboxMessage.java deleted file mode 100644 index 9b0b52cfa09..00000000000 --- a/osgi-tests/src/main/java/com/datastax/oss/driver/api/osgi/service/geo/GeoMailboxMessage.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.oss.driver.api.osgi.service.geo; - -import com.datastax.dse.driver.api.core.data.geometry.Point; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.mapper.annotations.ClusteringColumn; -import com.datastax.oss.driver.api.mapper.annotations.CqlName; -import com.datastax.oss.driver.api.mapper.annotations.Entity; -import com.datastax.oss.driver.api.mapper.annotations.PartitionKey; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Objects; - -@Entity -@CqlName("messages_by_location") -public class GeoMailboxMessage { - - public static final CqlIdentifier MAILBOX_TABLE = - CqlIdentifier.fromInternal("messages_by_location"); - - @PartitionKey private String recipient; - - @ClusteringColumn private Point location; - - private String sender; - - private String body; - - public GeoMailboxMessage() {} - - public GeoMailboxMessage( - @NonNull String recipient, - @NonNull Point location, - @NonNull String sender, - @NonNull String body) { - this.location = location; - this.recipient = recipient; - this.sender = sender; - this.body = body; - } - - public String getRecipient() { - return recipient; - } - - public void setRecipient(String recipient) { - this.recipient = recipient; - } - - public Point getLocation() { - return location; - } - - public void setLocation(Point location) { - this.location = location; - } - - public String getSender() { - return sender; - } - - public void setSender(String sender) { - this.sender = sender; - } - - public String getBody() { - return body; - } - - public void setBody(String body) { - this.body = body; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof GeoMailboxMessage)) { - return false; - } - GeoMailboxMessage that = (GeoMailboxMessage) o; - return Objects.equals(recipient, that.recipient) - && Objects.equals(location, that.location) - && Objects.equals(sender, that.sender) - && Objects.equals(body, that.body); - } - - @Override - public int hashCode() { - return Objects.hash(recipient, location, sender, body); - } -} diff --git a/osgi-tests/src/main/java/com/datastax/oss/driver/api/osgi/service/geo/GeoMailboxService.java b/osgi-tests/src/main/java/com/datastax/oss/driver/api/osgi/service/geo/GeoMailboxService.java deleted file mode 100644 index dcb7963ccc3..00000000000 --- a/osgi-tests/src/main/java/com/datastax/oss/driver/api/osgi/service/geo/GeoMailboxService.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.oss.driver.api.osgi.service.geo; - -import com.datastax.oss.driver.api.osgi.service.MailboxException; -import com.datastax.oss.driver.api.osgi.service.MailboxService; - -public interface GeoMailboxService extends MailboxService { - - void sendGeoMessage(GeoMailboxMessage message) throws MailboxException; - - Iterable getGeoMessages(String recipient) throws MailboxException; - - void clearGeoMailbox(String recipient) throws MailboxException; -} diff --git a/osgi-tests/src/main/java/com/datastax/oss/driver/api/osgi/service/graph/GraphMailboxService.java b/osgi-tests/src/main/java/com/datastax/oss/driver/api/osgi/service/graph/GraphMailboxService.java deleted file mode 100644 index 65999957066..00000000000 --- a/osgi-tests/src/main/java/com/datastax/oss/driver/api/osgi/service/graph/GraphMailboxService.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.oss.driver.api.osgi.service.graph; - -import com.datastax.oss.driver.api.osgi.service.MailboxException; -import com.datastax.oss.driver.api.osgi.service.MailboxMessage; -import com.datastax.oss.driver.api.osgi.service.MailboxService; - -public interface GraphMailboxService extends MailboxService { - - void sendGraphMessage(MailboxMessage message) throws MailboxException; - - Iterable getGraphMessages(String recipient) throws MailboxException; -} diff --git a/osgi-tests/src/main/java/com/datastax/oss/driver/internal/osgi/MailboxActivator.java b/osgi-tests/src/main/java/com/datastax/oss/driver/internal/osgi/MailboxActivator.java index 8dff11520af..3270a9e3f0a 100644 --- a/osgi-tests/src/main/java/com/datastax/oss/driver/internal/osgi/MailboxActivator.java +++ b/osgi-tests/src/main/java/com/datastax/oss/driver/internal/osgi/MailboxActivator.java @@ -17,8 +17,6 @@ */ package com.datastax.oss.driver.internal.osgi; -import com.datastax.dse.driver.api.core.config.DseDriverOption; -import com.datastax.dse.driver.internal.core.graph.GraphProtocol; import com.datastax.oss.driver.api.core.CqlIdentifier; import com.datastax.oss.driver.api.core.CqlSession; import com.datastax.oss.driver.api.core.CqlSessionBuilder; @@ -27,8 +25,6 @@ import com.datastax.oss.driver.api.core.config.ProgrammaticDriverConfigLoaderBuilder; import com.datastax.oss.driver.api.osgi.service.MailboxService; import com.datastax.oss.driver.internal.osgi.service.MailboxServiceImpl; -import com.datastax.oss.driver.internal.osgi.service.geo.GeoMailboxServiceImpl; -import com.datastax.oss.driver.internal.osgi.service.graph.GraphMailboxServiceImpl; import com.datastax.oss.driver.internal.osgi.service.reactive.ReactiveMailboxServiceImpl; import java.net.InetSocketAddress; import java.util.Dictionary; @@ -49,7 +45,6 @@ public class MailboxActivator implements BundleActivator { private CqlSession session; private CqlIdentifier keyspace; - private String graphName; @Override public void start(BundleContext context) { @@ -128,16 +123,6 @@ private void buildSession(BundleContext context) { LOGGER.info("Compression: NONE"); } - graphName = context.getProperty("cassandra.graph.name"); - if (graphName != null) { - LOGGER.info("Graph name: {}", graphName); - configLoaderBuilder.withString(DseDriverOption.GRAPH_NAME, graphName); - configLoaderBuilder.withString( - DseDriverOption.GRAPH_SUB_PROTOCOL, GraphProtocol.GRAPH_BINARY_1_0.toInternalCode()); - } else { - LOGGER.info("Graph: NONE"); - } - builder.withConfigLoader(configLoaderBuilder.build()); LOGGER.info("Initializing session"); @@ -149,10 +134,6 @@ private void registerService(BundleContext context) { MailboxServiceImpl mailbox; if ("true".equalsIgnoreCase(context.getProperty("cassandra.reactive"))) { mailbox = new ReactiveMailboxServiceImpl(session, keyspace); - } else if ("true".equalsIgnoreCase(context.getProperty("cassandra.geo"))) { - mailbox = new GeoMailboxServiceImpl(session, keyspace); - } else if ("true".equalsIgnoreCase(context.getProperty("cassandra.graph"))) { - mailbox = new GraphMailboxServiceImpl(session, keyspace, graphName); } else { mailbox = new MailboxServiceImpl(session, keyspace); } diff --git a/osgi-tests/src/main/java/com/datastax/oss/driver/internal/osgi/service/geo/GeoMailboxMapper.java b/osgi-tests/src/main/java/com/datastax/oss/driver/internal/osgi/service/geo/GeoMailboxMapper.java deleted file mode 100644 index 3beb990c1c9..00000000000 --- a/osgi-tests/src/main/java/com/datastax/oss/driver/internal/osgi/service/geo/GeoMailboxMapper.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.oss.driver.internal.osgi.service.geo; - -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.mapper.annotations.DaoFactory; -import com.datastax.oss.driver.api.mapper.annotations.DaoKeyspace; -import com.datastax.oss.driver.api.mapper.annotations.Mapper; - -@Mapper -public interface GeoMailboxMapper { - - @DaoFactory - GeoMailboxMessageDao mailboxMessageDao(@DaoKeyspace CqlIdentifier keyspace); -} diff --git a/osgi-tests/src/main/java/com/datastax/oss/driver/internal/osgi/service/geo/GeoMailboxMessageDao.java b/osgi-tests/src/main/java/com/datastax/oss/driver/internal/osgi/service/geo/GeoMailboxMessageDao.java deleted file mode 100644 index 1ea255fbe1d..00000000000 --- a/osgi-tests/src/main/java/com/datastax/oss/driver/internal/osgi/service/geo/GeoMailboxMessageDao.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.oss.driver.internal.osgi.service.geo; - -import com.datastax.oss.driver.api.core.PagingIterable; -import com.datastax.oss.driver.api.mapper.annotations.Dao; -import com.datastax.oss.driver.api.mapper.annotations.DefaultNullSavingStrategy; -import com.datastax.oss.driver.api.mapper.annotations.Insert; -import com.datastax.oss.driver.api.mapper.annotations.Select; -import com.datastax.oss.driver.api.mapper.entity.saving.NullSavingStrategy; -import com.datastax.oss.driver.api.osgi.service.geo.GeoMailboxMessage; -import com.datastax.oss.driver.internal.osgi.service.MailboxMessageDao; - -@Dao -@DefaultNullSavingStrategy(NullSavingStrategy.SET_TO_NULL) -public interface GeoMailboxMessageDao extends MailboxMessageDao { - - @Insert - void save(GeoMailboxMessage message); - - @Select - PagingIterable findGeoByRecipient(String recipient); -} diff --git a/osgi-tests/src/main/java/com/datastax/oss/driver/internal/osgi/service/geo/GeoMailboxServiceImpl.java b/osgi-tests/src/main/java/com/datastax/oss/driver/internal/osgi/service/geo/GeoMailboxServiceImpl.java deleted file mode 100644 index 415ffaa35f4..00000000000 --- a/osgi-tests/src/main/java/com/datastax/oss/driver/internal/osgi/service/geo/GeoMailboxServiceImpl.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.oss.driver.internal.osgi.service.geo; - -import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.bindMarker; -import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.deleteFrom; -import static com.datastax.oss.driver.api.querybuilder.relation.Relation.column; - -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.cql.BoundStatement; -import com.datastax.oss.driver.api.core.cql.PreparedStatement; -import com.datastax.oss.driver.api.osgi.service.MailboxException; -import com.datastax.oss.driver.api.osgi.service.geo.GeoMailboxMessage; -import com.datastax.oss.driver.api.osgi.service.geo.GeoMailboxService; -import com.datastax.oss.driver.internal.osgi.service.MailboxServiceImpl; - -public class GeoMailboxServiceImpl extends MailboxServiceImpl implements GeoMailboxService { - - private PreparedStatement deleteGeoStatement; - private GeoMailboxMessageDao geoDao; - - public GeoMailboxServiceImpl(CqlSession session, CqlIdentifier keyspace) { - super(session, keyspace); - } - - @Override - protected void createSchema() { - super.createSchema(); - session.execute( - "CREATE TABLE " - + keyspace - + "." - + GeoMailboxMessage.MAILBOX_TABLE - + " (" - + "recipient text," - + "location 'PointType'," - + "sender text," - + "body text," - + "PRIMARY KEY (recipient, location))"); - } - - @Override - protected void prepareStatements() { - super.prepareStatements(); - deleteGeoStatement = - session.prepare( - deleteFrom(keyspace, GeoMailboxMessage.MAILBOX_TABLE) - .where(column("recipient").isEqualTo(bindMarker())) - .build()); - } - - @Override - protected void createDaos() { - super.createDaos(); - GeoMailboxMapper mapper = new GeoMailboxMapperBuilder(session).build(); - geoDao = mapper.mailboxMessageDao(keyspace); - } - - @Override - public void sendGeoMessage(GeoMailboxMessage message) throws MailboxException { - try { - geoDao.save(message); - } catch (Exception e) { - throw new MailboxException(e); - } - } - - @Override - public Iterable getGeoMessages(String recipient) throws MailboxException { - try { - return geoDao.findGeoByRecipient(recipient); - } catch (Exception e) { - throw new MailboxException(e); - } - } - - @Override - public void clearGeoMailbox(String recipient) throws MailboxException { - try { - BoundStatement statement = deleteGeoStatement.bind(recipient); - session.execute(statement); - } catch (Exception e) { - throw new MailboxException(e); - } - } -} diff --git a/osgi-tests/src/main/java/com/datastax/oss/driver/internal/osgi/service/graph/GraphMailboxServiceImpl.java b/osgi-tests/src/main/java/com/datastax/oss/driver/internal/osgi/service/graph/GraphMailboxServiceImpl.java deleted file mode 100644 index b4637a27258..00000000000 --- a/osgi-tests/src/main/java/com/datastax/oss/driver/internal/osgi/service/graph/GraphMailboxServiceImpl.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.oss.driver.internal.osgi.service.graph; - -import static com.datastax.dse.driver.api.core.graph.DseGraph.g; -import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.unfold; - -import com.datastax.dse.driver.api.core.graph.FluentGraphStatement; -import com.datastax.dse.driver.api.core.graph.GraphNode; -import com.datastax.dse.driver.api.core.graph.ScriptGraphStatement; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.osgi.service.MailboxException; -import com.datastax.oss.driver.api.osgi.service.MailboxMessage; -import com.datastax.oss.driver.api.osgi.service.graph.GraphMailboxService; -import com.datastax.oss.driver.internal.osgi.service.MailboxServiceImpl; -import java.time.Instant; -import java.util.stream.Collectors; - -public class GraphMailboxServiceImpl extends MailboxServiceImpl implements GraphMailboxService { - - private final String graphName; - - public GraphMailboxServiceImpl(CqlSession session, CqlIdentifier keyspace, String graphName) { - super(session, keyspace); - this.graphName = graphName; - } - - @Override - protected void createSchema() { - super.createSchema(); - session.execute( - ScriptGraphStatement.newInstance( - String.format("system.graph('%s').ifExists().drop()", graphName)) - .setSystemQuery(true), - ScriptGraphStatement.SYNC); - session.execute( - ScriptGraphStatement.newInstance( - String.format("system.graph('%s').ifNotExists().coreEngine().create()", graphName)) - .setSystemQuery(true), - ScriptGraphStatement.SYNC); - session.execute( - ScriptGraphStatement.newInstance( - "schema.vertexLabel('message')" - + ".partitionBy('recipient', Text)" - + ".clusterBy('timestamp', Timestamp)" - + ".property('sender', Text)" - + ".property('body', Text)" - + ".create();")); - } - - @Override - public Iterable getGraphMessages(String recipient) throws MailboxException { - FluentGraphStatement statement = - FluentGraphStatement.newInstance( - g.V().hasLabel("message").has("recipient", recipient).valueMap().by(unfold())); - try { - return session.execute(statement).all().stream() - .map(GraphNode::asMap) - .map( - vertex -> { - Instant timestamp = (Instant) vertex.get("timestamp"); - String sender = (String) vertex.get("sender"); - String body = (String) vertex.get("body"); - return new MailboxMessage(recipient, timestamp, sender, body); - }) - .collect(Collectors.toList()); - } catch (Exception e) { - throw new MailboxException(e); - } - } - - @Override - public void sendGraphMessage(MailboxMessage message) throws MailboxException { - FluentGraphStatement insertVertex = - FluentGraphStatement.newInstance( - g.addV("message") - .property("recipient", message.getRecipient()) - .property("timestamp", message.getTimestamp()) - .property("sender", message.getSender()) - .property("body", message.getBody())); - try { - session.execute(insertVertex); - } catch (Exception e) { - throw new MailboxException(e); - } - } -} diff --git a/osgi-tests/src/main/resources/application.conf b/osgi-tests/src/main/resources/application.conf index 0c3e8e76c98..c600784dbd3 100644 --- a/osgi-tests/src/main/resources/application.conf +++ b/osgi-tests/src/main/resources/application.conf @@ -20,7 +20,6 @@ datastax-java-driver { basic { load-balancing-policy.class = DcInferringLoadBalancingPolicy request.timeout = 10 seconds - graph.timeout = 10 seconds } advanced { retry-policy.class = com.datastax.oss.driver.api.osgi.CustomRetryPolicy @@ -34,13 +33,6 @@ datastax-java-driver { trace.interval = 1 second warn-if-set-keyspace = false } - graph { - name = "demo" - } - continuous-paging.timeout { - first-page = 10 seconds - other-pages = 10 seconds - } metrics { session.enabled = [cql-requests] // Raise histogram bounds because the tests execute DDL queries with a higher timeout diff --git a/osgi-tests/src/test/java/com/datastax/oss/driver/internal/osgi/OsgiDefaultIT.java b/osgi-tests/src/test/java/com/datastax/oss/driver/internal/osgi/OsgiDefaultIT.java index 1f98956e680..62a08e61db6 100644 --- a/osgi-tests/src/test/java/com/datastax/oss/driver/internal/osgi/OsgiDefaultIT.java +++ b/osgi-tests/src/test/java/com/datastax/oss/driver/internal/osgi/OsgiDefaultIT.java @@ -47,7 +47,7 @@ public class OsgiDefaultIT { @Configuration public Option[] config() { // this configuration purposely excludes bundles whose resolution should be optional: - // ESRI, Reactive Streams and Tinkerpop. This allows to validate that the driver can still + // Reactive Streams. This allows to validate that the driver can still // work properly in an OSGi container as long as the missing packages are not accessed. return CoreOptions.options( BundleOptions.applicationBundle(), diff --git a/osgi-tests/src/test/java/com/datastax/oss/driver/internal/osgi/OsgiGeoTypesIT.java b/osgi-tests/src/test/java/com/datastax/oss/driver/internal/osgi/OsgiGeoTypesIT.java deleted file mode 100644 index c5ca962a66b..00000000000 --- a/osgi-tests/src/test/java/com/datastax/oss/driver/internal/osgi/OsgiGeoTypesIT.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.oss.driver.internal.osgi; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.oss.driver.api.osgi.service.MailboxService; -import com.datastax.oss.driver.api.osgi.service.geo.GeoMailboxService; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.internal.osgi.checks.DefaultServiceChecks; -import com.datastax.oss.driver.internal.osgi.checks.GeoServiceChecks; -import com.datastax.oss.driver.internal.osgi.support.BundleOptions; -import com.datastax.oss.driver.internal.osgi.support.CcmExamReactorFactory; -import com.datastax.oss.driver.internal.osgi.support.CcmPaxExam; -import javax.inject.Inject; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.ops4j.pax.exam.Configuration; -import org.ops4j.pax.exam.CoreOptions; -import org.ops4j.pax.exam.Option; -import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; - -@RunWith(CcmPaxExam.class) -@ExamReactorStrategy(CcmExamReactorFactory.class) -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "5.0", - description = "Requires geo types") -public class OsgiGeoTypesIT { - - @Inject MailboxService service; - - @Configuration - public Option[] config() { - return CoreOptions.options( - BundleOptions.applicationBundle(), - BundleOptions.driverCoreBundle(), - BundleOptions.driverQueryBuilderBundle(), - BundleOptions.driverMapperRuntimeBundle(), - BundleOptions.commonBundles(), - BundleOptions.nettyBundles(), - BundleOptions.jacksonBundles(), - BundleOptions.esriBundles(), - BundleOptions.testBundles()); - } - - @Test - public void test_geo_types() throws Exception { - DefaultServiceChecks.checkService(service); - assertThat(service).isInstanceOf(GeoMailboxService.class); - GeoServiceChecks.checkServiceGeo((GeoMailboxService) service); - } -} diff --git a/osgi-tests/src/test/java/com/datastax/oss/driver/internal/osgi/OsgiGraphIT.java b/osgi-tests/src/test/java/com/datastax/oss/driver/internal/osgi/OsgiGraphIT.java deleted file mode 100644 index be6997b9d02..00000000000 --- a/osgi-tests/src/test/java/com/datastax/oss/driver/internal/osgi/OsgiGraphIT.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.oss.driver.internal.osgi; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.oss.driver.api.osgi.service.MailboxService; -import com.datastax.oss.driver.api.osgi.service.graph.GraphMailboxService; -import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; -import com.datastax.oss.driver.internal.osgi.checks.DefaultServiceChecks; -import com.datastax.oss.driver.internal.osgi.checks.GraphServiceChecks; -import com.datastax.oss.driver.internal.osgi.support.BundleOptions; -import com.datastax.oss.driver.internal.osgi.support.CcmExamReactorFactory; -import com.datastax.oss.driver.internal.osgi.support.CcmPaxExam; -import javax.inject.Inject; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.ops4j.pax.exam.Configuration; -import org.ops4j.pax.exam.CoreOptions; -import org.ops4j.pax.exam.Option; -import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; - -@RunWith(CcmPaxExam.class) -@ExamReactorStrategy(CcmExamReactorFactory.class) -@BackendRequirement( - type = BackendType.DSE, - minInclusive = "6.8", - description = "Requires Core Graph") -public class OsgiGraphIT { - - @Inject MailboxService service; - - @Configuration - public Option[] config() { - return CoreOptions.options( - BundleOptions.applicationBundle(), - BundleOptions.driverCoreBundle(), - BundleOptions.driverQueryBuilderBundle(), - BundleOptions.driverMapperRuntimeBundle(), - BundleOptions.commonBundles(), - BundleOptions.nettyBundles(), - BundleOptions.jacksonBundles(), - BundleOptions.tinkerpopBundles(), - BundleOptions.testBundles()); - } - - @Test - public void test_graph() throws Exception { - DefaultServiceChecks.checkService(service); - assertThat(service).isInstanceOf(GraphMailboxService.class); - GraphServiceChecks.checkGraphService((GraphMailboxService) service); - } -} diff --git a/osgi-tests/src/test/java/com/datastax/oss/driver/internal/osgi/checks/GeoServiceChecks.java b/osgi-tests/src/test/java/com/datastax/oss/driver/internal/osgi/checks/GeoServiceChecks.java deleted file mode 100644 index a0fb35e2df5..00000000000 --- a/osgi-tests/src/test/java/com/datastax/oss/driver/internal/osgi/checks/GeoServiceChecks.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.oss.driver.internal.osgi.checks; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.dse.driver.api.core.data.geometry.Point; -import com.datastax.oss.driver.api.osgi.service.geo.GeoMailboxMessage; -import com.datastax.oss.driver.api.osgi.service.geo.GeoMailboxService; -import java.util.ArrayList; -import java.util.List; - -public class GeoServiceChecks { - - public static void checkServiceGeo(GeoMailboxService service) throws Exception { - // Insert some data into mailbox for a particular user. - String recipient = "user@datastax.com"; - try { - List insertedMessages = new ArrayList<>(); - for (int i = 0; i < 30; i++) { - Point location = Point.fromCoordinates(i, i); - GeoMailboxMessage message = - new GeoMailboxMessage(recipient, location, "sender" + i, "body" + i); - insertedMessages.add(message); - service.sendGeoMessage(message); - } - Iterable retrievedMessages = service.getGeoMessages(recipient); - assertThat(retrievedMessages).containsExactlyInAnyOrderElementsOf(insertedMessages); - } finally { - service.clearGeoMailbox(recipient); - } - } -} diff --git a/osgi-tests/src/test/java/com/datastax/oss/driver/internal/osgi/checks/GraphServiceChecks.java b/osgi-tests/src/test/java/com/datastax/oss/driver/internal/osgi/checks/GraphServiceChecks.java deleted file mode 100644 index 40bda10900b..00000000000 --- a/osgi-tests/src/test/java/com/datastax/oss/driver/internal/osgi/checks/GraphServiceChecks.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.oss.driver.internal.osgi.checks; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.oss.driver.api.osgi.service.MailboxException; -import com.datastax.oss.driver.api.osgi.service.MailboxMessage; -import com.datastax.oss.driver.api.osgi.service.graph.GraphMailboxService; -import java.time.Instant; -import java.util.ArrayList; -import java.util.List; - -public class GraphServiceChecks { - - public static void checkGraphService(GraphMailboxService service) throws MailboxException { - // Insert some data into mailbox for a particular user. - String recipient = "user@datastax.com"; - List insertedMessages = new ArrayList<>(); - for (int i = 0; i < 30; i++) { - Instant timestamp = Instant.ofEpochMilli(i); - MailboxMessage message = new MailboxMessage(recipient, timestamp, "sender" + i, "body" + i); - insertedMessages.add(message); - service.sendGraphMessage(message); - } - Iterable retrievedMessages = service.getGraphMessages(recipient); - assertThat(retrievedMessages).containsExactlyElementsOf(insertedMessages); - } -} diff --git a/osgi-tests/src/test/java/com/datastax/oss/driver/internal/osgi/support/BundleOptions.java b/osgi-tests/src/test/java/com/datastax/oss/driver/internal/osgi/support/BundleOptions.java index ffac828a0a8..7c3995cd005 100644 --- a/osgi-tests/src/test/java/com/datastax/oss/driver/internal/osgi/support/BundleOptions.java +++ b/osgi-tests/src/test/java/com/datastax/oss/driver/internal/osgi/support/BundleOptions.java @@ -28,7 +28,6 @@ import org.ops4j.pax.exam.CoreOptions; import org.ops4j.pax.exam.options.CompositeOption; import org.ops4j.pax.exam.options.UrlProvisionOption; -import org.ops4j.pax.exam.options.WrappedUrlProvisionOption; public class BundleOptions { @@ -128,67 +127,6 @@ public static CompositeOption snappyBundle() { systemProperty("cassandra.compression").value("SNAPPY")); } - public static CompositeOption tinkerpopBundles() { - return () -> - options( - CoreOptions.wrappedBundle( - mavenBundle("org.apache.tinkerpop", "gremlin-core").versionAsInProject()) - .exports( - // avoid exporting 'org.apache.tinkerpop.gremlin.*' as other Tinkerpop jars have - // this root package as well - "org.apache.tinkerpop.gremlin.jsr223.*", - "org.apache.tinkerpop.gremlin.process.*", - "org.apache.tinkerpop.gremlin.structure.*", - "org.apache.tinkerpop.gremlin.util.*") - .bundleSymbolicName("org.apache.tinkerpop.gremlin-core") - .overwriteManifest(WrappedUrlProvisionOption.OverwriteMode.FULL), - CoreOptions.wrappedBundle( - mavenBundle("org.apache.tinkerpop", "tinkergraph-gremlin").versionAsInProject()) - .exports("org.apache.tinkerpop.gremlin.tinkergraph.*") - .bundleSymbolicName("org.apache.tinkerpop.tinkergraph-gremlin") - .overwriteManifest(WrappedUrlProvisionOption.OverwriteMode.FULL), - CoreOptions.wrappedBundle( - mavenBundle("org.apache.tinkerpop", "gremlin-shaded").versionAsInProject()) - .exports("org.apache.tinkerpop.shaded.*") - .bundleSymbolicName("org.apache.tinkerpop.gremlin-shaded") - .overwriteManifest(WrappedUrlProvisionOption.OverwriteMode.FULL), - // Note: the versions below are hard-coded because they shouldn't change very often, - // but if the tests fail because of them, we should consider parameterizing them - mavenBundle("com.sun.activation", "jakarta.activation", "2.0.1"), - mavenBundle("com.sun.mail", "mailapi", "2.0.1"), - mavenBundle("org.apache.commons", "commons-text", "1.8"), - mavenBundle("org.apache.commons", "commons-configuration2", "2.9.0"), - CoreOptions.wrappedBundle(mavenBundle("commons-logging", "commons-logging", "1.1.1")) - .exports("org.apache.commons.logging.*") - .bundleVersion("1.1.1") - .bundleSymbolicName("org.apache.commons.commons-logging") - .overwriteManifest(WrappedUrlProvisionOption.OverwriteMode.FULL), - mavenBundle("commons-collections", "commons-collections", "3.2.2"), - mavenBundle("org.apache.commons", "commons-lang3", "3.8.1"), - mavenBundle("commons-lang", "commons-lang", "2.6"), - CoreOptions.wrappedBundle(mavenBundle("org.javatuples", "javatuples", "1.2")) - .exports("org.javatuples.*") - .bundleVersion("1.2") - .bundleSymbolicName("org.javatuples") - .overwriteManifest(WrappedUrlProvisionOption.OverwriteMode.FULL), - systemProperty("cassandra.graph").value("true"), - systemProperty("cassandra.graph.name").value("test_osgi_graph")); - } - - public static CompositeOption esriBundles() { - return () -> - options( - CoreOptions.wrappedBundle( - mavenBundle("com.esri.geometry", "esri-geometry-api").versionAsInProject()) - .exports("com.esri.core.geometry.*") - .imports("org.json", "org.codehaus.jackson") - .bundleSymbolicName("com.esri.core.geometry") - .overwriteManifest(WrappedUrlProvisionOption.OverwriteMode.FULL), - mavenBundle("org.json", "json").versionAsInProject(), - mavenBundle("org.codehaus.jackson", "jackson-core-asl").versionAsInProject(), - systemProperty("cassandra.geo").value("true")); - } - public static CompositeOption reactiveBundles() { return () -> options( diff --git a/osgi-tests/src/test/java/com/datastax/oss/driver/internal/osgi/support/CcmStagedReactor.java b/osgi-tests/src/test/java/com/datastax/oss/driver/internal/osgi/support/CcmStagedReactor.java index ce4d9095361..85fa0e0da2e 100644 --- a/osgi-tests/src/test/java/com/datastax/oss/driver/internal/osgi/support/CcmStagedReactor.java +++ b/osgi-tests/src/test/java/com/datastax/oss/driver/internal/osgi/support/CcmStagedReactor.java @@ -17,11 +17,8 @@ */ package com.datastax.oss.driver.internal.osgi.support; -import com.datastax.oss.driver.api.core.Version; import com.datastax.oss.driver.api.testinfra.ccm.CcmBridge; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; import java.util.List; -import java.util.Objects; import net.jcip.annotations.GuardedBy; import org.ops4j.pax.exam.TestContainer; import org.ops4j.pax.exam.TestProbeBuilder; @@ -35,14 +32,8 @@ public class CcmStagedReactor extends AllConfinedStagedReactor { public static final CcmBridge CCM_BRIDGE; - public static final Version DSE_5_0 = Objects.requireNonNull(Version.parse("5.0")); - static { - CcmBridge.Builder builder = CcmBridge.builder().withNodes(1); - if (CcmBridge.isDistributionOf(BackendType.DSE, (dist, cass) -> dist.compareTo(DSE_5_0) >= 0)) { - builder.withDseWorkloads("graph"); - } - CCM_BRIDGE = builder.build(); + CCM_BRIDGE = CcmBridge.builder().withNodes(1).build(); } @GuardedBy("this") diff --git a/osgi-tests/src/test/resources/logback-test.xml b/osgi-tests/src/test/resources/logback-test.xml index 6c2a3f70250..94c73e05918 100644 --- a/osgi-tests/src/test/resources/logback-test.xml +++ b/osgi-tests/src/test/resources/logback-test.xml @@ -28,7 +28,8 @@ - + + diff --git a/performance/duration-test.yaml b/performance/duration-test.yaml index de76b9e1e1f..3586ded7abc 100644 --- a/performance/duration-test.yaml +++ b/performance/duration-test.yaml @@ -15,7 +15,7 @@ # specific language governing permissions and limitations # under the License. -# Possible values: cassandra or dse +# Possible values: cassandra or scylla server_type: cassandra # Server version (e.g. 3.11.7 or 6.8.8) server_version: 3.11.7 diff --git a/pom.xml b/pom.xml index 76caea447cc..fddda203246 100644 --- a/pom.xml +++ b/pom.xml @@ -59,19 +59,11 @@ 2.2.2 4.2.38 4.1.136.Final - 1.2.1 - - 3.5.6 2.0.18 1.0.4 - 20250517 2.22.1 - 1.9.12 1.1.10.8 1.11.1 @@ -93,7 +85,6 @@ 2.2.21 4.3.0 1.5.9 - 2.0.0-M19 3.5.5 22.0.0.2 false @@ -233,44 +224,6 @@ HdrHistogram ${hdrhistogram.version} - - com.esri.geometry - esri-geometry-api - ${esri.version} - - - org.json - json - ${json.version} - - - org.apache.tinkerpop - gremlin-core - ${tinkerpop.version} - - - org.yaml - snakeyaml - - - com.carrotsearch - hppc - - - com.jcabi - * - - - net.objecthunter - exp4j - - - - - org.apache.tinkerpop - tinkergraph-gremlin - ${tinkerpop.version} - org.reactivestreams reactive-streams @@ -446,47 +399,6 @@ testng 7.12.0 - - org.apache.directory.server - apacheds-core - ${apacheds.version} - - - org.slf4j - slf4j-log4j12 - - - - - org.apache.directory.server - apacheds-protocol-kerberos - ${apacheds.version} - - - org.apache.directory.server - apacheds-interceptor-kerberos - ${apacheds.version} - - - org.apache.directory.server - apacheds-protocol-ldap - ${apacheds.version} - - - org.apache.directory.server - apacheds-ldif-partition - ${apacheds.version} - - - org.apache.directory.server - apacheds-jdbm-partition - ${apacheds.version} - - - org.apache.directory.api - api-ldap-codec-standalone - 2.1.7 - com.github.tomakehurst wiremock @@ -892,6 +804,7 @@ height="0" width="0" style="display:none;visibility:hidden"> -preventleak com.datastax.oss.driver.internal + com.datastax.dse.driver.internal -preventleak diff --git a/query-builder/pom.xml b/query-builder/pom.xml index efc52b9de6b..6f276b77755 100644 --- a/query-builder/pom.xml +++ b/query-builder/pom.xml @@ -133,28 +133,10 @@ com.datastax.oss.driver.querybuilder !net.jcip.annotations.*, !edu.umd.cs.findbugs.annotations.*, * - com.datastax.oss.driver.*.querybuilder.*, com.datastax.dse.driver.*.querybuilder.* + com.datastax.oss.driver.*.querybuilder.* - - maven-dependency-plugin - - - generate-dependency-list - - list - - generate-resources - - runtime - true - com.datastax.cassandra,com.datastax.dse - ${project.build.outputDirectory}/com/datastax/dse/driver/internal/querybuilder/deps.txt - - - - diff --git a/query-builder/revapi.json b/query-builder/revapi.json index ed97379332c..17431c26134 100644 --- a/query-builder/revapi.json +++ b/query-builder/revapi.json @@ -5,8 +5,8 @@ "packages": { "regex": true, "exclude": [ - "com\\.datastax\\.(oss|dse)\\.protocol\\.internal(\\..+)?", - "com\\.datastax\\.(oss|dse)\\.driver\\.internal(\\..+)?", + "com\\.datastax\\.oss\\.protocol\\.internal(\\..+)?", + "com\\.datastax\\.oss\\.driver\\.internal(\\..+)?", "com\\.datastax\\.oss\\.driver\\.shaded(\\..+)?", "org\\.assertj(\\..+)?", "// Don't re-check sibling modules that this module depends on", diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/DseQueryBuilder.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/DseQueryBuilder.java deleted file mode 100644 index 24e606897e5..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/DseQueryBuilder.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder; - -import com.datastax.oss.driver.api.querybuilder.QueryBuilder; - -/** - * A DSE extension of the Cassandra driver's {@linkplain QueryBuilder query builder}. - * - *

Note that, at this time, this class acts a simple pass-through: there is no DSE-specific - * syntax for DML queries, therefore it just inherits all of {@link QueryBuilder}'s methods, without - * adding any of its own. - * - *

However, it is a good idea to use it as the entry point to the DSL in your DSE application, to - * avoid changing all your imports if specialized methods get added here in the future. - */ -public class DseQueryBuilder extends QueryBuilder { - // nothing to do -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/DseSchemaBuilder.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/DseSchemaBuilder.java deleted file mode 100644 index 456746204b5..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/DseSchemaBuilder.java +++ /dev/null @@ -1,328 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder; - -import com.datastax.dse.driver.api.querybuilder.schema.AlterDseKeyspaceStart; -import com.datastax.dse.driver.api.querybuilder.schema.AlterDseTableStart; -import com.datastax.dse.driver.api.querybuilder.schema.CreateDseAggregateStart; -import com.datastax.dse.driver.api.querybuilder.schema.CreateDseFunctionStart; -import com.datastax.dse.driver.api.querybuilder.schema.CreateDseKeyspaceStart; -import com.datastax.dse.driver.api.querybuilder.schema.CreateDseTableStart; -import com.datastax.dse.driver.internal.querybuilder.schema.DefaultAlterDseKeyspace; -import com.datastax.dse.driver.internal.querybuilder.schema.DefaultAlterDseTable; -import com.datastax.dse.driver.internal.querybuilder.schema.DefaultCreateDseAggregate; -import com.datastax.dse.driver.internal.querybuilder.schema.DefaultCreateDseFunction; -import com.datastax.dse.driver.internal.querybuilder.schema.DefaultCreateDseKeyspace; -import com.datastax.dse.driver.internal.querybuilder.schema.DefaultCreateDseTable; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.querybuilder.SchemaBuilder; -import com.datastax.oss.driver.api.querybuilder.schema.CreateAggregateStart; -import com.datastax.oss.driver.api.querybuilder.schema.CreateFunctionStart; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; - -/** - * An extension of {@link com.datastax.oss.driver.api.querybuilder.SchemaBuilder} for building - * schema entities that have DSE specific functionality. - */ -public class DseSchemaBuilder extends SchemaBuilder { - - /** - * Starts a CREATE AGGREGATE query with the given aggregate name. This assumes the keyspace name - * is already qualified for the Session or Statement. - */ - @NonNull - public static CreateDseAggregateStart createDseAggregate(@NonNull CqlIdentifier aggregateId) { - return new DefaultCreateDseAggregate(aggregateId); - } - - /** Starts a CREATE AGGREGATE query with the given aggregate name for the given keyspace name. */ - @NonNull - public static CreateDseAggregateStart createDseAggregate( - @Nullable CqlIdentifier keyspaceId, @NonNull CqlIdentifier aggregateId) { - return new DefaultCreateDseAggregate(keyspaceId, aggregateId); - } - - /** - * Shortcut for {@link #createDseAggregate(CqlIdentifier) - * createDseAggregate(CqlIdentifier.fromCql(aggregateName))}. - */ - @NonNull - public static CreateDseAggregateStart createDseAggregate(@NonNull String aggregateName) { - return new DefaultCreateDseAggregate(CqlIdentifier.fromCql(aggregateName)); - } - - /** - * Shortcut for {@link #createAggregate(CqlIdentifier, CqlIdentifier) - * createDseAggregate(CqlIdentifier.fromCql(keyspaceName), CqlIdentifier.fromCql(aggregateName))}. - */ - @NonNull - public static CreateDseAggregateStart createDseAggregate( - @Nullable String keyspaceName, @NonNull String aggregateName) { - return new DefaultCreateDseAggregate( - keyspaceName == null ? null : CqlIdentifier.fromCql(keyspaceName), - CqlIdentifier.fromCql(aggregateName)); - } - - /** - * Starts a CREATE AGGREGATE query with the given aggregate name. This assumes the keyspace name - * is already qualified for the Session or Statement. - * - *

Note that this method only covers open-source Cassandra syntax. If you want to use - * DSE-specific features, such as the {@code DETERMINISTIC} keyword, use {@link - * #createDseAggregate(CqlIdentifier)}. - */ - @NonNull - public static CreateAggregateStart createAggregate(@NonNull CqlIdentifier aggregateName) { - return SchemaBuilder.createAggregate(aggregateName); - } - - /** - * Starts a CREATE AGGREGATE query with the given aggregate name for the given keyspace name. - * - *

Note that this method only covers open-source Cassandra syntax. If you want to use - * DSE-specific features, such as the {@code DETERMINISTIC} keyword, use {@link - * #createDseAggregate(CqlIdentifier, CqlIdentifier)}. - */ - @NonNull - public static CreateAggregateStart createAggregate( - @Nullable CqlIdentifier keyspace, @NonNull CqlIdentifier aggregateName) { - return SchemaBuilder.createAggregate(keyspace, aggregateName); - } - - /** - * Shortcut for {@link #createAggregate(CqlIdentifier) - * createAggregate(CqlIdentifier.fromCql(aggregateName)}. - * - *

Note that this method only covers open-source Cassandra syntax. If you want to use - * DSE-specific features, such as the {@code DETERMINISTIC} keyword, use {@link - * #createDseAggregate(String)}. - */ - @NonNull - public static CreateAggregateStart createAggregate(@NonNull String aggregateName) { - return SchemaBuilder.createAggregate(aggregateName); - } - - /** - * Shortcut for {@link #createAggregate(CqlIdentifier, CqlIdentifier) - * createAggregate(CqlIdentifier.fromCql(keyspace), CqlIdentifier.fromCql(aggregateName)}. - * - *

Note that this method only covers open-source Cassandra syntax. If you want to use - * DSE-specific features, such as the {@code DETERMINISTIC} keyword, use {@link - * #createDseAggregate(String, String)}. - */ - @NonNull - public static CreateAggregateStart createAggregate( - @Nullable String keyspace, @NonNull String aggregateName) { - return SchemaBuilder.createAggregate(keyspace, aggregateName); - } - - /** - * Starts a CREATE FUNCTION query with the given function name. This assumes the keyspace name is - * already qualified for the Session or Statement. - */ - @NonNull - public static CreateDseFunctionStart createDseFunction(@NonNull CqlIdentifier functionId) { - return new DefaultCreateDseFunction(functionId); - } - - /** Starts a CREATE FUNCTION query with the given function name for the given keyspace name. */ - @NonNull - public static CreateDseFunctionStart createDseFunction( - @Nullable CqlIdentifier keyspaceId, @NonNull CqlIdentifier functionId) { - return new DefaultCreateDseFunction(keyspaceId, functionId); - } - - /** - * Shortcut for {@link #createFunction(CqlIdentifier) - * createFunction(CqlIdentifier.fromCql(functionName)} - */ - @NonNull - public static CreateDseFunctionStart createDseFunction(@NonNull String functionName) { - return new DefaultCreateDseFunction(CqlIdentifier.fromCql(functionName)); - } - - /** - * Shortcut for {@link #createFunction(CqlIdentifier, CqlIdentifier) - * createFunction(CqlIdentifier.fromCql(keyspaceName), CqlIdentifier.fromCql(functionName)} - */ - @NonNull - public static CreateDseFunctionStart createDseFunction( - @Nullable String keyspaceName, @NonNull String functionName) { - return new DefaultCreateDseFunction( - keyspaceName == null ? null : CqlIdentifier.fromCql(keyspaceName), - CqlIdentifier.fromCql(functionName)); - } - - /** - * Starts a CREATE FUNCTION query with the given function name. This assumes the keyspace name is - * already qualified for the Session or Statement. - * - *

Note that this method only covers open-source Cassandra syntax. If you want to use - * DSE-specific features, such as the {@code MONOTONIC} or {@code DETERMINISTIC} keywords, use - * {@link #createDseFunction(CqlIdentifier)}. - */ - @NonNull - public static CreateFunctionStart createFunction(@NonNull CqlIdentifier functionName) { - return SchemaBuilder.createFunction(functionName); - } - - /** - * Starts a CREATE FUNCTION query with the given function name for the given keyspace name. - * - *

Note that this method only covers open-source Cassandra syntax. If you want to use - * DSE-specific features, such as the {@code MONOTONIC} or {@code DETERMINISTIC} keywords, use - * {@link #createDseFunction(CqlIdentifier,CqlIdentifier)}. - */ - @NonNull - public static CreateFunctionStart createFunction( - @Nullable CqlIdentifier keyspace, @NonNull CqlIdentifier functionName) { - return SchemaBuilder.createFunction(keyspace, functionName); - } - - /** - * Shortcut for {@link #createFunction(CqlIdentifier, CqlIdentifier) - * createFunction(CqlIdentifier.fromCql(keyspace, functionName)} - * - *

Note that this method only covers open-source Cassandra syntax. If you want to use - * DSE-specific features, such as the {@code MONOTONIC} or {@code DETERMINISTIC} keywords, use - * {@link #createDseFunction(String)}. - */ - @NonNull - public static CreateFunctionStart createFunction(@NonNull String functionName) { - return SchemaBuilder.createFunction(functionName); - } - - /** - * Shortcut for {@link #createFunction(CqlIdentifier) - * createFunction(CqlIdentifier.fromCql(keyspaceName),CqlIdentifier.fromCql(functionName)}. - * - *

Note that this method only covers open-source Cassandra syntax. If you want to use - * DSE-specific features, such as the {@code MONOTONIC} or {@code DETERMINISTIC} keywords, use - * {@link #createDseFunction(String, String)}. - */ - @NonNull - public static CreateFunctionStart createFunction( - @Nullable String keyspace, @NonNull String functionName) { - return SchemaBuilder.createFunction(keyspace, functionName); - } - - /** Starts a CREATE KEYSPACE query. */ - @NonNull - public static CreateDseKeyspaceStart createDseKeyspace(@NonNull CqlIdentifier keyspaceName) { - return new DefaultCreateDseKeyspace(keyspaceName); - } - - /** - * Shortcut for {@link #createDseKeyspace(CqlIdentifier) - * createKeyspace(CqlIdentifier.fromCql(keyspaceName))} - */ - @NonNull - public static CreateDseKeyspaceStart createDseKeyspace(@NonNull String keyspaceName) { - return createDseKeyspace(CqlIdentifier.fromCql(keyspaceName)); - } - - /** Starts an ALTER KEYSPACE query. */ - @NonNull - public static AlterDseKeyspaceStart alterDseKeyspace(@NonNull CqlIdentifier keyspaceName) { - return new DefaultAlterDseKeyspace(keyspaceName); - } - - /** - * Shortcut for {@link #alterDseKeyspace(CqlIdentifier) - * alterKeyspace(CqlIdentifier.fromCql(keyspaceName)}. - */ - @NonNull - public static AlterDseKeyspaceStart alterDseKeyspace(@NonNull String keyspaceName) { - return DseSchemaBuilder.alterDseKeyspace(CqlIdentifier.fromCql(keyspaceName)); - } - - /** - * Starts a CREATE TABLE query with the given table name. This assumes the keyspace name is - * already qualified for the Session or Statement. - */ - @NonNull - public static CreateDseTableStart createDseTable(@NonNull CqlIdentifier tableName) { - return createDseTable(null, tableName); - } - - /** Starts a CREATE TABLE query with the given table name for the given keyspace name. */ - @NonNull - public static CreateDseTableStart createDseTable( - @Nullable CqlIdentifier keyspace, @NonNull CqlIdentifier tableName) { - return new DefaultCreateDseTable(keyspace, tableName); - } - - /** - * Shortcut for {@link #createDseTable(CqlIdentifier) - * createDseTable(CqlIdentifier.fromCql(tableName)} - */ - @NonNull - public static CreateDseTableStart createDseTable(@NonNull String tableName) { - return createDseTable(CqlIdentifier.fromCql(tableName)); - } - - /** - * Shortcut for {@link #createDseTable(CqlIdentifier,CqlIdentifier) - * createDseTable(CqlIdentifier.fromCql(keyspaceName),CqlIdentifier.fromCql(tableName)} - */ - @NonNull - public static CreateDseTableStart createDseTable( - @Nullable String keyspace, @NonNull String tableName) { - return createDseTable( - keyspace == null ? null : CqlIdentifier.fromCql(keyspace), - CqlIdentifier.fromCql(tableName)); - } - - /** - * Starts an ALTER TABLE query with the given table name. This assumes the keyspace name is - * already qualified for the Session or Statement. - */ - @NonNull - public static AlterDseTableStart alterDseTable(@NonNull CqlIdentifier tableName) { - return new DefaultAlterDseTable(tableName); - } - - /** Starts an ALTER TABLE query with the given table name for the given keyspace name. */ - @NonNull - public static AlterDseTableStart alterDseTable( - @Nullable CqlIdentifier keyspace, @NonNull CqlIdentifier tableName) { - return new DefaultAlterDseTable(keyspace, tableName); - } - - /** - * Shortcut for {@link #alterDseTable(CqlIdentifier) - * alterDseTable(CqlIdentifier.fromCql(tableName)} - */ - @NonNull - public static AlterDseTableStart alterDseTable(@NonNull String tableName) { - return alterDseTable(CqlIdentifier.fromCql(tableName)); - } - - /** - * Shortcut for {@link #alterDseTable(CqlIdentifier,CqlIdentifier) - * alterDseTable(CqlIdentifier.fromCql(keyspaceName),CqlIdentifier.fromCql(tableName)} - */ - @NonNull - public static AlterDseTableStart alterDseTable( - @Nullable String keyspace, @NonNull String tableName) { - return alterDseTable( - keyspace == null ? null : CqlIdentifier.fromCql(keyspace), - CqlIdentifier.fromCql(tableName)); - } -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/package-info.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/package-info.java deleted file mode 100644 index 05f9d4e6912..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This package effectively mirrors the Cassandra OSS Query Builder package to allow DSE extended - * schema and query building for the DSE driver. In general, a class in this package should simply - * extend the equivalent class in the OSS driver and add extended functionality. - */ -package com.datastax.dse.driver.api.querybuilder; diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseKeyspace.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseKeyspace.java deleted file mode 100644 index c7aa795ae24..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseKeyspace.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import com.datastax.oss.driver.api.querybuilder.BuildableQuery; -import com.datastax.oss.driver.api.querybuilder.schema.KeyspaceOptions; -import com.datastax.oss.driver.api.querybuilder.schema.KeyspaceReplicationOptions; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Map; - -public interface AlterDseKeyspace - extends BuildableQuery, - KeyspaceOptions, - KeyspaceReplicationOptions { - - @NonNull - @Override - AlterDseKeyspace withOption(@NonNull String name, @NonNull Object value); - - /** - * Adjusts durable writes configuration for this keyspace. If set to false, data written to the - * keyspace will bypass the commit log. - */ - @NonNull - @Override - AlterDseKeyspace withDurableWrites(boolean durableWrites); - - /** Adjusts the graph engine that will be used to interpret this keyspace. */ - @NonNull - AlterDseKeyspace withGraphEngine(String graphEngine); - - /** - * Adds 'replication' options. One should only use this when they have a custom replication - * strategy, otherwise it is advisable to use {@link #withSimpleStrategy(int)} or {@link - * #withNetworkTopologyStrategy(Map)}. - */ - @NonNull - @Override - AlterDseKeyspace withReplicationOptions(@NonNull Map replicationOptions); - - /** - * Adds SimpleStrategy replication options with the given replication factor. - * - *

Note that using this will overwrite any previous use of this method or {@link - * #withNetworkTopologyStrategy(Map)}. - */ - @NonNull - @Override - AlterDseKeyspace withSimpleStrategy(int replicationFactor); - - /** - * Adds NetworkTopologyStrategy replication options with the given data center replication - * factors. - * - *

Note that using this will overwrite any previous use of this method or {@link - * #withSimpleStrategy(int)}. - * - * @param replications Mapping of data center name to replication factor to use for that data - * center. - */ - @NonNull - @Override - AlterDseKeyspace withNetworkTopologyStrategy(@NonNull Map replications); -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseKeyspaceStart.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseKeyspaceStart.java deleted file mode 100644 index 6a36d4b4d46..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseKeyspaceStart.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import com.datastax.oss.driver.api.querybuilder.schema.KeyspaceOptions; -import com.datastax.oss.driver.api.querybuilder.schema.KeyspaceReplicationOptions; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Map; - -public interface AlterDseKeyspaceStart - extends KeyspaceOptions, KeyspaceReplicationOptions { - - @NonNull - @Override - AlterDseKeyspace withOption(@NonNull String name, @NonNull Object value); - - /** - * Adjusts durable writes configuration for this keyspace. If set to false, data written to the - * keyspace will bypass the commit log. - */ - @NonNull - @Override - AlterDseKeyspace withDurableWrites(boolean durableWrites); - - /** Adjusts the graph engine that will be used to interpret this keyspace. */ - @NonNull - AlterDseKeyspace withGraphEngine(String graphEngine); - - /** - * Adds 'replication' options. One should only use this when they have a custom replication - * strategy, otherwise it is advisable to use {@link #withSimpleStrategy(int)} or {@link - * #withNetworkTopologyStrategy(Map)}. - */ - @NonNull - @Override - AlterDseKeyspace withReplicationOptions(@NonNull Map replicationOptions); - - /** - * Adds SimpleStrategy replication options with the given replication factor. - * - *

Note that using this will overwrite any previous use of this method or {@link - * #withNetworkTopologyStrategy(Map)}. - */ - @NonNull - @Override - AlterDseKeyspace withSimpleStrategy(int replicationFactor); - - /** - * Adds NetworkTopologyStrategy replication options with the given data center replication - * factors. - * - *

Note that using this will overwrite any previous use of this method or {@link - * #withSimpleStrategy(int)}. - * - * @param replications Mapping of data center name to replication factor to use for that data - * center. - */ - @NonNull - @Override - AlterDseKeyspace withNetworkTopologyStrategy(@NonNull Map replications); -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableAddColumn.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableAddColumn.java deleted file mode 100644 index c5f05a661b9..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableAddColumn.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.type.DataType; -import com.datastax.oss.driver.api.core.type.DataTypes; -import com.datastax.oss.driver.api.querybuilder.SchemaBuilder; -import edu.umd.cs.findbugs.annotations.NonNull; - -public interface AlterDseTableAddColumn { - /** - * Adds a column definition in the ALTER TABLE statement. - * - *

To create the data type, use the constants and static methods in {@link DataTypes}, or - * {@link SchemaBuilder#udt(CqlIdentifier, boolean)}. - */ - @NonNull - AlterDseTableAddColumnEnd addColumn( - @NonNull CqlIdentifier columnName, @NonNull DataType dataType); - - /** - * Shortcut for {@link #addColumn(CqlIdentifier, DataType) - * addColumn(CqlIdentifier.asCql(columnName), dataType)}. - */ - @NonNull - default AlterDseTableAddColumnEnd addColumn( - @NonNull String columnName, @NonNull DataType dataType) { - return addColumn(CqlIdentifier.fromCql(columnName), dataType); - } - - /** - * Adds a static column definition in the ALTER TABLE statement. - * - *

To create the data type, use the constants and static methods in {@link DataTypes}, or - * {@link SchemaBuilder#udt(CqlIdentifier, boolean)}. - */ - @NonNull - AlterDseTableAddColumnEnd addStaticColumn( - @NonNull CqlIdentifier columnName, @NonNull DataType dataType); - - /** - * Shortcut for {@link #addStaticColumn(CqlIdentifier, DataType) - * addStaticColumn(CqlIdentifier.asCql(columnName), dataType)}. - */ - @NonNull - default AlterDseTableAddColumnEnd addStaticColumn( - @NonNull String columnName, @NonNull DataType dataType) { - return addStaticColumn(CqlIdentifier.fromCql(columnName), dataType); - } -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableAddColumnEnd.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableAddColumnEnd.java deleted file mode 100644 index 80d3cc2a665..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableAddColumnEnd.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import com.datastax.oss.driver.api.querybuilder.BuildableQuery; - -public interface AlterDseTableAddColumnEnd extends AlterDseTableAddColumn, BuildableQuery {} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableDropColumn.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableDropColumn.java deleted file mode 100644 index 50e672f8e6e..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableDropColumn.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import com.datastax.oss.driver.api.core.CqlIdentifier; -import edu.umd.cs.findbugs.annotations.NonNull; - -public interface AlterDseTableDropColumn { - /** - * Adds column(s) to drop to ALTER TABLE specification. This may be repeated with successive calls - * to drop columns. - */ - @NonNull - AlterDseTableDropColumnEnd dropColumns(@NonNull CqlIdentifier... columnNames); - - /** Shortcut for {@link #dropColumns(CqlIdentifier...)}. */ - @NonNull - default AlterDseTableDropColumnEnd dropColumns(@NonNull String... columnNames) { - CqlIdentifier ids[] = new CqlIdentifier[columnNames.length]; - for (int i = 0; i < columnNames.length; i++) { - ids[i] = CqlIdentifier.fromCql(columnNames[i]); - } - return dropColumns(ids); - } - - /** - * Adds a column to drop to ALTER TABLE specification. This may be repeated with successive calls - * to drop columns. Shortcut for {@link #dropColumns(CqlIdentifier...) #dropColumns(columnName)}. - */ - @NonNull - default AlterDseTableDropColumnEnd dropColumn(@NonNull CqlIdentifier columnName) { - return dropColumns(columnName); - } - - /** - * Shortcut for {@link #dropColumn(CqlIdentifier) dropColumn(CqlIdentifier.fromCql(columnName))}. - */ - @NonNull - default AlterDseTableDropColumnEnd dropColumn(@NonNull String columnName) { - return dropColumns(CqlIdentifier.fromCql(columnName)); - } -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableDropColumnEnd.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableDropColumnEnd.java deleted file mode 100644 index 7e3d424eb31..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableDropColumnEnd.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import com.datastax.oss.driver.api.querybuilder.BuildableQuery; - -public interface AlterDseTableDropColumnEnd extends AlterDseTableDropColumn, BuildableQuery {} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableRenameColumn.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableRenameColumn.java deleted file mode 100644 index 7a24a76f4ab..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableRenameColumn.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import com.datastax.oss.driver.api.core.CqlIdentifier; -import edu.umd.cs.findbugs.annotations.NonNull; - -public interface AlterDseTableRenameColumn { - - /** - * Adds a column rename to ALTER TABLE specification. This may be repeated with successive calls - * to rename columns. - */ - @NonNull - AlterDseTableRenameColumnEnd renameColumn(@NonNull CqlIdentifier from, @NonNull CqlIdentifier to); - - /** - * Shortcut for {@link #renameColumn(CqlIdentifier, CqlIdentifier) - * renameField(CqlIdentifier.fromCql(from),CqlIdentifier.fromCql(to))}. - */ - @NonNull - default AlterDseTableRenameColumnEnd renameColumn(@NonNull String from, @NonNull String to) { - return renameColumn(CqlIdentifier.fromCql(from), CqlIdentifier.fromCql(to)); - } -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableRenameColumnEnd.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableRenameColumnEnd.java deleted file mode 100644 index db2890b844b..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableRenameColumnEnd.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import com.datastax.oss.driver.api.querybuilder.BuildableQuery; - -public interface AlterDseTableRenameColumnEnd extends AlterDseTableRenameColumn, BuildableQuery {} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableStart.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableStart.java deleted file mode 100644 index bb34bb3fb38..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableStart.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.type.DataType; -import com.datastax.oss.driver.api.core.type.DataTypes; -import com.datastax.oss.driver.api.querybuilder.BuildableQuery; -import com.datastax.oss.driver.api.querybuilder.SchemaBuilder; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; - -public interface AlterDseTableStart - extends AlterDseTableWithOptions, - AlterDseTableAddColumn, - AlterDseTableDropColumn, - AlterDseTableRenameColumn, - DseTableGraphOptions { - - /** Completes ALTER TABLE specifying that compact storage should be removed from the table. */ - @NonNull - BuildableQuery dropCompactStorage(); - - /** - * Completes ALTER TABLE specifying the the type of a column should be changed. - * - *

To create the data type, use the constants and static methods in {@link DataTypes}, or - * {@link SchemaBuilder#udt(CqlIdentifier, boolean)}. - */ - @NonNull - BuildableQuery alterColumn(@NonNull CqlIdentifier columnName, @NonNull DataType dataType); - - /** - * Shortcut for {@link #alterColumn(CqlIdentifier, DataType) - * alterColumn(CqlIdentifier.fromCql(columnName,dataType)}. - */ - @NonNull - default BuildableQuery alterColumn(@NonNull String columnName, @NonNull DataType dataType) { - return alterColumn(CqlIdentifier.fromCql(columnName), dataType); - } - - /** Removes the named vertex label from this table. */ - @NonNull - BuildableQuery withoutVertexLabel(@Nullable CqlIdentifier vertexLabelId); - - /** - * Shortcut for {@link #withoutVertexLabel(CqlIdentifier) - * withoutVertexLabel(CqlIdentifier.fromCql(vertexLabelName))}. - */ - @NonNull - default BuildableQuery withoutVertexLabel(@NonNull String vertexLabelName) { - return withoutVertexLabel(CqlIdentifier.fromCql(vertexLabelName)); - } - - /** - * Removes the anonymous vertex label from this table. - * - *

This is a shortcut for {@link #withoutVertexLabel(CqlIdentifier) withoutVertexLabel(null)}. - */ - @NonNull - default BuildableQuery withoutVertexLabel() { - return withoutVertexLabel((CqlIdentifier) null); - } - - /** Removes the named edge label from this table. */ - @NonNull - BuildableQuery withoutEdgeLabel(@Nullable CqlIdentifier edgeLabelId); - - /** - * Shortcut for {@link #withoutEdgeLabel(CqlIdentifier) - * withoutEdgeLabel(CqlIdentifier.fromCql(edgeLabelName))}. - */ - @NonNull - default BuildableQuery withoutEdgeLabel(@NonNull String edgeLabelName) { - return withoutEdgeLabel(CqlIdentifier.fromCql(edgeLabelName)); - } - - /** - * Removes the anonymous edge label from this table. - * - *

This is a shortcut for {@link #withoutVertexLabel(CqlIdentifier) withoutEdgeLabel(null)}. - */ - @NonNull - default BuildableQuery withoutEdgeLabel() { - return withoutEdgeLabel((CqlIdentifier) null); - } -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableWithOptions.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableWithOptions.java deleted file mode 100644 index 5713c3f25d6..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableWithOptions.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -public interface AlterDseTableWithOptions extends DseRelationOptions {} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableWithOptionsEnd.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableWithOptionsEnd.java deleted file mode 100644 index ef63881caa8..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableWithOptionsEnd.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import com.datastax.oss.driver.api.querybuilder.BuildableQuery; - -public interface AlterDseTableWithOptionsEnd - extends DseRelationOptions, BuildableQuery {} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseAggregateEnd.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseAggregateEnd.java deleted file mode 100644 index e28c887cd22..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseAggregateEnd.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.querybuilder.BuildableQuery; -import com.datastax.oss.driver.api.querybuilder.term.Term; -import edu.umd.cs.findbugs.annotations.NonNull; - -public interface CreateDseAggregateEnd extends BuildableQuery { - - /** - * Adds INITCOND to the aggregate query. Defines the initial condition, values, of the first - * parameter in the SFUNC. - */ - @NonNull - CreateDseAggregateEnd withInitCond(@NonNull Term term); - - /** - * Adds FINALFUNC to the create aggregate query. This is used to specify what type is returned - * from the state function. - */ - @NonNull - CreateDseAggregateEnd withFinalFunc(@NonNull CqlIdentifier finalFunc); - - /** - * Shortcut for {@link #withFinalFunc(CqlIdentifier) - * withFinalFunc(CqlIdentifier.fromCql(finalFuncName))}. - */ - @NonNull - default CreateDseAggregateEnd withFinalFunc(@NonNull String finalFuncName) { - return withFinalFunc(CqlIdentifier.fromCql(finalFuncName)); - } - - /** - * Adds "DETERMINISTIC" to create aggregate specification. This is used to specify that this - * aggregate always returns the same output for a given input. Requires an initial condition and - * returns a single value. - */ - @NonNull - CreateDseAggregateEnd deterministic(); -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseAggregateStart.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseAggregateStart.java deleted file mode 100644 index 76bece6ca5f..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseAggregateStart.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.type.DataType; -import com.datastax.oss.driver.api.core.type.DataTypes; -import com.datastax.oss.driver.api.querybuilder.SchemaBuilder; -import edu.umd.cs.findbugs.annotations.NonNull; - -public interface CreateDseAggregateStart { - /** - * Adds IF NOT EXISTS to the create aggregate specification. This indicates that the aggregate - * should not be created if it already exists. - */ - @NonNull - CreateDseAggregateStart ifNotExists(); - - /** - * Adds OR REPLACE to the create aggregate specification. This indicates that the aggregate should - * replace an existing aggregate with the same name if it exists. - */ - @NonNull - CreateDseAggregateStart orReplace(); - - /** - * Adds a parameter definition in the CREATE AGGREGATE statement. - * - *

Parameter keys are added in the order of their declaration. - * - *

To create the data type, use the constants and static methods in {@link DataTypes}, or - * {@link SchemaBuilder#udt(CqlIdentifier, boolean)}. - */ - @NonNull - CreateDseAggregateStart withParameter(@NonNull DataType paramType); - - /** Adds SFUNC to the create aggregate specification. This is the state function for each row. */ - @NonNull - CreateDseAggregateStateFunc withSFunc(@NonNull CqlIdentifier sfuncName); - - /** Shortcut for {@link #withSFunc(CqlIdentifier) withSFunc(CqlIdentifier.fromCql(sfuncName))}. */ - @NonNull - default CreateDseAggregateStateFunc withSFunc(@NonNull String sfuncName) { - return withSFunc(CqlIdentifier.fromCql(sfuncName)); - } -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseAggregateStateFunc.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseAggregateStateFunc.java deleted file mode 100644 index deb3b49a34a..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseAggregateStateFunc.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.type.DataType; -import com.datastax.oss.driver.api.core.type.DataTypes; -import com.datastax.oss.driver.api.querybuilder.SchemaBuilder; -import edu.umd.cs.findbugs.annotations.NonNull; - -public interface CreateDseAggregateStateFunc { - - /** - * Adds STYPE to the create aggregate query. This is used to specify what type is returned from - * the state function. - * - *

To create the data type, use the constants and static methods in {@link DataTypes}, or - * {@link SchemaBuilder#udt(CqlIdentifier, boolean)}. - */ - @NonNull - CreateDseAggregateEnd withSType(@NonNull DataType dataType); -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseFunctionEnd.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseFunctionEnd.java deleted file mode 100644 index 901eb1705ab..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseFunctionEnd.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import com.datastax.oss.driver.api.querybuilder.BuildableQuery; - -public interface CreateDseFunctionEnd extends BuildableQuery {} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseFunctionStart.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseFunctionStart.java deleted file mode 100644 index 64a741d62a9..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseFunctionStart.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.type.DataType; -import com.datastax.oss.driver.api.core.type.DataTypes; -import com.datastax.oss.driver.api.querybuilder.SchemaBuilder; -import edu.umd.cs.findbugs.annotations.NonNull; - -public interface CreateDseFunctionStart { - - /** - * Adds IF NOT EXISTS to the create function specification. This indicates that the function - * should not be created if it already exists. - */ - @NonNull - CreateDseFunctionStart ifNotExists(); - - /** - * Adds OR REPLACE to the create function specification. This indicates that the function should - * replace an existing function with the same name if it exists. - */ - @NonNull - CreateDseFunctionStart orReplace(); - - /** - * Adds a parameter definition in the CREATE FUNCTION statement. - * - *

Parameter keys are added in the order of their declaration. - * - *

To create the data type, use the constants and static methods in {@link DataTypes}, or - * {@link SchemaBuilder#udt(CqlIdentifier, boolean)}. - */ - @NonNull - CreateDseFunctionStart withParameter( - @NonNull CqlIdentifier paramName, @NonNull DataType paramType); - - /** - * Shortcut for {@link #withParameter(CqlIdentifier, DataType) - * withParameter(CqlIdentifier.asCql(paramName), dataType)}. - */ - @NonNull - default CreateDseFunctionStart withParameter( - @NonNull String paramName, @NonNull DataType paramType) { - return withParameter(CqlIdentifier.fromCql(paramName), paramType); - } - - /** - * Adds RETURNS NULL ON NULL to the create function specification. This indicates that the body of - * the function should be skipped when null input is provided. - */ - @NonNull - CreateDseFunctionWithNullOption returnsNullOnNull(); - - /** - * Adds CALLED ON NULL to the create function specification. This indicates that the body of the - * function not be skipped when null input is provided. - */ - @NonNull - CreateDseFunctionWithNullOption calledOnNull(); -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseFunctionWithLanguage.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseFunctionWithLanguage.java deleted file mode 100644 index 10935061404..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseFunctionWithLanguage.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import edu.umd.cs.findbugs.annotations.NonNull; - -public interface CreateDseFunctionWithLanguage { - - /** - * Adds AS to the create function specification. This is used to specify the body of the function. - * Note that it is expected that the provided body is properly quoted as this method does not make - * that decision for the user. For simple cases, one should wrap the input in single quotes, i.e. - * 'myBody'. If the body itself contains single quotes, one could use a - * postgres-style string literal, which is surrounded in two dollar signs, i.e. $$ myBody $$ - * . - */ - @NonNull - CreateDseFunctionEnd as(@NonNull String functionBody); - - /** - * Adds AS to the create function specification and quotes the function body. Assumes that if the - * input body contains at least one single quote, to quote the body with two dollar signs, i.e. - * $$ myBody $$, otherwise the body is quoted with single quotes, i.e. - * ' myBody '. If the function body is already quoted {@link #as(String)} should be used - * instead. - */ - @NonNull - default CreateDseFunctionEnd asQuoted(@NonNull String functionBody) { - if (functionBody.contains("'")) { - return as("$$ " + functionBody + " $$"); - } else { - return as('\'' + functionBody + '\''); - } - } -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseFunctionWithNullOption.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseFunctionWithNullOption.java deleted file mode 100644 index 2a44c002852..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseFunctionWithNullOption.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.type.DataType; -import com.datastax.oss.driver.api.core.type.DataTypes; -import com.datastax.oss.driver.api.querybuilder.SchemaBuilder; -import edu.umd.cs.findbugs.annotations.NonNull; - -public interface CreateDseFunctionWithNullOption { - /** - * Adds RETURNS to the create function specification. This is used to specify what type is - * returned from the function. - * - *

To create the data type, use the constants and static methods in {@link DataTypes}, or - * {@link SchemaBuilder#udt(CqlIdentifier, boolean)}. - */ - @NonNull - CreateDseFunctionWithType returnsType(@NonNull DataType dataType); -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseFunctionWithType.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseFunctionWithType.java deleted file mode 100644 index b70facf51a1..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseFunctionWithType.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import com.datastax.oss.driver.api.core.CqlIdentifier; -import edu.umd.cs.findbugs.annotations.NonNull; - -public interface CreateDseFunctionWithType { - /** - * Adds LANGUAGE to the create function specification. This is used to specify what language is - * used in the function body. - */ - @NonNull - CreateDseFunctionWithLanguage withLanguage(@NonNull String language); - - /** - * Adds "LANGUAGE java" to create function specification. Shortcut for {@link - * #withLanguage(String) withLanguage("java")}. - */ - @NonNull - default CreateDseFunctionWithLanguage withJavaLanguage() { - return withLanguage("java"); - } - - /** - * Adds "LANGUAGE javascript" to create function specification. Shortcut for {@link - * #withLanguage(String) withLanguage("javascript")}. - */ - @NonNull - default CreateDseFunctionWithLanguage withJavaScriptLanguage() { - return withLanguage("javascript"); - } - - /** - * Adds "DETERMINISTIC" to create function specification. This is used to specify that this - * function always returns the same output for a given input. - */ - @NonNull - CreateDseFunctionWithType deterministic(); - - /** - * Adds "MONOTONIC" to create function specification. This is used to specify that this function - * is either entirely non-increasing, or entirely non-decreasing. - */ - @NonNull - CreateDseFunctionWithType monotonic(); - - /** - * Adds "MONOTONIC ON" to create function specification. This is used to specify that this - * function has only a single column that is monotonic. If the function is fully monotonic, use - * {@link #monotonic()} instead. - */ - @NonNull - CreateDseFunctionWithType monotonicOn(@NonNull CqlIdentifier monotonicColumn); - - /** - * Shortcut for {@link #monotonicOn(CqlIdentifier) - * monotonicOn(CqlIdentifier.fromCql(monotonicColumn))}. - */ - @NonNull - default CreateDseFunctionWithType monotonicOn(@NonNull String monotonicColumn) { - return monotonicOn(CqlIdentifier.fromCql(monotonicColumn)); - } -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseKeyspace.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseKeyspace.java deleted file mode 100644 index 0fcb87bafbd..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseKeyspace.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import com.datastax.oss.driver.api.querybuilder.BuildableQuery; -import com.datastax.oss.driver.api.querybuilder.schema.KeyspaceOptions; -import edu.umd.cs.findbugs.annotations.NonNull; - -public interface CreateDseKeyspace extends BuildableQuery, KeyspaceOptions { - - @NonNull - @Override - CreateDseKeyspace withOption(@NonNull String name, @NonNull Object value); - - /** - * Adjusts durable writes configuration for this keyspace. If set to false, data written to the - * keyspace will bypass the commit log. - */ - @NonNull - @Override - default CreateDseKeyspace withDurableWrites(boolean durableWrites) { - return withOption("durable_writes", durableWrites); - } - - /** Adjusts the graph engine that will be used to interpret this keyspace. */ - @NonNull - default CreateDseKeyspace withGraphEngine(String graphEngine) { - return this.withOption("graph_engine", graphEngine); - } -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseKeyspaceStart.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseKeyspaceStart.java deleted file mode 100644 index c0ee240c8ff..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseKeyspaceStart.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import com.datastax.oss.driver.api.querybuilder.schema.KeyspaceReplicationOptions; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Map; - -public interface CreateDseKeyspaceStart extends KeyspaceReplicationOptions { - /** - * Adds IF NOT EXISTS to the create keyspace specification. This indicates that the keyspace - * should not be created it already exists. - */ - @NonNull - CreateDseKeyspaceStart ifNotExists(); - - /** - * Adds 'replication' options. One should only use this when they have a custom replication - * strategy, otherwise it is advisable to use {@link #withSimpleStrategy(int)} or {@link - * #withNetworkTopologyStrategy(Map)}. - */ - @NonNull - @Override - CreateDseKeyspace withReplicationOptions(@NonNull Map replicationOptions); - - /** - * Adds SimpleStrategy replication options with the given replication factor. - * - *

Note that using this will overwrite any previous use of this method or {@link - * #withNetworkTopologyStrategy(Map)}. - */ - @NonNull - @Override - default CreateDseKeyspace withSimpleStrategy(int replicationFactor) { - ImmutableMap replication = - ImmutableMap.builder() - .put("class", "SimpleStrategy") - .put("replication_factor", replicationFactor) - .build(); - - return withReplicationOptions(replication); - } - - /** - * Adds NetworkTopologyStrategy replication options with the given data center replication - * factors. - * - *

Note that using this will overwrite any previous use of this method or {@link - * #withSimpleStrategy(int)}. - * - * @param replications Mapping of data center name to replication factor to use for that data - * center. - */ - @NonNull - @Override - default CreateDseKeyspace withNetworkTopologyStrategy( - @NonNull Map replications) { - ImmutableMap.Builder replicationBuilder = - ImmutableMap.builder().put("class", "NetworkTopologyStrategy"); - - for (Map.Entry replication : replications.entrySet()) { - replicationBuilder.put(replication.getKey(), replication.getValue()); - } - - return withReplicationOptions(replicationBuilder.build()); - } -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseTable.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseTable.java deleted file mode 100644 index fa6d008c114..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseTable.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.type.DataType; -import com.datastax.oss.driver.api.core.type.DataTypes; -import com.datastax.oss.driver.api.querybuilder.BuildableQuery; -import com.datastax.oss.driver.api.querybuilder.SchemaBuilder; -import edu.umd.cs.findbugs.annotations.NonNull; - -public interface CreateDseTable - extends BuildableQuery, OngoingDsePartitionKey, CreateDseTableWithOptions { - - /** - * Adds a clustering column definition in the CREATE TABLE statement. - * - *

This includes the column declaration (you don't need an additional {@link - * #withColumn(CqlIdentifier, DataType) addColumn} call). - * - *

Clustering key columns are added in the order of their declaration. - * - *

To create the data type, use the constants and static methods in {@link DataTypes}, or - * {@link SchemaBuilder#udt(CqlIdentifier, boolean)}. - */ - @NonNull - CreateDseTable withClusteringColumn( - @NonNull CqlIdentifier columnName, @NonNull DataType dataType); - - /** - * Shortcut for {@link #withClusteringColumn(CqlIdentifier, DataType) - * withClusteringColumn(CqlIdentifier.asCql(columnName), dataType)}. - */ - @NonNull - default CreateDseTable withClusteringColumn( - @NonNull String columnName, @NonNull DataType dataType) { - return withClusteringColumn(CqlIdentifier.fromCql(columnName), dataType); - } - - /** - * Adds a column definition in the CREATE TABLE statement. - * - *

To create the data type, use the constants and static methods in {@link DataTypes}, or - * {@link SchemaBuilder#udt(CqlIdentifier, boolean)}. - */ - @NonNull - CreateDseTable withColumn(@NonNull CqlIdentifier columnName, @NonNull DataType dataType); - - /** - * Shortcut for {@link #withColumn(CqlIdentifier, DataType) - * withColumn(CqlIdentifier.asCql(columnName), dataType)}. - */ - @NonNull - default CreateDseTable withColumn(@NonNull String columnName, @NonNull DataType dataType) { - return withColumn(CqlIdentifier.fromCql(columnName), dataType); - } - - /** - * Adds a static column definition in the CREATE TABLE statement. - * - *

This includes the column declaration (you don't need an additional {@link - * #withColumn(CqlIdentifier, DataType) addColumn} call). - * - *

To create the data type, use the constants and static methods in {@link DataTypes}, or - * {@link SchemaBuilder#udt(CqlIdentifier, boolean)}. - */ - @NonNull - CreateDseTable withStaticColumn(@NonNull CqlIdentifier columnName, @NonNull DataType dataType); - - /** - * Shortcut for {@link #withStaticColumn(CqlIdentifier, DataType) - * withStaticColumn(CqlIdentifier.asCql(columnName), dataType)}. - */ - @NonNull - default CreateDseTable withStaticColumn(@NonNull String columnName, @NonNull DataType dataType) { - return withStaticColumn(CqlIdentifier.fromCql(columnName), dataType); - } -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseTableStart.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseTableStart.java deleted file mode 100644 index 030668262df..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseTableStart.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import edu.umd.cs.findbugs.annotations.NonNull; - -public interface CreateDseTableStart extends OngoingDsePartitionKey { - - /** - * Adds IF NOT EXISTS to the create table specification. This indicates that the table should not - * be created if it already exists. - */ - @NonNull - CreateDseTableStart ifNotExists(); -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseTableWithOptions.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseTableWithOptions.java deleted file mode 100644 index 3d7b44ef905..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseTableWithOptions.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import com.datastax.oss.driver.api.querybuilder.BuildableQuery; -import edu.umd.cs.findbugs.annotations.NonNull; - -public interface CreateDseTableWithOptions - extends BuildableQuery, - DseRelationStructure, - DseTableGraphOptions { - - /** Enables COMPACT STORAGE in the CREATE TABLE statement. */ - @NonNull - CreateDseTableWithOptions withCompactStorage(); -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/DseGraphEdgeSide.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/DseGraphEdgeSide.java deleted file mode 100644 index 7cfe8285919..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/DseGraphEdgeSide.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import com.datastax.dse.driver.internal.querybuilder.schema.DefaultDseGraphEdgeSide; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.List; - -public interface DseGraphEdgeSide { - - /** Starts the definition of a graph edge side by designating the from/to table. */ - @NonNull - static DseGraphEdgeSide table(@NonNull CqlIdentifier tableId) { - return new DefaultDseGraphEdgeSide(tableId); - } - - /** Shortcut for {@link #table(CqlIdentifier) table(CqlIdentifier.fromCql(tableName))}. */ - @NonNull - static DseGraphEdgeSide table(@NonNull String tableName) { - return table(CqlIdentifier.fromCql(tableName)); - } - - /** - * Adds a partition key column to the primary key definition of this edge side. - * - *

Call this method multiple times if the partition key is composite. - */ - @NonNull - DseGraphEdgeSide withPartitionKey(@NonNull CqlIdentifier columnId); - - /** - * Shortcut for {@link #withPartitionKey(CqlIdentifier) - * withPartitionKey(CqlIdentifier.fromCql(columnName))}. - */ - @NonNull - default DseGraphEdgeSide withPartitionKey(@NonNull String columnName) { - return withPartitionKey(CqlIdentifier.fromCql(columnName)); - } - - /** - * Adds a clustering column to the primary key definition of this edge side. - * - *

Call this method multiple times to add more than one clustering column. - */ - @NonNull - DseGraphEdgeSide withClusteringColumn(@NonNull CqlIdentifier columnId); - - /** - * Shortcut for {@link #withClusteringColumn(CqlIdentifier) - * withClusteringColumn(CqlIdentifier.fromCql(columnName))}. - */ - @NonNull - default DseGraphEdgeSide withClusteringColumn(@NonNull String columnName) { - return withClusteringColumn(CqlIdentifier.fromCql(columnName)); - } - - @NonNull - CqlIdentifier getTableId(); - - @NonNull - List getPartitionKeyColumns(); - - @NonNull - List getClusteringColumns(); -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/DseRelationOptions.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/DseRelationOptions.java deleted file mode 100644 index 170390c43d5..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/DseRelationOptions.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import com.datastax.oss.driver.api.querybuilder.schema.RelationOptions; - -public interface DseRelationOptions> - extends RelationOptions {} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/DseRelationStructure.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/DseRelationStructure.java deleted file mode 100644 index f26039e45b4..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/DseRelationStructure.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.metadata.schema.ClusteringOrder; -import com.datastax.oss.driver.internal.core.CqlIdentifiers; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Map; - -public interface DseRelationStructure> - extends DseRelationOptions { - - /** - * Adds the provided CLUSTERING ORDER. - * - *

They will be appended in the iteration order of the provided map. If an ordering was already - * defined for a given identifier, it will be removed and the new ordering will appear in its - * position in the provided map. - */ - @NonNull - SelfT withClusteringOrderByIds(@NonNull Map orderings); - - /** - * Shortcut for {@link #withClusteringOrderByIds(Map)} with the columns specified as - * case-insensitive names. They will be wrapped with {@link CqlIdentifier#fromCql(String)}. - * - *

Note that it's possible for two different case-sensitive names to resolve to the same - * identifier, for example "foo" and "Foo"; if this happens, a runtime exception will be thrown. - */ - @NonNull - default SelfT withClusteringOrder(@NonNull Map orderings) { - return withClusteringOrderByIds(CqlIdentifiers.wrapKeys(orderings)); - } - - /** - * Adds the provided clustering order. - * - *

If clustering order was already defined for this identifier, it will be removed and the new - * clause will be appended at the end of the current clustering order. - */ - @NonNull - SelfT withClusteringOrder(@NonNull CqlIdentifier columnName, @NonNull ClusteringOrder order); - - /** - * Shortcut for {@link #withClusteringOrder(CqlIdentifier, ClusteringOrder) - * withClusteringOrder(CqlIdentifier.fromCql(columnName), order)}. - */ - @NonNull - default SelfT withClusteringOrder(@NonNull String columnName, @NonNull ClusteringOrder order) { - return withClusteringOrder(CqlIdentifier.fromCql(columnName), order); - } -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/DseTableGraphOptions.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/DseTableGraphOptions.java deleted file mode 100644 index df1008ff053..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/DseTableGraphOptions.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import com.datastax.oss.driver.api.core.CqlIdentifier; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; - -public interface DseTableGraphOptions { - - /** Adds a vertex label to this table. */ - @NonNull - NextT withVertexLabel(@Nullable CqlIdentifier vertexLabelId); - - /** - * Shortcut for {@link #withVertexLabel(CqlIdentifier) - * withVertexLabel(CqlIdentifier.fromCql(vertexLabel))}. - */ - @NonNull - default NextT withVertexLabel(@NonNull String vertexLabelName) { - return withVertexLabel(CqlIdentifier.fromCql(vertexLabelName)); - } - - /** - * Adds an anonymous vertex label to this table. - * - *

This is a shortcut for {@link #withVertexLabel(CqlIdentifier) withVertexLabel(null)}. - */ - @NonNull - default NextT withVertexLabel() { - return withVertexLabel((CqlIdentifier) null); - } - - /** - * Adds an edge label to this table. - * - *

Use {@link DseGraphEdgeSide#table(CqlIdentifier)} to build the definitions of both sides, - * for example: - * - *

{@code
-   * withEdgeLabel("contrib",
-   *               table("person")
-   *                 .withPartitionKey("contributor"),
-   *               table("soft")
-   *                 .withPartitionKey("company_name"),
-   *                 .withPartitionKey("software_name"),
-   *                 .withClusteringColumn("software_version"))
-   * }
- */ - @NonNull - NextT withEdgeLabel( - @Nullable CqlIdentifier edgeLabelId, - @NonNull DseGraphEdgeSide from, - @NonNull DseGraphEdgeSide to); - - /** - * Shortcut for {@link #withEdgeLabel(CqlIdentifier, DseGraphEdgeSide, DseGraphEdgeSide) - * withEdgeLabel(CqlIdentifier.fromCql(edgeLabelName), from, to)}. - */ - @NonNull - default NextT withEdgeLabel( - @NonNull String edgeLabelName, @NonNull DseGraphEdgeSide from, @NonNull DseGraphEdgeSide to) { - return withEdgeLabel(CqlIdentifier.fromCql(edgeLabelName), from, to); - } - - /** - * Adds an anonymous edge label to this table. - * - *

This is a shortcut for {@link #withEdgeLabel(CqlIdentifier, DseGraphEdgeSide, - * DseGraphEdgeSide) withEdgeLabel(null, from, to)}. - */ - @NonNull - default NextT withEdgeLabel(@NonNull DseGraphEdgeSide from, @NonNull DseGraphEdgeSide to) { - return withEdgeLabel((CqlIdentifier) null, from, to); - } -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/OngoingDsePartitionKey.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/OngoingDsePartitionKey.java deleted file mode 100644 index d535939994b..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/OngoingDsePartitionKey.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.type.DataType; -import com.datastax.oss.driver.api.core.type.DataTypes; -import com.datastax.oss.driver.api.querybuilder.SchemaBuilder; -import com.datastax.oss.driver.api.querybuilder.schema.CreateTable; -import edu.umd.cs.findbugs.annotations.NonNull; - -public interface OngoingDsePartitionKey { - - /** - * Adds a partition key column definition. - * - *

This includes the column declaration (you don't need an additional {@link - * CreateTable#withColumn(CqlIdentifier, DataType) addColumn} call). - * - *

Partition keys are added in the order of their declaration. - * - *

To create the data type, use the constants and static methods in {@link DataTypes}, or - * {@link SchemaBuilder#udt(CqlIdentifier, boolean)}. - */ - @NonNull - CreateDseTable withPartitionKey(@NonNull CqlIdentifier columnName, @NonNull DataType dataType); - - /** - * Shortcut for {@link #withPartitionKey(CqlIdentifier, DataType) - * withPartitionKey(CqlIdentifier.asCql(columnName), dataType)}. - */ - @NonNull - default CreateDseTable withPartitionKey(@NonNull String columnName, @NonNull DataType dataType) { - return withPartitionKey(CqlIdentifier.fromCql(columnName), dataType); - } -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/package-info.java b/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/package-info.java deleted file mode 100644 index 5e647ee3a4d..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/api/querybuilder/schema/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This package effectively mirrors the Cassandra OSS Schema interfaces to allow extended schema and - * query building for the DSE driver. NOTE: Changes made to the OSS driver will need to be mirrored - * here if the OSS driver changes affect an extended schema build strategy for the DSE driver. - */ -package com.datastax.dse.driver.api.querybuilder.schema; diff --git a/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DefaultAlterDseKeyspace.java b/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DefaultAlterDseKeyspace.java deleted file mode 100644 index 6fa2a64eaf3..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DefaultAlterDseKeyspace.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.querybuilder.schema; - -import com.datastax.dse.driver.api.querybuilder.schema.AlterDseKeyspace; -import com.datastax.dse.driver.api.querybuilder.schema.AlterDseKeyspaceStart; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.internal.querybuilder.ImmutableCollections; -import com.datastax.oss.driver.internal.querybuilder.schema.OptionsUtils; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Map; -import net.jcip.annotations.Immutable; - -@Immutable -public class DefaultAlterDseKeyspace implements AlterDseKeyspaceStart, AlterDseKeyspace { - - private final CqlIdentifier keyspaceName; - private final ImmutableMap options; - - public DefaultAlterDseKeyspace(@NonNull CqlIdentifier keyspaceName) { - this(keyspaceName, ImmutableMap.of()); - } - - public DefaultAlterDseKeyspace( - @NonNull CqlIdentifier keyspaceName, @NonNull ImmutableMap options) { - this.keyspaceName = keyspaceName; - this.options = options; - } - - @NonNull - @Override - public AlterDseKeyspace withDurableWrites(boolean durableWrites) { - return withOption("durable_writes", durableWrites); - } - - @NonNull - @Override - public AlterDseKeyspace withGraphEngine(String graphEngine) { - return this.withOption("graph_engine", graphEngine); - } - - @NonNull - @Override - public AlterDseKeyspace withReplicationOptions(@NonNull Map replicationOptions) { - return withOption("replication", replicationOptions); - } - - @NonNull - @Override - public AlterDseKeyspace withSimpleStrategy(int replicationFactor) { - ImmutableMap replication = - ImmutableMap.builder() - .put("class", "SimpleStrategy") - .put("replication_factor", replicationFactor) - .build(); - - return withReplicationOptions(replication); - } - - @NonNull - @Override - public AlterDseKeyspace withNetworkTopologyStrategy(@NonNull Map replications) { - ImmutableMap.Builder replicationBuilder = - ImmutableMap.builder().put("class", "NetworkTopologyStrategy"); - - for (Map.Entry replication : replications.entrySet()) { - replicationBuilder.put(replication.getKey(), replication.getValue()); - } - - return withReplicationOptions(replicationBuilder.build()); - } - - @NonNull - @Override - public AlterDseKeyspace withOption(@NonNull String name, @NonNull Object value) { - return new DefaultAlterDseKeyspace( - keyspaceName, ImmutableCollections.append(options, name, value)); - } - - @NonNull - @Override - public String asCql() { - return "ALTER KEYSPACE " + keyspaceName.asCql(true) + OptionsUtils.buildOptions(options, true); - } - - @NonNull - @Override - public Map getOptions() { - return options; - } - - @NonNull - public CqlIdentifier getKeyspace() { - return keyspaceName; - } - - @Override - public String toString() { - return asCql(); - } -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DefaultAlterDseTable.java b/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DefaultAlterDseTable.java deleted file mode 100644 index 5f2ad10b7d1..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DefaultAlterDseTable.java +++ /dev/null @@ -1,485 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.querybuilder.schema; - -import static com.datastax.oss.driver.internal.querybuilder.schema.Utils.appendSet; - -import com.datastax.dse.driver.api.querybuilder.schema.AlterDseTableAddColumnEnd; -import com.datastax.dse.driver.api.querybuilder.schema.AlterDseTableDropColumnEnd; -import com.datastax.dse.driver.api.querybuilder.schema.AlterDseTableRenameColumnEnd; -import com.datastax.dse.driver.api.querybuilder.schema.AlterDseTableStart; -import com.datastax.dse.driver.api.querybuilder.schema.AlterDseTableWithOptionsEnd; -import com.datastax.dse.driver.api.querybuilder.schema.DseGraphEdgeSide; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.type.DataType; -import com.datastax.oss.driver.api.querybuilder.BuildableQuery; -import com.datastax.oss.driver.internal.querybuilder.CqlHelper; -import com.datastax.oss.driver.internal.querybuilder.ImmutableCollections; -import com.datastax.oss.driver.internal.querybuilder.schema.OptionsUtils; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableSet; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.util.Map; -import net.jcip.annotations.Immutable; - -@Immutable -public class DefaultAlterDseTable - implements AlterDseTableStart, - AlterDseTableAddColumnEnd, - AlterDseTableDropColumnEnd, - AlterDseTableRenameColumnEnd, - AlterDseTableWithOptionsEnd, - BuildableQuery { - - private final CqlIdentifier keyspace; - private final CqlIdentifier tableName; - - private final ImmutableMap columnsToAddInOrder; - private final ImmutableSet columnsToAdd; - private final ImmutableSet columnsToAddStatic; - private final ImmutableSet columnsToDrop; - private final ImmutableMap columnsToRename; - private final CqlIdentifier columnToAlter; - private final DataType columnToAlterType; - private final DseTableVertexOperation vertexOperation; - private final DseTableEdgeOperation edgeOperation; - private final ImmutableMap options; - private final boolean dropCompactStorage; - - public DefaultAlterDseTable(@NonNull CqlIdentifier tableName) { - this(null, tableName); - } - - public DefaultAlterDseTable(@Nullable CqlIdentifier keyspace, @NonNull CqlIdentifier tableName) { - this( - keyspace, - tableName, - false, - ImmutableMap.of(), - ImmutableSet.of(), - ImmutableSet.of(), - ImmutableSet.of(), - ImmutableMap.of(), - null, - null, - null, - null, - ImmutableMap.of()); - } - - public DefaultAlterDseTable( - @Nullable CqlIdentifier keyspace, - @NonNull CqlIdentifier tableName, - boolean dropCompactStorage, - @NonNull ImmutableMap columnsToAddInOrder, - @NonNull ImmutableSet columnsToAdd, - @NonNull ImmutableSet columnsToAddStatic, - @NonNull ImmutableSet columnsToDrop, - @NonNull ImmutableMap columnsToRename, - @Nullable CqlIdentifier columnToAlter, - @Nullable DataType columnToAlterType, - @Nullable DseTableVertexOperation vertexOperation, - @Nullable DseTableEdgeOperation edgeOperation, - @NonNull ImmutableMap options) { - this.keyspace = keyspace; - this.tableName = tableName; - this.dropCompactStorage = dropCompactStorage; - this.columnsToAddInOrder = columnsToAddInOrder; - this.columnsToAdd = columnsToAdd; - this.columnsToAddStatic = columnsToAddStatic; - this.columnsToDrop = columnsToDrop; - this.columnsToRename = columnsToRename; - this.columnToAlter = columnToAlter; - this.columnToAlterType = columnToAlterType; - this.vertexOperation = vertexOperation; - this.edgeOperation = edgeOperation; - this.options = options; - } - - @NonNull - @Override - public AlterDseTableAddColumnEnd addColumn( - @NonNull CqlIdentifier columnName, @NonNull DataType dataType) { - return new DefaultAlterDseTable( - keyspace, - tableName, - dropCompactStorage, - ImmutableCollections.append(columnsToAddInOrder, columnName, dataType), - appendSet(columnsToAdd, columnName), - columnsToAddStatic, - columnsToDrop, - columnsToRename, - columnToAlter, - columnToAlterType, - vertexOperation, - edgeOperation, - options); - } - - @NonNull - @Override - public AlterDseTableAddColumnEnd addStaticColumn( - @NonNull CqlIdentifier columnName, @NonNull DataType dataType) { - return new DefaultAlterDseTable( - keyspace, - tableName, - dropCompactStorage, - ImmutableCollections.append(columnsToAddInOrder, columnName, dataType), - columnsToAdd, - appendSet(columnsToAddStatic, columnName), - columnsToDrop, - columnsToRename, - columnToAlter, - columnToAlterType, - vertexOperation, - edgeOperation, - options); - } - - @NonNull - @Override - public BuildableQuery dropCompactStorage() { - return new DefaultAlterDseTable( - keyspace, - tableName, - true, - columnsToAddInOrder, - columnsToAdd, - columnsToAddStatic, - columnsToDrop, - columnsToRename, - columnToAlter, - columnToAlterType, - vertexOperation, - edgeOperation, - options); - } - - @NonNull - @Override - public AlterDseTableDropColumnEnd dropColumns(@NonNull CqlIdentifier... columnNames) { - ImmutableSet.Builder builder = - ImmutableSet.builder().addAll(columnsToDrop); - for (CqlIdentifier columnName : columnNames) { - builder = builder.add(columnName); - } - - return new DefaultAlterDseTable( - keyspace, - tableName, - dropCompactStorage, - columnsToAddInOrder, - columnsToAdd, - columnsToAddStatic, - builder.build(), - columnsToRename, - columnToAlter, - columnToAlterType, - vertexOperation, - edgeOperation, - options); - } - - @NonNull - @Override - public AlterDseTableRenameColumnEnd renameColumn( - @NonNull CqlIdentifier from, @NonNull CqlIdentifier to) { - return new DefaultAlterDseTable( - keyspace, - tableName, - dropCompactStorage, - columnsToAddInOrder, - columnsToAdd, - columnsToAddStatic, - columnsToDrop, - ImmutableCollections.append(columnsToRename, from, to), - columnToAlter, - columnToAlterType, - vertexOperation, - edgeOperation, - options); - } - - @NonNull - @Override - public BuildableQuery alterColumn(@NonNull CqlIdentifier columnName, @NonNull DataType dataType) { - return new DefaultAlterDseTable( - keyspace, - tableName, - dropCompactStorage, - columnsToAddInOrder, - columnsToAdd, - columnsToAddStatic, - columnsToDrop, - columnsToRename, - columnName, - dataType, - vertexOperation, - edgeOperation, - options); - } - - @NonNull - @Override - public BuildableQuery withVertexLabel(@Nullable CqlIdentifier vertexLabelId) { - return new DefaultAlterDseTable( - keyspace, - tableName, - dropCompactStorage, - columnsToAddInOrder, - columnsToAdd, - columnsToAddStatic, - columnsToDrop, - columnsToRename, - columnToAlter, - columnToAlterType, - new DseTableVertexOperation(DseTableGraphOperationType.WITH, vertexLabelId), - edgeOperation, - options); - } - - @NonNull - @Override - public BuildableQuery withoutVertexLabel(@Nullable CqlIdentifier vertexLabelId) { - return new DefaultAlterDseTable( - keyspace, - tableName, - dropCompactStorage, - columnsToAddInOrder, - columnsToAdd, - columnsToAddStatic, - columnsToDrop, - columnsToRename, - columnToAlter, - columnToAlterType, - new DseTableVertexOperation(DseTableGraphOperationType.WITHOUT, vertexLabelId), - edgeOperation, - options); - } - - @NonNull - @Override - public BuildableQuery withEdgeLabel( - @Nullable CqlIdentifier edgeLabelId, - @NonNull DseGraphEdgeSide from, - @NonNull DseGraphEdgeSide to) { - return new DefaultAlterDseTable( - keyspace, - tableName, - dropCompactStorage, - columnsToAddInOrder, - columnsToAdd, - columnsToAddStatic, - columnsToDrop, - columnsToRename, - columnToAlter, - columnToAlterType, - vertexOperation, - new DseTableEdgeOperation(DseTableGraphOperationType.WITH, edgeLabelId, from, to), - options); - } - - @NonNull - @Override - public BuildableQuery withoutEdgeLabel(@Nullable CqlIdentifier edgeLabelId) { - return new DefaultAlterDseTable( - keyspace, - tableName, - dropCompactStorage, - columnsToAddInOrder, - columnsToAdd, - columnsToAddStatic, - columnsToDrop, - columnsToRename, - columnToAlter, - columnToAlterType, - vertexOperation, - new DseTableEdgeOperation(DseTableGraphOperationType.WITHOUT, edgeLabelId, null, null), - options); - } - - @NonNull - @Override - public AlterDseTableWithOptionsEnd withOption(@NonNull String name, @NonNull Object value) { - return new DefaultAlterDseTable( - keyspace, - tableName, - dropCompactStorage, - columnsToAddInOrder, - columnsToAdd, - columnsToAddStatic, - columnsToDrop, - columnsToRename, - columnToAlter, - columnToAlterType, - vertexOperation, - edgeOperation, - ImmutableCollections.append(options, name, value)); - } - - @NonNull - @Override - public String asCql() { - StringBuilder builder = new StringBuilder("ALTER TABLE "); - - CqlHelper.qualify(keyspace, tableName, builder); - - if (columnToAlter != null) { - return builder - .append(" ALTER ") - .append(columnToAlter.asCql(true)) - .append(" TYPE ") - .append(columnToAlterType.asCql(true, true)) - .toString(); - } else if (!columnsToAdd.isEmpty()) { - builder.append(" ADD "); - if (columnsToAdd.size() > 1) { - builder.append('('); - } - boolean first = true; - for (Map.Entry column : columnsToAddInOrder.entrySet()) { - if (first) { - first = false; - } else { - builder.append(','); - } - builder - .append(column.getKey().asCql(true)) - .append(' ') - .append(column.getValue().asCql(true, true)); - - if (columnsToAddStatic.contains(column.getKey())) { - builder.append(" STATIC"); - } - } - if (columnsToAdd.size() > 1) { - builder.append(')'); - } - return builder.toString(); - } else if (!columnsToDrop.isEmpty()) { - boolean moreThanOneDrop = columnsToDrop.size() > 1; - CqlHelper.appendIds( - columnsToDrop, - builder, - moreThanOneDrop ? " DROP (" : " DROP ", - ",", - moreThanOneDrop ? ")" : ""); - return builder.toString(); - } else if (!columnsToRename.isEmpty()) { - builder.append(" RENAME "); - boolean first = true; - for (Map.Entry entry : columnsToRename.entrySet()) { - if (first) { - first = false; - } else { - builder.append(" AND "); - } - builder - .append(entry.getKey().asCql(true)) - .append(" TO ") - .append(entry.getValue().asCql(true)); - } - return builder.toString(); - } else if (vertexOperation != null) { - builder.append(' ').append(vertexOperation.getType()).append(' '); - vertexOperation.append(builder); - } else if (edgeOperation != null) { - builder.append(' ').append(edgeOperation.getType()).append(' '); - edgeOperation.append(builder); - } else if (dropCompactStorage) { - return builder.append(" DROP COMPACT STORAGE").toString(); - } else if (!options.isEmpty()) { - return builder.append(OptionsUtils.buildOptions(options, true)).toString(); - } - - // While this is incomplete, we should return partially build query at this point for toString - // purposes. - return builder.toString(); - } - - @Override - public String toString() { - return asCql(); - } - - @NonNull - @Override - public Map getOptions() { - return options; - } - - @Nullable - public CqlIdentifier getKeyspace() { - return keyspace; - } - - @NonNull - public CqlIdentifier getTable() { - return tableName; - } - - @NonNull - public ImmutableMap getColumnsToAddInOrder() { - return columnsToAddInOrder; - } - - @NonNull - public ImmutableSet getColumnsToAddRegular() { - return columnsToAdd; - } - - @NonNull - public ImmutableSet getColumnsToAddStatic() { - return columnsToAddStatic; - } - - @NonNull - public ImmutableSet getColumnsToDrop() { - return columnsToDrop; - } - - @NonNull - public ImmutableMap getColumnsToRename() { - return columnsToRename; - } - - @Nullable - public CqlIdentifier getColumnToAlter() { - return columnToAlter; - } - - @Nullable - public DataType getColumnToAlterType() { - return columnToAlterType; - } - - @Nullable - public DseTableVertexOperation getVertexOperation() { - return vertexOperation; - } - - @Nullable - public DseTableEdgeOperation getEdgeOperation() { - return edgeOperation; - } - - public boolean isDropCompactStorage() { - return dropCompactStorage; - } -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DefaultCreateDseAggregate.java b/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DefaultCreateDseAggregate.java deleted file mode 100644 index 38c13f6e7d5..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DefaultCreateDseAggregate.java +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.querybuilder.schema; - -import com.datastax.dse.driver.api.querybuilder.schema.CreateDseAggregateEnd; -import com.datastax.dse.driver.api.querybuilder.schema.CreateDseAggregateStart; -import com.datastax.dse.driver.api.querybuilder.schema.CreateDseAggregateStateFunc; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.type.DataType; -import com.datastax.oss.driver.api.querybuilder.term.Term; -import com.datastax.oss.driver.internal.querybuilder.CqlHelper; -import com.datastax.oss.driver.internal.querybuilder.ImmutableCollections; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import net.jcip.annotations.Immutable; - -/** - * Implements DSE extended interfaces for creating aggregates. This class provides the same - * functionality as the Cassandra OSS {@link - * com.datastax.oss.driver.internal.querybuilder.schema.DefaultCreateAggregate} implementation, with - * the additional DSE specific extended functionality (DETERMINISTIC keyword). - */ -@Immutable -public class DefaultCreateDseAggregate - implements CreateDseAggregateEnd, CreateDseAggregateStart, CreateDseAggregateStateFunc { - - private final CqlIdentifier keyspace; - private final CqlIdentifier functionName; - private boolean orReplace; - private boolean ifNotExists; - private final ImmutableList parameters; - private final CqlIdentifier sFunc; - private final DataType sType; - private final CqlIdentifier finalFunc; - private final Term term; - private final boolean deterministic; - - public DefaultCreateDseAggregate(@NonNull CqlIdentifier functionName) { - this(null, functionName); - } - - public DefaultCreateDseAggregate( - @Nullable CqlIdentifier keyspace, @NonNull CqlIdentifier functionName) { - this(keyspace, functionName, false, false, ImmutableList.of(), null, null, null, null, false); - } - - public DefaultCreateDseAggregate( - @Nullable CqlIdentifier keyspace, - @NonNull CqlIdentifier functionName, - boolean orReplace, - boolean ifNotExists, - @NonNull ImmutableList parameters, - @Nullable CqlIdentifier sFunc, - @Nullable DataType sType, - @Nullable CqlIdentifier finalFunc, - @Nullable Term term, - boolean deterministic) { - this.keyspace = keyspace; - this.functionName = functionName; - this.orReplace = orReplace; - this.ifNotExists = ifNotExists; - this.parameters = parameters; - this.sFunc = sFunc; - this.sType = sType; - this.finalFunc = finalFunc; - this.term = term; - this.deterministic = deterministic; - } - - @NonNull - @Override - public String asCql() { - StringBuilder builder = new StringBuilder(); - - builder.append("CREATE "); - if (orReplace) { - builder.append("OR REPLACE "); - } - builder.append("AGGREGATE "); - - if (ifNotExists) { - builder.append("IF NOT EXISTS "); - } - CqlHelper.qualify(keyspace, functionName, builder); - - builder.append(" ("); - boolean first = true; - for (DataType param : parameters) { - if (first) { - first = false; - } else { - builder.append(','); - } - builder.append(param.asCql(false, true)); - } - builder.append(')'); - if (sFunc != null) { - builder.append(" SFUNC "); - builder.append(sFunc.asCql(true)); - } - if (sType != null) { - builder.append(" STYPE "); - builder.append(sType.asCql(false, true)); - } - if (finalFunc != null) { - builder.append(" FINALFUNC "); - builder.append(finalFunc.asCql(true)); - } - if (term != null) { - builder.append(" INITCOND "); - term.appendTo(builder); - } - // deterministic - if (deterministic) { - builder.append(" DETERMINISTIC"); - } - return builder.toString(); - } - - @NonNull - @Override - public CreateDseAggregateEnd withInitCond(@NonNull Term term) { - return new DefaultCreateDseAggregate( - keyspace, - functionName, - orReplace, - ifNotExists, - parameters, - sFunc, - sType, - finalFunc, - term, - deterministic); - } - - @NonNull - @Override - public CreateDseAggregateStart ifNotExists() { - return new DefaultCreateDseAggregate( - keyspace, - functionName, - orReplace, - true, - parameters, - sFunc, - sType, - finalFunc, - term, - deterministic); - } - - @NonNull - @Override - public CreateDseAggregateStart orReplace() { - return new DefaultCreateDseAggregate( - keyspace, - functionName, - true, - ifNotExists, - parameters, - sFunc, - sType, - finalFunc, - term, - deterministic); - } - - @NonNull - @Override - public CreateDseAggregateStart withParameter(@NonNull DataType paramType) { - return new DefaultCreateDseAggregate( - keyspace, - functionName, - orReplace, - ifNotExists, - ImmutableCollections.append(parameters, paramType), - sFunc, - sType, - finalFunc, - term, - deterministic); - } - - @NonNull - @Override - public CreateDseAggregateStateFunc withSFunc(@NonNull CqlIdentifier sFunc) { - return new DefaultCreateDseAggregate( - keyspace, - functionName, - orReplace, - ifNotExists, - parameters, - sFunc, - sType, - finalFunc, - term, - deterministic); - } - - @NonNull - @Override - public CreateDseAggregateEnd withSType(@NonNull DataType sType) { - return new DefaultCreateDseAggregate( - keyspace, - functionName, - orReplace, - ifNotExists, - parameters, - sFunc, - sType, - finalFunc, - term, - deterministic); - } - - @NonNull - @Override - public CreateDseAggregateEnd withFinalFunc(@NonNull CqlIdentifier finalFunc) { - return new DefaultCreateDseAggregate( - keyspace, - functionName, - orReplace, - ifNotExists, - parameters, - sFunc, - sType, - finalFunc, - term, - deterministic); - } - - @NonNull - @Override - public CreateDseAggregateEnd deterministic() { - return new DefaultCreateDseAggregate( - keyspace, - functionName, - orReplace, - ifNotExists, - parameters, - sFunc, - sType, - finalFunc, - term, - true); - } - - @Override - public String toString() { - return asCql(); - } - - @Nullable - public CqlIdentifier getKeyspace() { - return keyspace; - } - - @NonNull - public CqlIdentifier getFunctionName() { - return functionName; - } - - public boolean isOrReplace() { - return orReplace; - } - - public boolean isIfNotExists() { - return ifNotExists; - } - - @NonNull - public ImmutableList getParameters() { - return parameters; - } - - @Nullable - public CqlIdentifier getsFunc() { - return sFunc; - } - - @Nullable - public DataType getsType() { - return sType; - } - - @Nullable - public CqlIdentifier getFinalFunc() { - return finalFunc; - } - - @Nullable - public Term getTerm() { - return term; - } - - public boolean isDeterministic() { - return deterministic; - } -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DefaultCreateDseFunction.java b/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DefaultCreateDseFunction.java deleted file mode 100644 index 679629bf893..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DefaultCreateDseFunction.java +++ /dev/null @@ -1,444 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.querybuilder.schema; - -import com.datastax.dse.driver.api.querybuilder.schema.CreateDseFunctionEnd; -import com.datastax.dse.driver.api.querybuilder.schema.CreateDseFunctionStart; -import com.datastax.dse.driver.api.querybuilder.schema.CreateDseFunctionWithLanguage; -import com.datastax.dse.driver.api.querybuilder.schema.CreateDseFunctionWithNullOption; -import com.datastax.dse.driver.api.querybuilder.schema.CreateDseFunctionWithType; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.type.DataType; -import com.datastax.oss.driver.internal.querybuilder.CqlHelper; -import com.datastax.oss.driver.internal.querybuilder.ImmutableCollections; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.util.Map; -import net.jcip.annotations.Immutable; - -/** - * Implements DSE extended interfaces for creating functions. This class provides the same - * functionality as the Cassandra OSS {@link - * com.datastax.oss.driver.internal.querybuilder.schema.DefaultCreateFunction} implementation, with - * the additional DSE specific extended functionality (DETERMINISTIC and MONOTONIC keywords). - */ -@Immutable -public class DefaultCreateDseFunction - implements CreateDseFunctionEnd, - CreateDseFunctionStart, - CreateDseFunctionWithLanguage, - CreateDseFunctionWithNullOption, - CreateDseFunctionWithType { - - private final CqlIdentifier keyspace; - private final CqlIdentifier functionName; - private boolean orReplace; - private boolean ifNotExists; - private final ImmutableMap parameters; - private boolean returnsNullOnNull; - private final DataType returnType; - private final String language; - private final String functionBody; - private final boolean deterministic; - private final boolean globallyMonotonic; - private final CqlIdentifier monotonicOn; - - public DefaultCreateDseFunction(CqlIdentifier functionName) { - this(null, functionName); - } - - public DefaultCreateDseFunction(CqlIdentifier keyspace, CqlIdentifier functionName) { - this( - keyspace, - functionName, - false, - false, - ImmutableMap.of(), - false, - null, - null, - null, - false, - false, - null); - } - - public DefaultCreateDseFunction( - CqlIdentifier keyspace, - CqlIdentifier functionName, - boolean orReplace, - boolean ifNotExists, - ImmutableMap parameters, - boolean returnsNullOnNull, - DataType returns, - String language, - String functionBody, - boolean deterministic, - boolean globallyMonotonic, - CqlIdentifier monotonicOn) { - this.keyspace = keyspace; - this.functionName = functionName; - this.orReplace = orReplace; - this.ifNotExists = ifNotExists; - this.parameters = parameters; - this.returnsNullOnNull = returnsNullOnNull; - this.returnType = returns; - this.language = language; - this.functionBody = functionBody; - this.deterministic = deterministic; - this.globallyMonotonic = globallyMonotonic; - this.monotonicOn = monotonicOn; - } - - @NonNull - @Override - public String asCql() { - StringBuilder builder = new StringBuilder(); - - builder.append("CREATE "); - if (orReplace) { - builder.append("OR REPLACE "); - } - builder.append("FUNCTION "); - - if (ifNotExists) { - builder.append("IF NOT EXISTS "); - } - CqlHelper.qualify(keyspace, functionName, builder); - - builder.append(" ("); - - boolean first = true; - for (Map.Entry param : parameters.entrySet()) { - if (first) { - first = false; - } else { - builder.append(','); - } - builder - .append(param.getKey().asCql(true)) - .append(' ') - .append(param.getValue().asCql(false, true)); - } - builder.append(')'); - if (returnsNullOnNull) { - builder.append(" RETURNS NULL"); - } else { - builder.append(" CALLED"); - } - - builder.append(" ON NULL INPUT"); - - if (returnType == null) { - // return type has not been provided yet. - return builder.toString(); - } - - builder.append(" RETURNS "); - builder.append(returnType.asCql(false, true)); - - // deterministic - if (deterministic) { - builder.append(" DETERMINISTIC"); - } - - // monotonic - if (globallyMonotonic) { - builder.append(" MONOTONIC"); - } else if (monotonicOn != null) { - builder.append(" MONOTONIC ON ").append(monotonicOn.asCql(true)); - } - - if (language == null) { - // language has not been provided yet. - return builder.toString(); - } - - builder.append(" LANGUAGE "); - builder.append(language); - - if (functionBody == null) { - // body has not been provided yet. - return builder.toString(); - } - - builder.append(" AS "); - builder.append(functionBody); - return builder.toString(); - } - - @Override - public String toString() { - return asCql(); - } - - @NonNull - @Override - public CreateDseFunctionEnd as(@NonNull String functionBody) { - return new DefaultCreateDseFunction( - keyspace, - functionName, - orReplace, - ifNotExists, - parameters, - returnsNullOnNull, - returnType, - language, - functionBody, - deterministic, - globallyMonotonic, - monotonicOn); - } - - @NonNull - @Override - public CreateDseFunctionWithLanguage withLanguage(@NonNull String language) { - return new DefaultCreateDseFunction( - keyspace, - functionName, - orReplace, - ifNotExists, - parameters, - returnsNullOnNull, - returnType, - language, - functionBody, - deterministic, - globallyMonotonic, - monotonicOn); - } - - @NonNull - @Override - public CreateDseFunctionStart ifNotExists() { - return new DefaultCreateDseFunction( - keyspace, - functionName, - orReplace, - true, - parameters, - returnsNullOnNull, - returnType, - language, - functionBody, - deterministic, - globallyMonotonic, - monotonicOn); - } - - @NonNull - @Override - public CreateDseFunctionStart orReplace() { - return new DefaultCreateDseFunction( - keyspace, - functionName, - true, - ifNotExists, - parameters, - returnsNullOnNull, - returnType, - language, - functionBody, - deterministic, - globallyMonotonic, - monotonicOn); - } - - @NonNull - @Override - public CreateDseFunctionStart withParameter( - @NonNull CqlIdentifier paramName, @NonNull DataType paramType) { - return new DefaultCreateDseFunction( - keyspace, - functionName, - orReplace, - ifNotExists, - ImmutableCollections.append(parameters, paramName, paramType), - returnsNullOnNull, - returnType, - language, - functionBody, - deterministic, - globallyMonotonic, - monotonicOn); - } - - @NonNull - @Override - public CreateDseFunctionWithNullOption returnsNullOnNull() { - return new DefaultCreateDseFunction( - keyspace, - functionName, - orReplace, - ifNotExists, - parameters, - true, - returnType, - language, - functionBody, - deterministic, - globallyMonotonic, - monotonicOn); - } - - @NonNull - @Override - public CreateDseFunctionWithNullOption calledOnNull() { - return new DefaultCreateDseFunction( - keyspace, - functionName, - orReplace, - ifNotExists, - parameters, - false, - returnType, - language, - functionBody, - deterministic, - globallyMonotonic, - monotonicOn); - } - - @NonNull - @Override - public CreateDseFunctionWithType deterministic() { - return new DefaultCreateDseFunction( - keyspace, - functionName, - orReplace, - ifNotExists, - parameters, - returnsNullOnNull, - returnType, - language, - functionBody, - true, - globallyMonotonic, - monotonicOn); - } - - @NonNull - @Override - public CreateDseFunctionWithType monotonic() { - return new DefaultCreateDseFunction( - keyspace, - functionName, - orReplace, - ifNotExists, - parameters, - returnsNullOnNull, - returnType, - language, - functionBody, - deterministic, - true, - null); - } - - @NonNull - @Override - public CreateDseFunctionWithType monotonicOn(@NonNull CqlIdentifier monotonicColumn) { - return new DefaultCreateDseFunction( - keyspace, - functionName, - orReplace, - ifNotExists, - parameters, - returnsNullOnNull, - returnType, - language, - functionBody, - deterministic, - false, - monotonicColumn); - } - - @NonNull - @Override - public CreateDseFunctionWithType returnsType(@NonNull DataType returnType) { - return new DefaultCreateDseFunction( - keyspace, - functionName, - orReplace, - ifNotExists, - parameters, - returnsNullOnNull, - returnType, - language, - functionBody, - deterministic, - globallyMonotonic, - monotonicOn); - } - - @Nullable - public CqlIdentifier getKeyspace() { - return keyspace; - } - - @NonNull - public CqlIdentifier getFunction() { - return functionName; - } - - public boolean isOrReplace() { - return orReplace; - } - - public boolean isIfNotExists() { - return ifNotExists; - } - - @NonNull - public ImmutableMap getParameters() { - return parameters; - } - - public boolean isReturnsNullOnNull() { - return returnsNullOnNull; - } - - @Nullable - public DataType getReturnType() { - return returnType; - } - - @Nullable - public String getLanguage() { - return language; - } - - @Nullable - public String getFunctionBody() { - return functionBody; - } - - public boolean isDeterministic() { - return deterministic; - } - - public boolean isGloballyMonotonic() { - return globallyMonotonic; - } - - @Nullable - public CqlIdentifier getMonotonicOn() { - return monotonicOn; - } -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DefaultCreateDseKeyspace.java b/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DefaultCreateDseKeyspace.java deleted file mode 100644 index 3b542254dab..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DefaultCreateDseKeyspace.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.querybuilder.schema; - -import com.datastax.dse.driver.api.querybuilder.schema.CreateDseKeyspace; -import com.datastax.dse.driver.api.querybuilder.schema.CreateDseKeyspaceStart; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.internal.querybuilder.ImmutableCollections; -import com.datastax.oss.driver.internal.querybuilder.schema.OptionsUtils; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Map; -import net.jcip.annotations.Immutable; - -@Immutable -public class DefaultCreateDseKeyspace implements CreateDseKeyspace, CreateDseKeyspaceStart { - - private final CqlIdentifier keyspaceName; - private final boolean ifNotExists; - private final ImmutableMap options; - - public DefaultCreateDseKeyspace(@NonNull CqlIdentifier keyspaceName) { - this(keyspaceName, false, ImmutableMap.of()); - } - - public DefaultCreateDseKeyspace( - @NonNull CqlIdentifier keyspaceName, - boolean ifNotExists, - @NonNull ImmutableMap options) { - this.keyspaceName = keyspaceName; - this.ifNotExists = ifNotExists; - this.options = options; - } - - @NonNull - @Override - public CreateDseKeyspace withOption(@NonNull String name, @NonNull Object value) { - return new DefaultCreateDseKeyspace( - keyspaceName, ifNotExists, ImmutableCollections.append(options, name, value)); - } - - @NonNull - @Override - public CreateDseKeyspaceStart ifNotExists() { - return new DefaultCreateDseKeyspace(keyspaceName, true, options); - } - - @NonNull - @Override - public CreateDseKeyspace withReplicationOptions(@NonNull Map replicationOptions) { - return withOption("replication", replicationOptions); - } - - @NonNull - @Override - public String asCql() { - StringBuilder builder = new StringBuilder(); - - builder.append("CREATE KEYSPACE "); - if (ifNotExists) { - builder.append("IF NOT EXISTS "); - } - - builder.append(keyspaceName.asCql(true)); - builder.append(OptionsUtils.buildOptions(options, true)); - return builder.toString(); - } - - @Override - public String toString() { - return asCql(); - } - - @NonNull - @Override - public Map getOptions() { - return options; - } - - @NonNull - public CqlIdentifier getKeyspace() { - return keyspaceName; - } - - public boolean isIfNotExists() { - return ifNotExists; - } -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DefaultCreateDseTable.java b/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DefaultCreateDseTable.java deleted file mode 100644 index 86169cdd29b..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DefaultCreateDseTable.java +++ /dev/null @@ -1,479 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.querybuilder.schema; - -import static com.datastax.oss.driver.internal.querybuilder.schema.Utils.appendSet; - -import com.datastax.dse.driver.api.querybuilder.schema.CreateDseTable; -import com.datastax.dse.driver.api.querybuilder.schema.CreateDseTableStart; -import com.datastax.dse.driver.api.querybuilder.schema.CreateDseTableWithOptions; -import com.datastax.dse.driver.api.querybuilder.schema.DseGraphEdgeSide; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.metadata.schema.ClusteringOrder; -import com.datastax.oss.driver.api.core.type.DataType; -import com.datastax.oss.driver.internal.querybuilder.CqlHelper; -import com.datastax.oss.driver.internal.querybuilder.ImmutableCollections; -import com.datastax.oss.driver.internal.querybuilder.schema.OptionsUtils; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableSet; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.util.Map; -import net.jcip.annotations.Immutable; - -@Immutable -public class DefaultCreateDseTable - implements CreateDseTableStart, CreateDseTable, CreateDseTableWithOptions { - - private final CqlIdentifier keyspace; - private final CqlIdentifier tableName; - - private final boolean ifNotExists; - private final boolean compactStorage; - - private final ImmutableMap options; - - private final ImmutableMap columnsInOrder; - - private final ImmutableSet partitionKeyColumns; - private final ImmutableSet clusteringKeyColumns; - private final ImmutableSet staticColumns; - private final ImmutableSet regularColumns; - - private final ImmutableMap orderings; - - private final DseTableVertexOperation vertexOperation; - private final DseTableEdgeOperation edgeOperation; - - public DefaultCreateDseTable(@Nullable CqlIdentifier keyspace, @NonNull CqlIdentifier tableName) { - this( - keyspace, - tableName, - false, - false, - ImmutableMap.of(), - ImmutableSet.of(), - ImmutableSet.of(), - ImmutableSet.of(), - ImmutableSet.of(), - ImmutableMap.of(), - null, - null, - ImmutableMap.of()); - } - - public DefaultCreateDseTable( - @Nullable CqlIdentifier keyspace, - @NonNull CqlIdentifier tableName, - boolean ifNotExists, - boolean compactStorage, - @NonNull ImmutableMap columnsInOrder, - @NonNull ImmutableSet partitionKeyColumns, - @NonNull ImmutableSet clusteringKeyColumns, - @NonNull ImmutableSet staticColumns, - @NonNull ImmutableSet regularColumns, - @NonNull ImmutableMap orderings, - @Nullable DseTableVertexOperation vertexOperation, - @Nullable DseTableEdgeOperation edgeOperation, - @NonNull ImmutableMap options) { - this.keyspace = keyspace; - this.tableName = tableName; - this.ifNotExists = ifNotExists; - this.compactStorage = compactStorage; - this.columnsInOrder = columnsInOrder; - this.partitionKeyColumns = partitionKeyColumns; - this.clusteringKeyColumns = clusteringKeyColumns; - this.staticColumns = staticColumns; - this.regularColumns = regularColumns; - this.orderings = orderings; - this.options = options; - this.vertexOperation = vertexOperation; - this.edgeOperation = edgeOperation; - } - - @NonNull - @Override - public CreateDseTableStart ifNotExists() { - return new DefaultCreateDseTable( - keyspace, - tableName, - true, - compactStorage, - columnsInOrder, - partitionKeyColumns, - clusteringKeyColumns, - staticColumns, - regularColumns, - orderings, - vertexOperation, - edgeOperation, - options); - } - - @NonNull - @Override - public CreateDseTable withPartitionKey( - @NonNull CqlIdentifier columnName, @NonNull DataType dataType) { - return new DefaultCreateDseTable( - keyspace, - tableName, - ifNotExists, - compactStorage, - ImmutableCollections.append(columnsInOrder, columnName, dataType), - appendSet(partitionKeyColumns, columnName), - clusteringKeyColumns, - staticColumns, - regularColumns, - orderings, - vertexOperation, - edgeOperation, - options); - } - - @NonNull - @Override - public CreateDseTable withClusteringColumn( - @NonNull CqlIdentifier columnName, @NonNull DataType dataType) { - return new DefaultCreateDseTable( - keyspace, - tableName, - ifNotExists, - compactStorage, - ImmutableCollections.append(columnsInOrder, columnName, dataType), - partitionKeyColumns, - appendSet(clusteringKeyColumns, columnName), - staticColumns, - regularColumns, - orderings, - vertexOperation, - edgeOperation, - options); - } - - @NonNull - @Override - public CreateDseTable withColumn(@NonNull CqlIdentifier columnName, @NonNull DataType dataType) { - return new DefaultCreateDseTable( - keyspace, - tableName, - ifNotExists, - compactStorage, - ImmutableCollections.append(columnsInOrder, columnName, dataType), - partitionKeyColumns, - clusteringKeyColumns, - staticColumns, - appendSet(regularColumns, columnName), - orderings, - vertexOperation, - edgeOperation, - options); - } - - @NonNull - @Override - public CreateDseTable withStaticColumn( - @NonNull CqlIdentifier columnName, @NonNull DataType dataType) { - return new DefaultCreateDseTable( - keyspace, - tableName, - ifNotExists, - compactStorage, - ImmutableCollections.append(columnsInOrder, columnName, dataType), - partitionKeyColumns, - clusteringKeyColumns, - appendSet(staticColumns, columnName), - regularColumns, - orderings, - vertexOperation, - edgeOperation, - options); - } - - @NonNull - @Override - public CreateDseTableWithOptions withCompactStorage() { - return new DefaultCreateDseTable( - keyspace, - tableName, - ifNotExists, - true, - columnsInOrder, - partitionKeyColumns, - clusteringKeyColumns, - staticColumns, - regularColumns, - orderings, - vertexOperation, - edgeOperation, - options); - } - - @NonNull - @Override - public CreateDseTableWithOptions withClusteringOrderByIds( - @NonNull Map orderings) { - return withClusteringOrders(ImmutableCollections.concat(this.orderings, orderings)); - } - - @NonNull - @Override - public CreateDseTableWithOptions withClusteringOrder( - @NonNull CqlIdentifier columnName, @NonNull ClusteringOrder order) { - return withClusteringOrders(ImmutableCollections.append(orderings, columnName, order)); - } - - @NonNull - public CreateDseTableWithOptions withClusteringOrders( - @NonNull ImmutableMap orderings) { - return new DefaultCreateDseTable( - keyspace, - tableName, - ifNotExists, - compactStorage, - columnsInOrder, - partitionKeyColumns, - clusteringKeyColumns, - staticColumns, - regularColumns, - orderings, - vertexOperation, - edgeOperation, - options); - } - - @NonNull - @Override - public CreateDseTableWithOptions withVertexLabel(@Nullable CqlIdentifier vertexLabelId) { - return new DefaultCreateDseTable( - keyspace, - tableName, - ifNotExists, - compactStorage, - columnsInOrder, - partitionKeyColumns, - clusteringKeyColumns, - staticColumns, - regularColumns, - orderings, - new DseTableVertexOperation(DseTableGraphOperationType.WITH, vertexLabelId), - edgeOperation, - options); - } - - @NonNull - @Override - public CreateDseTableWithOptions withEdgeLabel( - @Nullable CqlIdentifier edgeLabelId, - @NonNull DseGraphEdgeSide from, - @NonNull DseGraphEdgeSide to) { - return new DefaultCreateDseTable( - keyspace, - tableName, - ifNotExists, - compactStorage, - columnsInOrder, - partitionKeyColumns, - clusteringKeyColumns, - staticColumns, - regularColumns, - orderings, - vertexOperation, - new DseTableEdgeOperation(DseTableGraphOperationType.WITH, edgeLabelId, from, to), - options); - } - - @NonNull - @Override - public CreateDseTable withOption(@NonNull String name, @NonNull Object value) { - return new DefaultCreateDseTable( - keyspace, - tableName, - ifNotExists, - compactStorage, - columnsInOrder, - partitionKeyColumns, - clusteringKeyColumns, - staticColumns, - regularColumns, - orderings, - vertexOperation, - edgeOperation, - ImmutableCollections.append(options, name, value)); - } - - @NonNull - @Override - public String asCql() { - StringBuilder builder = new StringBuilder(); - - builder.append("CREATE TABLE "); - if (ifNotExists) { - builder.append("IF NOT EXISTS "); - } - - CqlHelper.qualify(keyspace, tableName, builder); - - if (columnsInOrder.isEmpty()) { - // no columns provided yet. - return builder.toString(); - } - - boolean singlePrimaryKey = partitionKeyColumns.size() == 1 && clusteringKeyColumns.size() == 0; - - builder.append(" ("); - - boolean first = true; - for (Map.Entry column : columnsInOrder.entrySet()) { - if (first) { - first = false; - } else { - builder.append(','); - } - builder - .append(column.getKey().asCql(true)) - .append(' ') - .append(column.getValue().asCql(true, true)); - - if (singlePrimaryKey && partitionKeyColumns.contains(column.getKey())) { - builder.append(" PRIMARY KEY"); - } else if (staticColumns.contains(column.getKey())) { - builder.append(" STATIC"); - } - } - - if (!singlePrimaryKey) { - builder.append(","); - CqlHelper.buildPrimaryKey(partitionKeyColumns, clusteringKeyColumns, builder); - } - - builder.append(')'); - - boolean firstOption = true; - - if (compactStorage) { - firstOption = false; - builder.append(" WITH COMPACT STORAGE"); - } - - if (!orderings.isEmpty()) { - if (firstOption) { - builder.append(" WITH "); - firstOption = false; - } else { - builder.append(" AND "); - } - builder.append("CLUSTERING ORDER BY ("); - boolean firstClustering = true; - - for (Map.Entry ordering : orderings.entrySet()) { - if (firstClustering) { - firstClustering = false; - } else { - builder.append(','); - } - builder - .append(ordering.getKey().asCql(true)) - .append(' ') - .append(ordering.getValue().toString()); - } - - builder.append(')'); - } - - if (vertexOperation != null) { - if (firstOption) { - builder.append(" WITH "); - firstOption = false; - } else { - builder.append(" AND "); - } - vertexOperation.append(builder); - } else if (edgeOperation != null) { - if (firstOption) { - builder.append(" WITH "); - firstOption = false; - } else { - builder.append(" AND "); - } - edgeOperation.append(builder); - } - - builder.append(OptionsUtils.buildOptions(options, firstOption)); - - return builder.toString(); - } - - @Override - public String toString() { - return asCql(); - } - - @NonNull - @Override - public Map getOptions() { - return options; - } - - @Nullable - public CqlIdentifier getKeyspace() { - return keyspace; - } - - @NonNull - public CqlIdentifier getTable() { - return tableName; - } - - public boolean isIfNotExists() { - return ifNotExists; - } - - public boolean isCompactStorage() { - return compactStorage; - } - - @NonNull - public ImmutableMap getColumnsInOrder() { - return columnsInOrder; - } - - @NonNull - public ImmutableSet getPartitionKeyColumns() { - return partitionKeyColumns; - } - - @NonNull - public ImmutableSet getClusteringKeyColumns() { - return clusteringKeyColumns; - } - - @NonNull - public ImmutableSet getStaticColumns() { - return staticColumns; - } - - @NonNull - public ImmutableSet getRegularColumns() { - return regularColumns; - } - - @NonNull - public ImmutableMap getOrderings() { - return orderings; - } -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DefaultDseGraphEdgeSide.java b/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DefaultDseGraphEdgeSide.java deleted file mode 100644 index 32f43ab8ff2..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DefaultDseGraphEdgeSide.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.querybuilder.schema; - -import com.datastax.dse.driver.api.querybuilder.schema.DseGraphEdgeSide; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.internal.querybuilder.ImmutableCollections; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.List; - -public class DefaultDseGraphEdgeSide implements DseGraphEdgeSide { - - private final CqlIdentifier tableId; - private final ImmutableList partitionKeyColumns; - private final ImmutableList clusteringColumns; - - public DefaultDseGraphEdgeSide(CqlIdentifier tableId) { - this(tableId, ImmutableList.of(), ImmutableList.of()); - } - - private DefaultDseGraphEdgeSide( - CqlIdentifier tableId, - ImmutableList partitionKeyColumns, - ImmutableList clusteringColumns) { - this.tableId = tableId; - this.partitionKeyColumns = partitionKeyColumns; - this.clusteringColumns = clusteringColumns; - } - - @NonNull - @Override - public DseGraphEdgeSide withPartitionKey(@NonNull CqlIdentifier columnId) { - return new DefaultDseGraphEdgeSide( - tableId, ImmutableCollections.append(partitionKeyColumns, columnId), clusteringColumns); - } - - @NonNull - @Override - public DseGraphEdgeSide withClusteringColumn(@NonNull CqlIdentifier columnId) { - return new DefaultDseGraphEdgeSide( - tableId, partitionKeyColumns, ImmutableCollections.append(clusteringColumns, columnId)); - } - - @NonNull - @Override - public CqlIdentifier getTableId() { - return tableId; - } - - @NonNull - @Override - public List getPartitionKeyColumns() { - return partitionKeyColumns; - } - - @NonNull - @Override - public List getClusteringColumns() { - return clusteringColumns; - } -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DseTableEdgeOperation.java b/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DseTableEdgeOperation.java deleted file mode 100644 index f514158e853..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DseTableEdgeOperation.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.querybuilder.schema; - -import com.datastax.dse.driver.api.querybuilder.schema.DseGraphEdgeSide; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.internal.querybuilder.CqlHelper; -import java.util.List; - -public class DseTableEdgeOperation { - - private final DseTableGraphOperationType type; - private final CqlIdentifier label; - private final DseGraphEdgeSide from; - private final DseGraphEdgeSide to; - - public DseTableEdgeOperation( - DseTableGraphOperationType type, - CqlIdentifier label, - DseGraphEdgeSide from, - DseGraphEdgeSide to) { - this.type = type; - this.label = label; - this.from = from; - this.to = to; - } - - public DseTableGraphOperationType getType() { - return type; - } - - public CqlIdentifier getLabel() { - return label; - } - - public DseGraphEdgeSide getFrom() { - return from; - } - - public DseGraphEdgeSide getTo() { - return to; - } - - public void append(StringBuilder builder) { - builder.append("EDGE LABEL"); - if (label != null) { - builder.append(' ').append(label.asCql(true)); - } - if (type == DseTableGraphOperationType.WITH) { - builder.append(" FROM "); - append(from, builder); - builder.append(" TO "); - append(to, builder); - } - } - - private static void append(DseGraphEdgeSide side, StringBuilder builder) { - builder.append(side.getTableId().asCql(true)).append('('); - List pkColumns = side.getPartitionKeyColumns(); - if (pkColumns.size() == 1) { - builder.append(pkColumns.get(0).asCql(true)); - } else { - CqlHelper.appendIds(pkColumns, builder, "(", ",", ")"); - } - CqlHelper.appendIds(side.getClusteringColumns(), builder, ",", ",", null); - builder.append(')'); - } -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DseTableGraphOperationType.java b/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DseTableGraphOperationType.java deleted file mode 100644 index 35d5dd7c80b..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DseTableGraphOperationType.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.querybuilder.schema; - -public enum DseTableGraphOperationType { - WITH, - WITHOUT -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DseTableVertexOperation.java b/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DseTableVertexOperation.java deleted file mode 100644 index 64a2d44c29a..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/DseTableVertexOperation.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.querybuilder.schema; - -import com.datastax.oss.driver.api.core.CqlIdentifier; - -public class DseTableVertexOperation { - - private final DseTableGraphOperationType type; - private final CqlIdentifier label; - - public DseTableVertexOperation(DseTableGraphOperationType type, CqlIdentifier label) { - this.type = type; - this.label = label; - } - - public DseTableGraphOperationType getType() { - return type; - } - - public CqlIdentifier getLabel() { - return label; - } - - public void append(StringBuilder builder) { - builder.append("VERTEX LABEL"); - if (label != null) { - builder.append(' ').append(label.asCql(true)); - } - } -} diff --git a/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/package-info.java b/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/package-info.java deleted file mode 100644 index de137d9f952..00000000000 --- a/query-builder/src/main/java/com/datastax/dse/driver/internal/querybuilder/schema/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This package effectively mirrors the Cassandra OSS default query and schema implementations to - * allow extended schema and query building for the DSE driver. In general, a class in this package - * will need to implement the DSE equivalent interfaces for any DSE specific extensions. - */ -package com.datastax.dse.driver.internal.querybuilder.schema; diff --git a/query-builder/src/test/java/com/datastax/dse/driver/api/querybuilder/Assertions.java b/query-builder/src/test/java/com/datastax/dse/driver/api/querybuilder/Assertions.java deleted file mode 100644 index b1a463378e0..00000000000 --- a/query-builder/src/test/java/com/datastax/dse/driver/api/querybuilder/Assertions.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder; - -import com.datastax.oss.driver.api.querybuilder.BuildableQuery; -import com.datastax.oss.driver.api.querybuilder.CqlSnippet; - -public class Assertions extends org.assertj.core.api.Assertions { - - public static BuildableQueryAssert assertThat(BuildableQuery actual) { - return new BuildableQueryAssert(actual); - } - - public static CqlSnippetAssert assertThat(CqlSnippet actual) { - return new CqlSnippetAssert(actual); - } -} diff --git a/query-builder/src/test/java/com/datastax/dse/driver/api/querybuilder/BuildableQueryAssert.java b/query-builder/src/test/java/com/datastax/dse/driver/api/querybuilder/BuildableQueryAssert.java deleted file mode 100644 index 3173723353a..00000000000 --- a/query-builder/src/test/java/com/datastax/dse/driver/api/querybuilder/BuildableQueryAssert.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.oss.driver.api.querybuilder.BuildableQuery; -import org.assertj.core.api.AbstractAssert; - -public class BuildableQueryAssert extends AbstractAssert { - - public BuildableQueryAssert(BuildableQuery actual) { - super(actual, BuildableQueryAssert.class); - } - - public BuildableQueryAssert hasCql(String expected) { - assertThat(actual.asCql()).isEqualTo(expected); - return this; - } - - public BuildableQueryAssert isIdempotent() { - assertThat(actual.build().isIdempotent()).isTrue(); - return this; - } - - public BuildableQueryAssert isNotIdempotent() { - assertThat(actual.build().isIdempotent()).isFalse(); - return this; - } -} diff --git a/query-builder/src/test/java/com/datastax/dse/driver/api/querybuilder/CqlSnippetAssert.java b/query-builder/src/test/java/com/datastax/dse/driver/api/querybuilder/CqlSnippetAssert.java deleted file mode 100644 index 1aa165d1319..00000000000 --- a/query-builder/src/test/java/com/datastax/dse/driver/api/querybuilder/CqlSnippetAssert.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.oss.driver.api.querybuilder.CqlSnippet; -import org.assertj.core.api.AbstractAssert; - -public class CqlSnippetAssert extends AbstractAssert { - - public CqlSnippetAssert(CqlSnippet actual) { - super(actual, CqlSnippetAssert.class); - } - - public CqlSnippetAssert hasCql(String expected) { - StringBuilder builder = new StringBuilder(); - actual.appendTo(builder); - assertThat(builder.toString()).isEqualTo(expected); - return this; - } -} diff --git a/query-builder/src/test/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseKeyspaceTest.java b/query-builder/src/test/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseKeyspaceTest.java deleted file mode 100644 index a3e2c44cfac..00000000000 --- a/query-builder/src/test/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseKeyspaceTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import static com.datastax.dse.driver.api.querybuilder.Assertions.assertThat; -import static com.datastax.dse.driver.api.querybuilder.DseSchemaBuilder.alterDseKeyspace; - -import org.junit.Test; - -public class AlterDseKeyspaceTest { - - @Test - public void should_not_throw_on_toString_for_AlterKeyspaceStart() { - assertThat(alterDseKeyspace("foo").toString()).isEqualTo("ALTER KEYSPACE foo"); - } - - @Test - public void should_generate_alter_keyspace_with_replication() { - assertThat(alterDseKeyspace("foo").withSimpleStrategy(3)) - .hasCql( - "ALTER KEYSPACE foo WITH replication={'class':'SimpleStrategy','replication_factor':3}"); - } - - @Test - public void should_generate_alter_keyspace_with_graph_engine() { - assertThat(alterDseKeyspace("foo").withSimpleStrategy(3).withGraphEngine("Core")) - .hasCql( - "ALTER KEYSPACE foo " - + "WITH replication={'class':'SimpleStrategy','replication_factor':3} " - + "AND graph_engine='Core'"); - } - - @Test - public void should_generate_alter_keyspace_with_durable_writes_and_options() { - assertThat(alterDseKeyspace("foo").withDurableWrites(true).withOption("hello", "world")) - .hasCql("ALTER KEYSPACE foo WITH durable_writes=true AND hello='world'"); - } -} diff --git a/query-builder/src/test/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableTest.java b/query-builder/src/test/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableTest.java deleted file mode 100644 index b2b5965fbc7..00000000000 --- a/query-builder/src/test/java/com/datastax/dse/driver/api/querybuilder/schema/AlterDseTableTest.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import static com.datastax.dse.driver.api.querybuilder.Assertions.assertThat; -import static com.datastax.dse.driver.api.querybuilder.DseSchemaBuilder.alterDseTable; -import static com.datastax.dse.driver.api.querybuilder.schema.DseGraphEdgeSide.table; - -import com.datastax.oss.driver.api.core.type.DataTypes; -import org.junit.Test; - -public class AlterDseTableTest { - - @Test - public void should_not_throw_on_toString_for_AlterTableStart() { - assertThat(alterDseTable("foo").toString()).isEqualTo("ALTER TABLE foo"); - } - - @Test - public void should_generate_alter_table_with_alter_column_type() { - assertThat(alterDseTable("foo", "bar").alterColumn("x", DataTypes.TEXT)) - .hasCql("ALTER TABLE foo.bar ALTER x TYPE text"); - } - - @Test - public void should_generate_alter_table_with_add_single_column() { - assertThat(alterDseTable("foo", "bar").addColumn("x", DataTypes.TEXT)) - .hasCql("ALTER TABLE foo.bar ADD x text"); - } - - @Test - public void should_generate_alter_table_with_add_three_columns() { - assertThat( - alterDseTable("foo", "bar") - .addColumn("x", DataTypes.TEXT) - .addStaticColumn("y", DataTypes.FLOAT) - .addColumn("z", DataTypes.DOUBLE)) - .hasCql("ALTER TABLE foo.bar ADD (x text,y float STATIC,z double)"); - } - - @Test - public void should_generate_alter_table_with_drop_single_column() { - assertThat(alterDseTable("foo", "bar").dropColumn("x")).hasCql("ALTER TABLE foo.bar DROP x"); - } - - @Test - public void should_generate_alter_table_with_drop_two_columns() { - assertThat(alterDseTable("foo", "bar").dropColumn("x").dropColumn("y")) - .hasCql("ALTER TABLE foo.bar DROP (x,y)"); - } - - @Test - public void should_generate_alter_table_with_drop_two_columns_at_once() { - assertThat(alterDseTable("foo", "bar").dropColumns("x", "y")) - .hasCql("ALTER TABLE foo.bar DROP (x,y)"); - } - - @Test - public void should_generate_alter_table_with_rename_single_column() { - assertThat(alterDseTable("foo", "bar").renameColumn("x", "y")) - .hasCql("ALTER TABLE foo.bar RENAME x TO y"); - } - - @Test - public void should_generate_alter_table_with_rename_three_columns() { - assertThat( - alterDseTable("foo", "bar") - .renameColumn("x", "y") - .renameColumn("u", "v") - .renameColumn("b", "a")) - .hasCql("ALTER TABLE foo.bar RENAME x TO y AND u TO v AND b TO a"); - } - - @Test - public void should_generate_alter_table_with_drop_compact_storage() { - assertThat(alterDseTable("bar").dropCompactStorage()) - .hasCql("ALTER TABLE bar DROP COMPACT STORAGE"); - } - - @Test - public void should_generate_alter_table_with_options() { - assertThat(alterDseTable("bar").withComment("Hello").withCDC(true)) - .hasCql("ALTER TABLE bar WITH comment='Hello' AND cdc=true"); - } - - @Test - public void should_generate_alter_table_with_no_compression() { - assertThat(alterDseTable("bar").withNoCompression()) - .hasCql("ALTER TABLE bar WITH compression={'sstable_compression':''}"); - } - - @Test - public void should_generate_alter_table_to_add_anonymous_vertex_label() { - assertThat(alterDseTable("bar").withVertexLabel()).hasCql("ALTER TABLE bar WITH VERTEX LABEL"); - } - - @Test - public void should_generate_alter_table_to_add_named_vertex_label() { - assertThat(alterDseTable("bar").withVertexLabel("baz")) - .hasCql("ALTER TABLE bar WITH VERTEX LABEL baz"); - } - - @Test - public void should_generate_alter_table_to_remove_anonymous_vertex_label() { - assertThat(alterDseTable("bar").withoutVertexLabel()) - .hasCql("ALTER TABLE bar WITHOUT VERTEX LABEL"); - } - - @Test - public void should_generate_alter_table_to_remove_named_vertex_label() { - assertThat(alterDseTable("bar").withoutVertexLabel("baz")) - .hasCql("ALTER TABLE bar WITHOUT VERTEX LABEL baz"); - } - - @Test - public void should_generate_alter_table_to_add_anonymous_edge_label() { - assertThat( - alterDseTable("bar") - .withEdgeLabel( - table("source").withPartitionKey("pk"), - table("dest") - .withPartitionKey("pk1") - .withPartitionKey("pk2") - .withClusteringColumn("cc"))) - .hasCql("ALTER TABLE bar WITH EDGE LABEL FROM source(pk) TO dest((pk1,pk2),cc)"); - } - - @Test - public void should_generate_alter_table_to_add_named_edge_label() { - assertThat( - alterDseTable("bar") - .withEdgeLabel( - "e", - table("source").withPartitionKey("pk"), - table("dest") - .withPartitionKey("pk1") - .withPartitionKey("pk2") - .withClusteringColumn("cc"))) - .hasCql("ALTER TABLE bar WITH EDGE LABEL e FROM source(pk) TO dest((pk1,pk2),cc)"); - } - - @Test - public void should_generate_alter_table_to_remove_anonymous_edge_label() { - assertThat(alterDseTable("bar").withoutEdgeLabel()) - .hasCql("ALTER TABLE bar WITHOUT EDGE LABEL"); - } - - @Test - public void should_generate_alter_table_to_remove_named_edge_label() { - assertThat(alterDseTable("bar").withoutEdgeLabel("baz")) - .hasCql("ALTER TABLE bar WITHOUT EDGE LABEL baz"); - } -} diff --git a/query-builder/src/test/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseKeyspaceTest.java b/query-builder/src/test/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseKeyspaceTest.java deleted file mode 100644 index d92659b2d1c..00000000000 --- a/query-builder/src/test/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseKeyspaceTest.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import static com.datastax.dse.driver.api.querybuilder.Assertions.assertThat; -import static com.datastax.dse.driver.api.querybuilder.DseSchemaBuilder.createDseKeyspace; - -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import org.junit.Test; - -public class CreateDseKeyspaceTest { - - @Test - public void should_not_throw_on_toString_for_CreateKeyspaceStart() { - assertThat(createDseKeyspace("foo").toString()).isEqualTo("CREATE KEYSPACE foo"); - } - - @Test - public void should_generate_create_keyspace_simple_strategy() { - assertThat(createDseKeyspace("foo").withSimpleStrategy(5)) - .hasCql( - "CREATE KEYSPACE foo WITH replication={'class':'SimpleStrategy','replication_factor':5}"); - } - - @Test - public void should_generate_create_keyspace_simple_strategy_and_durable_writes() { - assertThat(createDseKeyspace("foo").withSimpleStrategy(5).withDurableWrites(true)) - .hasCql( - "CREATE KEYSPACE foo WITH replication={'class':'SimpleStrategy','replication_factor':5} AND durable_writes=true"); - } - - @Test - public void should_generate_create_keyspace_if_not_exists() { - assertThat(createDseKeyspace("foo").ifNotExists().withSimpleStrategy(2)) - .hasCql( - "CREATE KEYSPACE IF NOT EXISTS foo WITH replication={'class':'SimpleStrategy','replication_factor':2}"); - } - - @Test - public void should_generate_create_keyspace_network_topology_strategy() { - assertThat( - createDseKeyspace("foo") - .withNetworkTopologyStrategy(ImmutableMap.of("dc1", 3, "dc2", 4))) - .hasCql( - "CREATE KEYSPACE foo WITH replication={'class':'NetworkTopologyStrategy','dc1':3,'dc2':4}"); - } - - @Test - public void should_generate_create_keyspace_with_graph_engine() { - assertThat( - createDseKeyspace("foo") - .ifNotExists() - .withNetworkTopologyStrategy(ImmutableMap.of("dc1", 3, "dc2", 4)) - .withDurableWrites(true) - .withGraphEngine("Core")) - .hasCql( - "CREATE KEYSPACE IF NOT EXISTS foo " - + "WITH replication={'class':'NetworkTopologyStrategy','dc1':3,'dc2':4} " - + "AND durable_writes=true " - + "AND graph_engine='Core'"); - } - - @Test - public void should_generate_create_keyspace_with_custom_properties() { - assertThat( - createDseKeyspace("foo") - .withSimpleStrategy(3) - .withOption("awesome_feature", true) - .withOption("wow_factor", 11) - .withOption("random_string", "hi")) - .hasCql( - "CREATE KEYSPACE foo WITH replication={'class':'SimpleStrategy','replication_factor':3} AND awesome_feature=true AND wow_factor=11 AND random_string='hi'"); - } -} diff --git a/query-builder/src/test/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseTableTest.java b/query-builder/src/test/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseTableTest.java deleted file mode 100644 index d8ee1c4e380..00000000000 --- a/query-builder/src/test/java/com/datastax/dse/driver/api/querybuilder/schema/CreateDseTableTest.java +++ /dev/null @@ -1,457 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.api.querybuilder.schema; - -import static com.datastax.dse.driver.api.querybuilder.Assertions.assertThat; -import static com.datastax.dse.driver.api.querybuilder.DseSchemaBuilder.createDseTable; -import static com.datastax.dse.driver.api.querybuilder.schema.DseGraphEdgeSide.table; -import static com.datastax.oss.driver.api.querybuilder.SchemaBuilder.udt; - -import com.datastax.oss.driver.api.core.metadata.schema.ClusteringOrder; -import com.datastax.oss.driver.api.core.type.DataTypes; -import com.datastax.oss.driver.api.querybuilder.SchemaBuilder; -import com.datastax.oss.driver.api.querybuilder.SchemaBuilder.RowsPerPartition; -import com.datastax.oss.driver.api.querybuilder.schema.compaction.TimeWindowCompactionStrategy.CompactionWindowUnit; -import com.datastax.oss.driver.api.querybuilder.schema.compaction.TimeWindowCompactionStrategy.TimestampResolution; -import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; -import org.junit.Test; - -public class CreateDseTableTest { - - @Test - public void should_not_throw_on_toString_for_CreateTableStart() { - assertThat(createDseTable("foo").toString()).isEqualTo("CREATE TABLE foo"); - } - - @Test - public void should_generate_create_table_if_not_exists() { - assertThat(createDseTable("bar").ifNotExists().withPartitionKey("k", DataTypes.INT)) - .hasCql("CREATE TABLE IF NOT EXISTS bar (k int PRIMARY KEY)"); - } - - @Test - public void should_generate_create_table_with_single_partition_key() { - assertThat( - createDseTable("bar") - .withPartitionKey("k", DataTypes.INT) - .withColumn("v", DataTypes.TEXT)) - .hasCql("CREATE TABLE bar (k int PRIMARY KEY,v text)"); - } - - @Test - public void should_generate_create_table_with_compound_partition_key() { - assertThat( - createDseTable("bar") - .withPartitionKey("kc", DataTypes.INT) - .withPartitionKey("ka", DataTypes.TIMESTAMP) - .withColumn("v", DataTypes.TEXT)) - .hasCql("CREATE TABLE bar (kc int,ka timestamp,v text,PRIMARY KEY((kc,ka)))"); - } - - @Test - public void should_generate_create_table_with_single_partition_key_and_clustering_column() { - assertThat( - createDseTable("bar") - .withPartitionKey("k", DataTypes.INT) - .withClusteringColumn("c", DataTypes.TEXT) - .withColumn("v", udt("val", true))) - .hasCql("CREATE TABLE bar (k int,c text,v frozen,PRIMARY KEY(k,c))"); - } - - @Test - public void should_generate_create_table_with_static_column() { - assertThat( - createDseTable("bar") - .withPartitionKey("k", DataTypes.INT) - .withClusteringColumn("c", DataTypes.TEXT) - .withStaticColumn("s", DataTypes.TIMEUUID) - .withColumn("v", udt("val", true))) - .hasCql("CREATE TABLE bar (k int,c text,s timeuuid STATIC,v frozen,PRIMARY KEY(k,c))"); - } - - @Test - public void should_generate_create_table_with_compound_partition_key_and_clustering_columns() { - assertThat( - createDseTable("bar") - .withPartitionKey("kc", DataTypes.INT) - .withPartitionKey("ka", DataTypes.TIMESTAMP) - .withClusteringColumn("c", DataTypes.FLOAT) - .withClusteringColumn("a", DataTypes.UUID) - .withColumn("v", DataTypes.TEXT)) - .hasCql( - "CREATE TABLE bar (kc int,ka timestamp,c float,a uuid,v text,PRIMARY KEY((kc,ka),c,a))"); - } - - @Test - public void should_generate_create_table_with_compact_storage() { - assertThat( - createDseTable("bar") - .withPartitionKey("k", DataTypes.INT) - .withColumn("v", DataTypes.TEXT) - .withCompactStorage()) - .hasCql("CREATE TABLE bar (k int PRIMARY KEY,v text) WITH COMPACT STORAGE"); - } - - @Test - public void should_generate_create_table_with_clustering_single() { - assertThat( - createDseTable("bar") - .withPartitionKey("k", DataTypes.INT) - .withClusteringColumn("c", DataTypes.TEXT) - .withColumn("v", DataTypes.TEXT) - .withClusteringOrder("c", ClusteringOrder.ASC)) - .hasCql( - "CREATE TABLE bar (k int,c text,v text,PRIMARY KEY(k,c)) WITH CLUSTERING ORDER BY (c ASC)"); - } - - @Test - public void should_generate_create_table_with_clustering_three() { - assertThat( - createDseTable("bar") - .withPartitionKey("k", DataTypes.INT) - .withClusteringColumn("c0", DataTypes.TEXT) - .withClusteringColumn("c1", DataTypes.TEXT) - .withClusteringColumn("c2", DataTypes.TEXT) - .withColumn("v", DataTypes.TEXT) - .withClusteringOrder("c0", ClusteringOrder.DESC) - .withClusteringOrder( - ImmutableMap.of("c1", ClusteringOrder.ASC, "c2", ClusteringOrder.DESC))) - .hasCql( - "CREATE TABLE bar (k int,c0 text,c1 text,c2 text,v text,PRIMARY KEY(k,c0,c1,c2)) WITH CLUSTERING ORDER BY (c0 DESC,c1 ASC,c2 DESC)"); - } - - @Test - public void should_generate_create_table_with_compact_storage_and_default_ttl() { - assertThat( - createDseTable("bar") - .withPartitionKey("k", DataTypes.INT) - .withColumn("v", DataTypes.TEXT) - .withCompactStorage() - .withDefaultTimeToLiveSeconds(86400)) - .hasCql( - "CREATE TABLE bar (k int PRIMARY KEY,v text) WITH COMPACT STORAGE AND default_time_to_live=86400"); - } - - @Test - public void should_generate_create_table_with_clustering_compact_storage_and_default_ttl() { - assertThat( - createDseTable("bar") - .withPartitionKey("k", DataTypes.INT) - .withClusteringColumn("c", DataTypes.TEXT) - .withColumn("v", DataTypes.TEXT) - .withCompactStorage() - .withClusteringOrder("c", ClusteringOrder.DESC) - .withDefaultTimeToLiveSeconds(86400)) - .hasCql( - "CREATE TABLE bar (k int,c text,v text,PRIMARY KEY(k,c)) WITH COMPACT STORAGE AND CLUSTERING ORDER BY (c DESC) AND default_time_to_live=86400"); - } - - @Test - public void should_generate_create_table_with_options() { - assertThat( - createDseTable("bar") - .withPartitionKey("k", DataTypes.INT) - .withColumn("v", DataTypes.TEXT) - .withBloomFilterFpChance(0.42) - .withCDC(false) - .withComment("Hello world") - .withDcLocalReadRepairChance(0.54) - .withDefaultTimeToLiveSeconds(86400) - .withGcGraceSeconds(864000) - .withMemtableFlushPeriodInMs(10000) - .withMinIndexInterval(1024) - .withMaxIndexInterval(4096) - .withReadRepairChance(0.55) - .withSpeculativeRetry("99percentile")) - .hasCql( - "CREATE TABLE bar (k int PRIMARY KEY,v text) WITH bloom_filter_fp_chance=0.42 AND cdc=false AND comment='Hello world' AND dclocal_read_repair_chance=0.54 AND default_time_to_live=86400 AND gc_grace_seconds=864000 AND memtable_flush_period_in_ms=10000 AND min_index_interval=1024 AND max_index_interval=4096 AND read_repair_chance=0.55 AND speculative_retry='99percentile'"); - } - - @Test - public void should_generate_create_table_lz4_compression() { - assertThat( - createDseTable("bar") - .withPartitionKey("k", DataTypes.INT) - .withColumn("v", DataTypes.TEXT) - .withLZ4Compression()) - .hasCql( - "CREATE TABLE bar (k int PRIMARY KEY,v text) WITH compression={'class':'LZ4Compressor'}"); - } - - @Test - public void should_generate_create_table_lz4_compression_options() { - assertThat( - createDseTable("bar") - .withPartitionKey("k", DataTypes.INT) - .withColumn("v", DataTypes.TEXT) - .withLZ4Compression(1024)) - .hasCql( - "CREATE TABLE bar (k int PRIMARY KEY,v text) WITH compression={'class':'LZ4Compressor','chunk_length_in_kb':1024}"); - } - - @Test - public void should_generate_create_table_lz4_compression_options_crc() { - assertThat( - createDseTable("bar") - .withPartitionKey("k", DataTypes.INT) - .withColumn("v", DataTypes.TEXT) - .withLZ4Compression(1024, .5)) - .hasCql( - "CREATE TABLE bar (k int PRIMARY KEY,v text) WITH compression={'class':'LZ4Compressor','chunk_length_kb':1024,'crc_check_chance':0.5}"); - } - - @Test - public void should_generate_create_table_zstd_compression() { - assertThat( - createDseTable("bar") - .withPartitionKey("k", DataTypes.INT) - .withColumn("v", DataTypes.TEXT) - .withZstdCompression()) - .hasCql( - "CREATE TABLE bar (k int PRIMARY KEY,v text) WITH compression={'class':'ZstdCompressor'}"); - } - - @Test - public void should_generate_create_table_zstd_compression_options() { - assertThat( - createDseTable("bar") - .withPartitionKey("k", DataTypes.INT) - .withColumn("v", DataTypes.TEXT) - .withZstdCompression(1024)) - .hasCql( - "CREATE TABLE bar (k int PRIMARY KEY,v text) WITH compression={'class':'ZstdCompressor','chunk_length_in_kb':1024}"); - } - - @Test - public void should_generate_create_table_snappy_compression() { - assertThat( - createDseTable("bar") - .withPartitionKey("k", DataTypes.INT) - .withColumn("v", DataTypes.TEXT) - .withSnappyCompression()) - .hasCql( - "CREATE TABLE bar (k int PRIMARY KEY,v text) WITH compression={'class':'SnappyCompressor'}"); - } - - @Test - public void should_generate_create_table_snappy_compression_options() { - assertThat( - createDseTable("bar") - .withPartitionKey("k", DataTypes.INT) - .withColumn("v", DataTypes.TEXT) - .withSnappyCompression(2048)) - .hasCql( - "CREATE TABLE bar (k int PRIMARY KEY,v text) WITH compression={'class':'SnappyCompressor','chunk_length_in_kb':2048}"); - } - - @Test - public void should_generate_create_table_snappy_compression_options_crc() { - assertThat( - createDseTable("bar") - .withPartitionKey("k", DataTypes.INT) - .withColumn("v", DataTypes.TEXT) - .withSnappyCompression(2048, .25)) - .hasCql( - "CREATE TABLE bar (k int PRIMARY KEY,v text) WITH compression={'class':'SnappyCompressor','chunk_length_kb':2048,'crc_check_chance':0.25}"); - } - - @Test - public void should_generate_create_table_deflate_compression() { - assertThat( - createDseTable("bar") - .withPartitionKey("k", DataTypes.INT) - .withColumn("v", DataTypes.TEXT) - .withDeflateCompression()) - .hasCql( - "CREATE TABLE bar (k int PRIMARY KEY,v text) WITH compression={'class':'DeflateCompressor'}"); - } - - @Test - public void should_generate_create_table_deflate_compression_options() { - assertThat( - createDseTable("bar") - .withPartitionKey("k", DataTypes.INT) - .withColumn("v", DataTypes.TEXT) - .withDeflateCompression(4096)) - .hasCql( - "CREATE TABLE bar (k int PRIMARY KEY,v text) WITH compression={'class':'DeflateCompressor','chunk_length_in_kb':4096}"); - } - - @Test - public void should_generate_create_table_deflate_compression_options_crc() { - assertThat( - createDseTable("bar") - .withPartitionKey("k", DataTypes.INT) - .withColumn("v", DataTypes.TEXT) - .withDeflateCompression(4096, .1)) - .hasCql( - "CREATE TABLE bar (k int PRIMARY KEY,v text) WITH compression={'class':'DeflateCompressor','chunk_length_kb':4096,'crc_check_chance':0.1}"); - } - - @Test - public void should_generate_create_table_caching_options() { - assertThat( - createDseTable("bar") - .withPartitionKey("k", DataTypes.INT) - .withColumn("v", DataTypes.TEXT) - .withCaching(true, RowsPerPartition.rows(10))) - .hasCql( - "CREATE TABLE bar (k int PRIMARY KEY,v text) WITH caching={'keys':'ALL','rows_per_partition':'10'}"); - } - - @Test - public void should_generate_create_table_size_tiered_compaction() { - assertThat( - createDseTable("bar") - .withPartitionKey("k", DataTypes.INT) - .withColumn("v", DataTypes.TEXT) - .withCompaction( - SchemaBuilder.sizeTieredCompactionStrategy() - .withBucketHigh(1.6) - .withBucketLow(0.6) - .withColdReadsToOmit(0.1) - .withMaxThreshold(33) - .withMinThreshold(5) - .withMinSSTableSizeInBytes(50000) - .withOnlyPurgeRepairedTombstones(true) - .withEnabled(false) - .withTombstoneCompactionIntervalInSeconds(86400) - .withTombstoneThreshold(0.22) - .withUncheckedTombstoneCompaction(true))) - .hasCql( - "CREATE TABLE bar (k int PRIMARY KEY,v text) WITH compaction={'class':'SizeTieredCompactionStrategy','bucket_high':1.6,'bucket_low':0.6,'cold_reads_to_omit':0.1,'max_threshold':33,'min_threshold':5,'min_sstable_size':50000,'only_purge_repaired_tombstones':true,'enabled':false,'tombstone_compaction_interval':86400,'tombstone_threshold':0.22,'unchecked_tombstone_compaction':true}"); - } - - @Test - public void should_generate_create_table_leveled_compaction() { - assertThat( - createDseTable("bar") - .withPartitionKey("k", DataTypes.INT) - .withColumn("v", DataTypes.TEXT) - .withCompaction( - SchemaBuilder.leveledCompactionStrategy() - .withSSTableSizeInMB(110) - .withTombstoneCompactionIntervalInSeconds(3600))) - .hasCql( - "CREATE TABLE bar (k int PRIMARY KEY,v text) WITH compaction={'class':'LeveledCompactionStrategy','sstable_size_in_mb':110,'tombstone_compaction_interval':3600}"); - } - - @Test - public void should_generate_create_table_time_window_compaction() { - assertThat( - createDseTable("bar") - .withPartitionKey("k", DataTypes.INT) - .withColumn("v", DataTypes.TEXT) - .withCompaction( - SchemaBuilder.timeWindowCompactionStrategy() - .withCompactionWindow(10, CompactionWindowUnit.DAYS) - .withTimestampResolution(TimestampResolution.MICROSECONDS) - .withUnsafeAggressiveSSTableExpiration(false))) - .hasCql( - "CREATE TABLE bar (k int PRIMARY KEY,v text) WITH compaction={'class':'TimeWindowCompactionStrategy','compaction_window_size':10,'compaction_window_unit':'DAYS','timestamp_resolution':'MICROSECONDS','unsafe_aggressive_sstable_expiration':false}"); - } - - @Test - public void should_generate_create_table_with_anonymous_vertex() { - assertThat( - createDseTable("bar") - .withPartitionKey("k", DataTypes.INT) - .withColumn("v", DataTypes.TEXT) - .withComment("test") - .withVertexLabel() - .withCaching(true, RowsPerPartition.rows(10))) - .hasCql( - "CREATE TABLE bar (k int PRIMARY KEY,v text) " - + "WITH VERTEX LABEL " - + "AND comment='test' " - + "AND caching={'keys':'ALL','rows_per_partition':'10'}"); - } - - @Test - public void should_generate_create_table_with_named_vertex() { - assertThat( - createDseTable("bar") - .withPartitionKey("k", DataTypes.INT) - .withColumn("v", DataTypes.TEXT) - .withComment("test") - .withVertexLabel("b") - .withCaching(true, RowsPerPartition.rows(10))) - .hasCql( - "CREATE TABLE bar (k int PRIMARY KEY,v text) " - + "WITH VERTEX LABEL b " - + "AND comment='test' " - + "AND caching={'keys':'ALL','rows_per_partition':'10'}"); - } - - @Test - public void should_generate_create_table_with_anonymous_edge() { - assertThat( - createDseTable("contributors") - .withPartitionKey("contributor", DataTypes.TEXT) - .withClusteringColumn("company_name", DataTypes.TEXT) - .withClusteringColumn("software_name", DataTypes.TEXT) - .withClusteringColumn("software_version", DataTypes.INT) - .withEdgeLabel( - table("person").withPartitionKey("contributor"), - table("soft") - .withPartitionKey("company_name") - .withPartitionKey("software_name") - .withClusteringColumn("software_version"))) - .hasCql( - "CREATE TABLE contributors (contributor text,company_name text,software_name text,software_version int," - + "PRIMARY KEY(contributor,company_name,software_name,software_version)) " - + "WITH EDGE LABEL " - + "FROM person(contributor) " - + "TO soft((company_name,software_name),software_version)"); - } - - @Test - public void should_generate_create_table_with_named_edge() { - assertThat( - createDseTable("contributors") - .withPartitionKey("contributor", DataTypes.TEXT) - .withClusteringColumn("company_name", DataTypes.TEXT) - .withClusteringColumn("software_name", DataTypes.TEXT) - .withClusteringColumn("software_version", DataTypes.INT) - .withClusteringOrder("company_name", ClusteringOrder.ASC) - .withEdgeLabel( - "contrib", - table("person").withPartitionKey("contributor"), - table("soft") - .withPartitionKey("company_name") - .withPartitionKey("software_name") - .withClusteringColumn("software_version"))) - .hasCql( - "CREATE TABLE contributors (contributor text,company_name text,software_name text,software_version int," - + "PRIMARY KEY(contributor,company_name,software_name,software_version)) " - + "WITH CLUSTERING ORDER BY (company_name ASC) " - + "AND EDGE LABEL contrib " - + "FROM person(contributor) " - + "TO soft((company_name,software_name),software_version)"); - } - - @Test - public void should_generate_create_table_crc_check_chance() { - assertThat( - createDseTable("bar") - .withPartitionKey("k", DataTypes.INT) - .withColumn("v", DataTypes.TEXT) - .withCRCCheckChance(0.8)) - .hasCql("CREATE TABLE bar (k int PRIMARY KEY,v text) WITH crc_check_chance=0.8"); - } -} diff --git a/query-builder/src/test/java/com/datastax/dse/driver/internal/querybuilder/DependencyCheckTest.java b/query-builder/src/test/java/com/datastax/dse/driver/internal/querybuilder/DependencyCheckTest.java deleted file mode 100644 index ff5dd1e66a4..00000000000 --- a/query-builder/src/test/java/com/datastax/dse/driver/internal/querybuilder/DependencyCheckTest.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.querybuilder; - -import com.datastax.dse.driver.internal.DependencyCheckTestBase; -import java.nio.file.Path; -import java.nio.file.Paths; - -public class DependencyCheckTest extends DependencyCheckTestBase { - - @Override - protected Path getDepsTxtPath() { - return Paths.get( - getBaseResourcePathString(), - "target", - "classes", - "com", - "datastax", - "dse", - "driver", - "internal", - "querybuilder", - "deps.txt"); - } -} diff --git a/query-builder/src/test/java/com/datastax/dse/driver/internal/querybuilder/schema/CreateDseAggregateTest.java b/query-builder/src/test/java/com/datastax/dse/driver/internal/querybuilder/schema/CreateDseAggregateTest.java deleted file mode 100644 index 22ba0d8814d..00000000000 --- a/query-builder/src/test/java/com/datastax/dse/driver/internal/querybuilder/schema/CreateDseAggregateTest.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.querybuilder.schema; - -import static com.datastax.dse.driver.api.querybuilder.DseSchemaBuilder.createDseAggregate; -import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.literal; -import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.tuple; -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.oss.driver.api.core.type.DataTypes; -import org.junit.Test; - -/** - * Tests for creating DSE extended aggregates. Most of these tests are copied from the OSS {@code - * com.datastax.oss.driver.internal.querybuilder.schema.CreateAggregateTest} class to ensure DSE - * extended behavior does not break OSS functionality, with additional tests to verify the DSE - * specific functionality (i.e. the DETERMINISTIC keyword). - */ -public class CreateDseAggregateTest { - - @Test - public void should_create_aggreate_with_simple_param() { - - assertThat( - createDseAggregate("keyspace1", "agg1") - .withParameter(DataTypes.INT) - .withSFunc("sfunction") - .withSType(DataTypes.ASCII) - .withFinalFunc("finalfunction") - .withInitCond(tuple(literal(0), literal(0))) - .asCql()) - .isEqualTo( - "CREATE AGGREGATE keyspace1.agg1 (int) SFUNC sfunction STYPE ascii FINALFUNC finalfunction INITCOND (0,0)"); - } - - @Test - public void should_create_aggregate_with_many_params() { - - assertThat( - createDseAggregate("keyspace1", "agg2") - .withParameter(DataTypes.INT) - .withParameter(DataTypes.TEXT) - .withParameter(DataTypes.BOOLEAN) - .withSFunc("sfunction") - .withSType(DataTypes.ASCII) - .withFinalFunc("finalfunction") - .withInitCond(tuple(literal(0), literal(0))) - .asCql()) - .isEqualTo( - "CREATE AGGREGATE keyspace1.agg2 (int,text,boolean) SFUNC sfunction STYPE ascii FINALFUNC finalfunction INITCOND (0,0)"); - } - - @Test - public void should_create_aggregate_with_param_without_frozen() { - - assertThat( - createDseAggregate("keyspace1", "agg9") - .withParameter(DataTypes.tupleOf(DataTypes.TEXT)) - .withSFunc("sfunction") - .withSType(DataTypes.ASCII) - .withFinalFunc("finalfunction") - .withInitCond(tuple(literal(0), literal(0))) - .asCql()) - .isEqualTo( - "CREATE AGGREGATE keyspace1.agg9 (tuple) SFUNC sfunction STYPE ascii FINALFUNC finalfunction INITCOND (0,0)"); - } - - @Test - public void should_create_aggregate_with_no_params() { - - assertThat( - createDseAggregate("keyspace1", "agg3") - .withSFunc("sfunction") - .withSType(DataTypes.ASCII) - .withFinalFunc("finalfunction") - .withInitCond(tuple(literal(0), literal(0))) - .asCql()) - .isEqualTo( - "CREATE AGGREGATE keyspace1.agg3 () SFUNC sfunction STYPE ascii FINALFUNC finalfunction INITCOND (0,0)"); - } - - @Test - public void should_create_aggregate_with_no_keyspace() { - - assertThat( - createDseAggregate("agg4") - .withSFunc("sfunction") - .withSType(DataTypes.ASCII) - .withFinalFunc("finalfunction") - .withInitCond(tuple(literal(0), literal(0))) - .asCql()) - .isEqualTo( - "CREATE AGGREGATE agg4 () SFUNC sfunction STYPE ascii FINALFUNC finalfunction INITCOND (0,0)"); - } - - @Test - public void should_create_aggregate_with_if_not_exists() { - - assertThat( - createDseAggregate("agg6") - .ifNotExists() - .withSFunc("sfunction") - .withSType(DataTypes.ASCII) - .withFinalFunc("finalfunction") - .withInitCond(tuple(literal(0), literal(0))) - .asCql()) - .isEqualTo( - "CREATE AGGREGATE IF NOT EXISTS agg6 () SFUNC sfunction STYPE ascii FINALFUNC finalfunction INITCOND (0,0)"); - } - - @Test - public void should_create_aggregate_with_no_final_func() { - - assertThat( - createDseAggregate("cycling", "sum") - .withParameter(DataTypes.INT) - .withSFunc("dsum") - .withSType(DataTypes.INT) - .asCql()) - .isEqualTo("CREATE AGGREGATE cycling.sum (int) SFUNC dsum STYPE int"); - } - - @Test - public void should_create_or_replace() { - assertThat( - createDseAggregate("keyspace1", "agg7") - .orReplace() - .withSFunc("sfunction") - .withSType(DataTypes.ASCII) - .withFinalFunc("finalfunction") - .withInitCond(tuple(literal(0), literal(0))) - .asCql()) - .isEqualTo( - "CREATE OR REPLACE AGGREGATE keyspace1.agg7 () SFUNC sfunction STYPE ascii FINALFUNC finalfunction INITCOND (0,0)"); - } - - @Test - public void should_not_throw_on_toString_for_CreateAggregateStart() { - assertThat(createDseAggregate("agg1").toString()).isEqualTo("CREATE AGGREGATE agg1 ()"); - } - - @Test - public void should_not_throw_on_toString_for_CreateAggregateWithParam() { - assertThat(createDseAggregate("func1").withParameter(DataTypes.INT).toString()) - .isEqualTo("CREATE AGGREGATE func1 (int)"); - } - - @Test - public void should_not_throw_on_toString_for_NotExists_OrReplace() { - assertThat(createDseAggregate("func1").ifNotExists().orReplace().toString()) - .isEqualTo("CREATE OR REPLACE AGGREGATE IF NOT EXISTS func1 ()"); - } - - @Test - public void should_create_aggregate_with_deterministic() { - - assertThat( - createDseAggregate("keyspace1", "agg1") - .withParameter(DataTypes.INT) - .withSFunc("sfunction") - .withSType(DataTypes.ASCII) - .withFinalFunc("finalfunction") - .withInitCond(tuple(literal(0), literal(0))) - .deterministic() - .asCql()) - .isEqualTo( - "CREATE AGGREGATE keyspace1.agg1 (int) SFUNC sfunction STYPE ascii FINALFUNC finalfunction INITCOND (0,0) DETERMINISTIC"); - } -} diff --git a/query-builder/src/test/java/com/datastax/dse/driver/internal/querybuilder/schema/CreateDseFunctionTest.java b/query-builder/src/test/java/com/datastax/dse/driver/internal/querybuilder/schema/CreateDseFunctionTest.java deleted file mode 100644 index b795b4c5251..00000000000 --- a/query-builder/src/test/java/com/datastax/dse/driver/internal/querybuilder/schema/CreateDseFunctionTest.java +++ /dev/null @@ -1,454 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.dse.driver.internal.querybuilder.schema; - -import static com.datastax.dse.driver.api.querybuilder.DseSchemaBuilder.createDseFunction; -import static com.datastax.oss.driver.api.querybuilder.SchemaBuilder.udt; -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.oss.driver.api.core.type.DataTypes; -import org.junit.Test; - -/** - * Tests for creating DSE extended functions. Most of these tests are copied from the OSS {@code - * com.datastax.oss.driver.internal.querybuilder.schema.CreateFunctionTest} class to ensure DSE - * extended behavior does not break OSS functionality, with additional tests to verify the DSE - * specific functionality (i.e. the DETERMINISTIC and MONOTONIC keywords). - */ -public class CreateDseFunctionTest { - - @Test - public void should_not_throw_on_toString_for_CreateFunctionStart() { - String funcStr = createDseFunction("func1").toString(); - assertThat(funcStr).isEqualTo("CREATE FUNCTION func1 () CALLED ON NULL INPUT"); - } - - @Test - public void should_not_throw_on_toString_for_CreateFunctionWithType() { - assertThat( - createDseFunction("func1") - .withParameter("param1", DataTypes.INT) - .returnsNullOnNull() - .returnsType(DataTypes.INT) - .toString()) - .isEqualTo("CREATE FUNCTION func1 (param1 int) RETURNS NULL ON NULL INPUT RETURNS int"); - } - - @Test - public void should_not_throw_on_toString_for_CreateFunctionWithLanguage() { - assertThat( - createDseFunction("func1") - .withParameter("param1", DataTypes.INT) - .returnsNullOnNull() - .returnsType(DataTypes.INT) - .withJavaLanguage() - .toString()) - .isEqualTo( - "CREATE FUNCTION func1 (param1 int) RETURNS NULL ON NULL INPUT RETURNS int LANGUAGE java"); - } - - @Test - public void should_create_function_with_simple_params() { - assertThat( - createDseFunction("keyspace1", "func1") - .withParameter("param1", DataTypes.INT) - .calledOnNull() - .returnsType(DataTypes.TEXT) - .withJavaLanguage() - .asQuoted("return Integer.toString(param1);") - .asCql()) - .isEqualTo( - "CREATE FUNCTION keyspace1.func1 (param1 int) CALLED ON NULL INPUT RETURNS text LANGUAGE java AS 'return Integer.toString(param1);'"); - } - - @Test - public void should_create_function_with_param_and_return_type_not_frozen() { - assertThat( - createDseFunction("keyspace1", "func6") - .withParameter("param1", DataTypes.tupleOf(DataTypes.INT, DataTypes.INT)) - .returnsNullOnNull() - .returnsType(udt("person", true)) - .withJavaLanguage() - .as("'return Integer.toString(param1);'") - .asCql()) - .isEqualTo( - "CREATE FUNCTION keyspace1.func6 (param1 tuple) RETURNS NULL ON NULL INPUT RETURNS person LANGUAGE java AS 'return Integer.toString(param1);'"); - } - - @Test - public void should_honor_returns_null() { - assertThat( - createDseFunction("keyspace1", "func2") - .withParameter("param1", DataTypes.INT) - .returnsNullOnNull() - .returnsType(DataTypes.TEXT) - .withJavaLanguage() - .asQuoted("return Integer.toString(param1);") - .asCql()) - .isEqualTo( - "CREATE FUNCTION keyspace1.func2 (param1 int) RETURNS NULL ON NULL INPUT RETURNS text LANGUAGE java AS 'return Integer.toString(param1);'"); - } - - @Test - public void should_create_function_with_many_params() { - assertThat( - createDseFunction("keyspace1", "func3") - .withParameter("param1", DataTypes.INT) - .withParameter("param2", DataTypes.TEXT) - .withParameter("param3", DataTypes.BOOLEAN) - .returnsNullOnNull() - .returnsType(DataTypes.TEXT) - .withJavaLanguage() - .asQuoted("return Integer.toString(param1);") - .asCql()) - .isEqualTo( - "CREATE FUNCTION keyspace1.func3 (param1 int,param2 text,param3 boolean) RETURNS NULL ON NULL INPUT RETURNS text LANGUAGE java AS 'return Integer.toString(param1);'"); - } - - @Test - public void should_create_function_with_no_params() { - - assertThat( - createDseFunction("keyspace1", "func4") - .returnsNullOnNull() - .returnsType(DataTypes.TEXT) - .withLanguage("java") - .asQuoted("return \"hello world\";") - .asCql()) - .isEqualTo( - "CREATE FUNCTION keyspace1.func4 () RETURNS NULL ON NULL INPUT RETURNS text LANGUAGE java AS 'return \"hello world\";'"); - } - - @Test - public void should_create_function_with_no_keyspace() { - assertThat( - createDseFunction("func5") - .returnsNullOnNull() - .returnsType(DataTypes.TEXT) - .withJavaLanguage() - .asQuoted("return \"hello world\";") - .asCql()) - .isEqualTo( - "CREATE FUNCTION func5 () RETURNS NULL ON NULL INPUT RETURNS text LANGUAGE java AS 'return \"hello world\";'"); - } - - @Test - public void should_create_function_with_if_not_exists() { - assertThat( - createDseFunction("keyspace1", "func6") - .ifNotExists() - .returnsNullOnNull() - .returnsType(DataTypes.TEXT) - .withJavaLanguage() - .asQuoted("return \"hello world\";") - .asCql()) - .isEqualTo( - "CREATE FUNCTION IF NOT EXISTS keyspace1.func6 () RETURNS NULL ON NULL INPUT RETURNS text LANGUAGE java AS 'return \"hello world\";'"); - } - - @Test - public void should_create_or_replace() { - assertThat( - createDseFunction("keyspace1", "func6") - .orReplace() - .withParameter("param1", DataTypes.INT) - .returnsNullOnNull() - .returnsType(DataTypes.TEXT) - .withJavaLanguage() - .asQuoted("return Integer.toString(param1);") - .asCql()) - .isEqualTo( - "CREATE OR REPLACE FUNCTION keyspace1.func6 (param1 int) RETURNS NULL ON NULL INPUT RETURNS text LANGUAGE java AS 'return Integer.toString(param1);'"); - } - - @Test - public void should_not_quote_body_using_as() { - assertThat( - createDseFunction("keyspace1", "func6") - .withParameter("param1", DataTypes.INT) - .returnsNullOnNull() - .returnsType(DataTypes.TEXT) - .withJavaLanguage() - .as("'return Integer.toString(param1);'") - .asCql()) - .isEqualTo( - "CREATE FUNCTION keyspace1.func6 (param1 int) RETURNS NULL ON NULL INPUT RETURNS text LANGUAGE java AS 'return Integer.toString(param1);'"); - } - - @Test - public void should_quote_with_dollar_signs_on_asQuoted_if_body_contains_single_quote() { - assertThat( - createDseFunction("keyspace1", "func6") - .withParameter("param1", DataTypes.INT) - .returnsNullOnNull() - .returnsType(DataTypes.TEXT) - .withJavaScriptLanguage() - .asQuoted("'hello ' + param1;") - .asCql()) - .isEqualTo( - "CREATE FUNCTION keyspace1.func6 (param1 int) RETURNS NULL ON NULL INPUT RETURNS text LANGUAGE javascript AS $$ 'hello ' + param1; $$"); - } - - @Test - public void should_not_throw_on_toString_for_create_function_with_deterministic() { - final String funcStr = - createDseFunction("func1") - .withParameter("param1", DataTypes.INT) - .returnsNullOnNull() - .returnsType(DataTypes.INT) - .deterministic() - .toString(); - assertThat(funcStr) - .isEqualTo( - "CREATE FUNCTION func1 (param1 int) RETURNS NULL ON NULL INPUT RETURNS int DETERMINISTIC"); - } - - @Test - public void should_not_quote_body_using_as_with_deterministic() { - final String funcStr = - createDseFunction("func1") - .withParameter("param1", DataTypes.INT) - .returnsNullOnNull() - .returnsType(DataTypes.TEXT) - .deterministic() - .withJavaLanguage() - .as("'return Integer.toString(param1);'") - .asCql(); - assertThat(funcStr) - .isEqualTo( - "CREATE FUNCTION func1 (param1 int) RETURNS NULL ON NULL INPUT RETURNS text DETERMINISTIC LANGUAGE java AS 'return Integer.toString(param1);'"); - } - - @Test - public void - should_quote_with_dollar_signs_on_asQuoted_if_body_contains_single_quote_with_deterministic() { - final String funcStr = - createDseFunction("func1") - .withParameter("param1", DataTypes.INT) - .returnsNullOnNull() - .returnsType(DataTypes.TEXT) - .deterministic() - .withJavaScriptLanguage() - .asQuoted("'hello ' + param1;") - .asCql(); - assertThat(funcStr) - .isEqualTo( - "CREATE FUNCTION func1 (param1 int) RETURNS NULL ON NULL INPUT RETURNS text DETERMINISTIC LANGUAGE javascript AS $$ 'hello ' + param1; $$"); - } - - @Test - public void should_not_throw_on_toString_for_create_function_with_monotonic() { - final String funcStr = - createDseFunction("func1") - .withParameter("param1", DataTypes.INT) - .returnsNullOnNull() - .returnsType(DataTypes.INT) - .monotonic() - .toString(); - assertThat(funcStr) - .isEqualTo( - "CREATE FUNCTION func1 (param1 int) RETURNS NULL ON NULL INPUT RETURNS int MONOTONIC"); - } - - @Test - public void should_not_quote_body_using_as_with_monotonic() { - final String funcStr = - createDseFunction("func1") - .withParameter("param1", DataTypes.INT) - .returnsNullOnNull() - .returnsType(DataTypes.TEXT) - .monotonic() - .withJavaLanguage() - .as("'return Integer.toString(param1);'") - .asCql(); - assertThat(funcStr) - .isEqualTo( - "CREATE FUNCTION func1 (param1 int) RETURNS NULL ON NULL INPUT RETURNS text MONOTONIC LANGUAGE java AS 'return Integer.toString(param1);'"); - } - - @Test - public void - should_quote_with_dollar_signs_on_asQuoted_if_body_contains_single_quote_with_monotonic() { - final String funcStr = - createDseFunction("func1") - .withParameter("param1", DataTypes.INT) - .returnsNullOnNull() - .returnsType(DataTypes.TEXT) - .monotonic() - .withJavaScriptLanguage() - .asQuoted("'hello ' + param1;") - .asCql(); - assertThat(funcStr) - .isEqualTo( - "CREATE FUNCTION func1 (param1 int) RETURNS NULL ON NULL INPUT RETURNS text MONOTONIC LANGUAGE javascript AS $$ 'hello ' + param1; $$"); - } - - @Test - public void should_not_throw_on_toString_for_create_function_with_monotonic_on() { - final String funcStr = - createDseFunction("func1") - .withParameter("param1", DataTypes.INT) - .withParameter("param2", DataTypes.INT) - .returnsNullOnNull() - .returnsType(DataTypes.INT) - .monotonicOn("param2") - .toString(); - assertThat(funcStr) - .isEqualTo( - "CREATE FUNCTION func1 (param1 int,param2 int) RETURNS NULL ON NULL INPUT RETURNS int MONOTONIC ON param2"); - } - - @Test - public void should_not_quote_body_using_as_with_monotonic_on() { - final String funcStr = - createDseFunction("func1") - .withParameter("param1", DataTypes.INT) - .withParameter("param2", DataTypes.INT) - .returnsNullOnNull() - .returnsType(DataTypes.TEXT) - .monotonicOn("param2") - .withJavaLanguage() - .as("'return Integer.toString(param1);'") - .asCql(); - assertThat(funcStr) - .isEqualTo( - "CREATE FUNCTION func1 (param1 int,param2 int) RETURNS NULL ON NULL INPUT RETURNS text MONOTONIC ON param2 LANGUAGE java AS 'return Integer.toString(param1);'"); - } - - @Test - public void - should_quote_with_dollar_signs_on_asQuoted_if_body_contains_single_quote_with_monotonic_on() { - final String funcStr = - createDseFunction("func1") - .withParameter("param1", DataTypes.INT) - .withParameter("param2", DataTypes.INT) - .returnsNullOnNull() - .returnsType(DataTypes.TEXT) - .monotonicOn("param2") - .withJavaScriptLanguage() - .asQuoted("'hello ' + param1;") - .asCql(); - assertThat(funcStr) - .isEqualTo( - "CREATE FUNCTION func1 (param1 int,param2 int) RETURNS NULL ON NULL INPUT RETURNS text MONOTONIC ON param2 LANGUAGE javascript AS $$ 'hello ' + param1; $$"); - } - - @Test - public void should_not_throw_on_toString_for_create_function_with_deterministic_and_monotonic() { - final String funcStr = - createDseFunction("func1") - .withParameter("param1", DataTypes.INT) - .returnsNullOnNull() - .returnsType(DataTypes.INT) - .deterministic() - .monotonic() - .toString(); - assertThat(funcStr) - .isEqualTo( - "CREATE FUNCTION func1 (param1 int) RETURNS NULL ON NULL INPUT RETURNS int DETERMINISTIC MONOTONIC"); - } - - @Test - public void should_not_quote_body_using_as_with_deterministic_and_monotonic() { - final String funcStr = - createDseFunction("func1") - .withParameter("param1", DataTypes.INT) - .returnsNullOnNull() - .returnsType(DataTypes.TEXT) - .deterministic() - .monotonic() - .withJavaLanguage() - .as("'return Integer.toString(param1);'") - .asCql(); - assertThat(funcStr) - .isEqualTo( - "CREATE FUNCTION func1 (param1 int) RETURNS NULL ON NULL INPUT RETURNS text DETERMINISTIC MONOTONIC LANGUAGE java AS 'return Integer.toString(param1);'"); - } - - @Test - public void - should_quote_with_dollar_signs_on_asQuoted_if_body_contains_single_quote_with_deterministic_and_monotonic() { - final String funcStr = - createDseFunction("func1") - .withParameter("param1", DataTypes.INT) - .returnsNullOnNull() - .returnsType(DataTypes.TEXT) - .deterministic() - .monotonic() - .withJavaScriptLanguage() - .asQuoted("'hello ' + param1;") - .asCql(); - assertThat(funcStr) - .isEqualTo( - "CREATE FUNCTION func1 (param1 int) RETURNS NULL ON NULL INPUT RETURNS text DETERMINISTIC MONOTONIC LANGUAGE javascript AS $$ 'hello ' + param1; $$"); - } - - @Test - public void - should_not_throw_on_toString_for_create_function_with_deterministic_and_monotonic_on() { - final String funcStr = - createDseFunction("func1") - .withParameter("param1", DataTypes.INT) - .withParameter("param2", DataTypes.INT) - .returnsNullOnNull() - .returnsType(DataTypes.INT) - .deterministic() - .monotonicOn("param2") - .toString(); - assertThat(funcStr) - .isEqualTo( - "CREATE FUNCTION func1 (param1 int,param2 int) RETURNS NULL ON NULL INPUT RETURNS int DETERMINISTIC MONOTONIC ON param2"); - } - - @Test - public void should_not_quote_body_using_as_with_deterministic_and_monotonic_on() { - final String funcStr = - createDseFunction("func1") - .withParameter("param1", DataTypes.INT) - .withParameter("param2", DataTypes.INT) - .returnsNullOnNull() - .returnsType(DataTypes.TEXT) - .deterministic() - .monotonicOn("param2") - .withJavaLanguage() - .as("'return Integer.toString(param1);'") - .asCql(); - assertThat(funcStr) - .isEqualTo( - "CREATE FUNCTION func1 (param1 int,param2 int) RETURNS NULL ON NULL INPUT RETURNS text DETERMINISTIC MONOTONIC ON param2 LANGUAGE java AS 'return Integer.toString(param1);'"); - } - - @Test - public void - should_quote_with_dollar_signs_on_asQuoted_if_body_contains_single_quote_with_deterministic_and_monotonic_on() { - final String funcStr = - createDseFunction("func1") - .withParameter("param1", DataTypes.INT) - .withParameter("param2", DataTypes.INT) - .returnsNullOnNull() - .returnsType(DataTypes.TEXT) - .deterministic() - .monotonicOn("param2") - .withJavaScriptLanguage() - .asQuoted("'hello ' + param1;") - .asCql(); - assertThat(funcStr) - .isEqualTo( - "CREATE FUNCTION func1 (param1 int,param2 int) RETURNS NULL ON NULL INPUT RETURNS text DETERMINISTIC MONOTONIC ON param2 LANGUAGE javascript AS $$ 'hello ' + param1; $$"); - } -} diff --git a/test-infra/pom.xml b/test-infra/pom.xml index f4e5d93af34..ef38722861b 100644 --- a/test-infra/pom.xml +++ b/test-infra/pom.xml @@ -48,11 +48,6 @@ com.scylladb java-driver-core - - org.apache.tinkerpop - gremlin-core - provided - com.github.spotbugs spotbugs-annotations diff --git a/test-infra/revapi.json b/test-infra/revapi.json index 293d9f4d142..5553823be7d 100644 --- a/test-infra/revapi.json +++ b/test-infra/revapi.json @@ -5,8 +5,8 @@ "packages": { "regex": true, "exclude": [ - "com\\.datastax\\.(oss|dse)\\.protocol\\.internal(\\..+)?", - "com\\.datastax\\.(oss|dse)\\.driver\\.internal(\\..+)?", + "com\\.datastax\\.oss\\.protocol\\.internal(\\..+)?", + "com\\.datastax\\.oss\\.driver\\.internal(\\..+)?", "com\\.datastax\\.oss\\.driver\\.shaded(\\..+)?", "com\\.datastax\\.oss\\.simulacron(\\..+)?", "org\\.assertj(\\..+)?", @@ -170,26 +170,11 @@ "old": "method void com.datastax.oss.driver.api.testinfra.ccm.CcmRule::reloadCore(int, java.lang.String, java.lang.String, boolean)", "justification": "Modifying the state of a globally shared CCM instance is dangerous" }, - { - "code": "java.method.removed", - "old": "method java.util.Optional com.datastax.oss.driver.api.testinfra.ccm.BaseCcmRule::getDseVersion()", - "justification": "Method has been replaced with more generic isDistributionOf(BackendType) and getDistributionVersion()" - }, - { - "code": "java.field.removed", - "old": "field com.datastax.oss.driver.api.testinfra.ccm.CcmBridge.DSE_ENABLEMENT", - "justification": "Method has been replaced with more generic isDistributionOf(BackendType) and getDistributionVersion()" - }, { "code": "java.method.nowStatic", "old": "method com.datastax.oss.driver.api.core.Version com.datastax.oss.driver.api.testinfra.ccm.CcmBridge::getCassandraVersion()", "new": "method com.datastax.oss.driver.api.core.Version com.datastax.oss.driver.api.testinfra.ccm.CcmBridge::getCassandraVersion()", "justification": "Previous and current implemntation do not relay on non-static fields" - }, - { - "code": "java.method.removed", - "old": "method java.util.Optional com.datastax.oss.driver.api.testinfra.ccm.CcmBridge::getDseVersion()", - "justification": "Method has been replaced with more generic isDistributionOf(BackendType) and getDistributionVersion()" } ] } diff --git a/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/DseRequirement.java b/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/DseRequirement.java deleted file mode 100644 index c1c4249620f..00000000000 --- a/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/DseRequirement.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.oss.driver.api.testinfra; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * Annotation for a Class or Method that defines a DSE Version requirement. If the DSE version in - * use does not meet the version requirement or DSE isn't used at all, the test is skipped. - * - * @deprecated Replaced by {@link - * com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement} - */ -@Deprecated -@Retention(RetentionPolicy.RUNTIME) -public @interface DseRequirement { - - /** @return The minimum version required to execute this test, i.e. "5.0.13" */ - String min() default ""; - - /** - * @return the maximum exclusive version allowed to execute this test, i.e. "2.2" means only tests - * < "2.2" may execute this test. - */ - String max() default ""; - - /** @return The description returned if this version requirement is not met. */ - String description() default "Does not meet version requirement."; -} diff --git a/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/ccm/CcmBridge.java b/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/ccm/CcmBridge.java index e35c8013e35..47b041e4a36 100644 --- a/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/ccm/CcmBridge.java +++ b/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/ccm/CcmBridge.java @@ -77,8 +77,6 @@ public class CcmBridge implements AutoCloseable { public static final String BRANCH = System.getProperty("ccm.branch"); - public static final Boolean DSE_ENABLEMENT = Boolean.getBoolean("ccm.dse"); - public static final Boolean SCYLLA_ENTERPRISE = String.valueOf(VERSION.getMajor()).matches("\\d{4}"); @@ -132,16 +130,7 @@ public class CcmBridge implements AutoCloseable { // @IntegrationTestDisabledCassandra3Failure @IntegrationTestDisabledSSL // = createTempStore(DEFAULT_SERVER_LOCALHOST_KEYSTORE_PATH); - // major DSE versions - public static final Version V6_0_0 = Version.parse("6.0.0"); - public static final Version V5_1_0 = Version.parse("5.1.0"); - public static final Version V5_0_0 = Version.parse("5.0.0"); - - // mapped C* versions from DSE versions - public static final Version V4_0_0 = Version.parse("4.0.0"); - public static final Version V3_10 = Version.parse("3.10"); public static final Version V3_0_15 = Version.parse("3.0.15"); - public static final Version V2_1_19 = Version.parse("2.1.19"); // mapped C* versions from HCD versions public static final Version V4_0_11 = Version.parse("4.0.11"); @@ -180,10 +169,7 @@ public class CcmBridge implements AutoCloseable { private final AtomicBoolean created = new AtomicBoolean(); private final String ipPrefix; private final Map cassandraConfiguration; - private final Map dseConfiguration; - private final List rawDseYaml; private final List createOptions; - private final List dseWorkloads; private final String jvmArgs; private CcmBridge( @@ -191,11 +177,8 @@ private CcmBridge( int[] nodes, String ipPrefix, Map cassandraConfiguration, - Map dseConfiguration, - List dseConfigurationRawYaml, List createOptions, - Collection jvmArgs, - List dseWorkloads) { + Collection jvmArgs) { this.configDirectory = configDirectory; if (nodes.length == 1) { // Hack to ensure that the default DC is always called 'dc1': pass a list ('-nX:0') even if @@ -214,8 +197,6 @@ private CcmBridge( } this.cassandraConfiguration = cassandraConfiguration; - this.dseConfiguration = dseConfiguration; - this.rawDseYaml = dseConfigurationRawYaml; this.createOptions = createOptions; if ((getCassandraVersion().nextStable().compareTo(Version.V4_1_0) >= 0) @@ -236,7 +217,6 @@ private CcmBridge( allJvmArgs.append(quote); } this.jvmArgs = allJvmArgs.toString(); - this.dseWorkloads = dseWorkloads; } // Copied from Netty's PlatformDependent to avoid the dependency on Netty @@ -296,10 +276,6 @@ public Optional getScyllaUnparsedVersion() { : Optional.empty(); } - public Optional getDseVersion() { - return DSE_ENABLEMENT ? Optional.of(VERSION) : Optional.empty(); - } - public static boolean isDistributionOf(BackendType type) { return DISTRIBUTION == type; } @@ -407,19 +383,6 @@ public void create() { if (updateConfArguments.length() > 0) { execute("updateconf", updateConfArguments.toString()); } - - // Note that we aren't performing any substitution on DSE key/value props (at least for now) - if (isDistributionOf(BackendType.DSE)) { - for (Map.Entry conf : dseConfiguration.entrySet()) { - execute("updatedseconf", String.format("%s:%s", conf.getKey(), conf.getValue())); - } - for (String yaml : rawDseYaml) { - executeUnsanitized("updatedseconf", "-y", yaml); - } - if (!dseWorkloads.isEmpty()) { - execute("setworkload", String.join(",", dseWorkloads)); - } - } } } @@ -427,14 +390,6 @@ public void nodetool(int node, String... args) { execute(String.format("node%d nodetool %s", node, Joiner.on(" ").join(args))); } - public void dsetool(int node, String... args) { - execute(String.format("node%d dsetool %s", node, Joiner.on(" ").join(args))); - } - - public void reloadCore(int node, String keyspace, String table, boolean reindex) { - dsetool(node, "reload_core", keyspace + "." + table, "reindex=" + reindex); - } - public void start() { startWithArgs("--wait-for-binary-proto", "--wait-other-notice"); } @@ -685,12 +640,9 @@ public static Builder builder() { public static class Builder { private int[] nodes = {1}; private final Map cassandraConfiguration = new LinkedHashMap<>(); - private final Map dseConfiguration = new LinkedHashMap<>(); - private final List dseRawYaml = new ArrayList<>(); private final List jvmArgs = new ArrayList<>(); private String ipPrefix; private final List createOptions = new ArrayList<>(); - private final List dseWorkloads = new ArrayList<>(); private final Path configDirectory; @@ -712,16 +664,6 @@ public Builder withCassandraConfiguration(String key, Object value) { return this; } - public Builder withDseConfiguration(String key, Object value) { - dseConfiguration.put(key, value); - return this; - } - - public Builder withDseConfiguration(String rawYaml) { - dseRawYaml.add(rawYaml); - return this; - } - public Builder withJvmArgs(String... jvmArgs) { Collections.addAll(this.jvmArgs, jvmArgs); return this; @@ -793,22 +735,9 @@ public Builder withSslAuth() { return this; } - public Builder withDseWorkloads(String... workloads) { - this.dseWorkloads.addAll(Arrays.asList(workloads)); - return this; - } - public CcmBridge build() { return new CcmBridge( - configDirectory, - nodes, - ipPrefix, - cassandraConfiguration, - dseConfiguration, - dseRawYaml, - createOptions, - jvmArgs, - dseWorkloads); + configDirectory, nodes, ipPrefix, cassandraConfiguration, createOptions, jvmArgs); } } diff --git a/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/ccm/CustomCcmRule.java b/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/ccm/CustomCcmRule.java index 5ea1bf7ed3c..2097ec44418 100644 --- a/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/ccm/CustomCcmRule.java +++ b/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/ccm/CustomCcmRule.java @@ -94,21 +94,6 @@ public Builder withCassandraConfiguration(String key, Object value) { return this; } - public Builder withDseConfiguration(String key, Object value) { - bridgeBuilder.withDseConfiguration(key, value); - return this; - } - - public Builder withDseConfiguration(String rawYaml) { - bridgeBuilder.withDseConfiguration(rawYaml); - return this; - } - - public Builder withDseWorkloads(String... workloads) { - bridgeBuilder.withDseWorkloads(workloads); - return this; - } - public Builder withJvmArgs(String... jvmArgs) { bridgeBuilder.withJvmArgs(jvmArgs); return this; diff --git a/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/ccm/DefaultCcmBridgeBuilderCustomizer.java b/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/ccm/DefaultCcmBridgeBuilderCustomizer.java index 6e4f8f5efec..429f02f6d1e 100644 --- a/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/ccm/DefaultCcmBridgeBuilderCustomizer.java +++ b/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/ccm/DefaultCcmBridgeBuilderCustomizer.java @@ -31,12 +31,8 @@ public class DefaultCcmBridgeBuilderCustomizer { public static CcmBridge.Builder configureBuilder(CcmBridge.Builder builder) { - if (!CcmBridge.isDistributionOf( - BackendType.DSE, (dist, cass) -> dist.nextStable().compareTo(Version.V4_0_0) >= 0) - || CcmBridge.isDistributionOf(BackendType.HCD)) { - builder.withCassandraConfiguration("enable_materialized_views", true); - builder.withCassandraConfiguration("enable_sasi_indexes", true); - } + builder.withCassandraConfiguration("enable_materialized_views", true); + builder.withCassandraConfiguration("enable_sasi_indexes", true); if (CcmBridge.getDistributionVersion().nextStable().compareTo(Version.V3_0_0) >= 0) { if (!CcmBridge.isDistributionOf(BackendType.SCYLLA)) { builder.withJvmArgs("-Dcassandra.superuser_setup_delay_ms=0"); diff --git a/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/ccm/DistributionCassandraVersions.java b/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/ccm/DistributionCassandraVersions.java index 1960c2f0ee7..89a8d7cd5ea 100644 --- a/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/ccm/DistributionCassandraVersions.java +++ b/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/ccm/DistributionCassandraVersions.java @@ -29,16 +29,6 @@ public abstract class DistributionCassandraVersions { new HashMap<>(); static { - { - // DSE - ImmutableSortedMap dse = - ImmutableSortedMap.of( - Version.V1_0_0, CcmBridge.V2_1_19, - Version.V5_0_0, CcmBridge.V3_0_15, - CcmBridge.V5_1_0, CcmBridge.V3_10, - CcmBridge.V6_0_0, CcmBridge.V4_0_0); - mappings.put(BackendType.DSE, dse); - } { // HCD ImmutableSortedMap hcd = diff --git a/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/requirement/BackendType.java b/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/requirement/BackendType.java index 735215eeee8..2f4b7c0c18a 100644 --- a/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/requirement/BackendType.java +++ b/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/requirement/BackendType.java @@ -19,7 +19,6 @@ public enum BackendType { CASSANDRA("Apache Cassandra"), - DSE("DSE"), HCD("HCD"), SCYLLA("ScyllaDB"); diff --git a/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/requirement/VersionRequirement.java b/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/requirement/VersionRequirement.java index a176dc28fc9..6dd1c0ce36b 100644 --- a/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/requirement/VersionRequirement.java +++ b/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/requirement/VersionRequirement.java @@ -19,7 +19,6 @@ import com.datastax.oss.driver.api.core.Version; import com.datastax.oss.driver.api.testinfra.CassandraRequirement; -import com.datastax.oss.driver.api.testinfra.DseRequirement; import com.datastax.oss.driver.api.testinfra.ScyllaRequirement; import com.datastax.oss.driver.api.testinfra.ScyllaSkip; import java.util.ArrayList; @@ -31,7 +30,7 @@ /** * Used to unify the requirements specified by - * annotations @CassandraRequirement, @DseRequirment, @BackendRequirement + * annotations @CassandraRequirement, @ScyllaRequirement, @BackendRequirement */ public class VersionRequirement { final BackendType backendType; @@ -94,11 +93,6 @@ public static VersionRequirement fromCassandraRequirement(CassandraRequirement r BackendType.CASSANDRA, requirement.min(), requirement.max(), requirement.description()); } - public static VersionRequirement fromDseRequirement(DseRequirement requirement) { - return new VersionRequirement( - BackendType.DSE, requirement.min(), requirement.max(), requirement.description()); - } - public static VersionRequirement fromScyllaOssRequirement(ScyllaRequirement requirement) { return new VersionRequirement( BackendType.SCYLLA, @@ -119,7 +113,6 @@ public static Collection fromAnnotations(Description descrip // collect all requirement annotation types CassandraRequirement cassandraRequirement = description.getAnnotation(CassandraRequirement.class); - DseRequirement dseRequirement = description.getAnnotation(DseRequirement.class); ScyllaRequirement scyllaRequirement = description.getAnnotation(ScyllaRequirement.class); // matches methods/classes with one @BackendRequirement annotation BackendRequirement backendRequirement = description.getAnnotation(BackendRequirement.class); @@ -132,9 +125,6 @@ public static Collection fromAnnotations(Description descrip if (cassandraRequirement != null) { requirements.add(VersionRequirement.fromCassandraRequirement(cassandraRequirement)); } - if (dseRequirement != null) { - requirements.add(VersionRequirement.fromDseRequirement(dseRequirement)); - } if (scyllaSkip != null) { requirements.add( new VersionRequirement(BackendType.SCYLLA, "0.0.0", "1.0.0", scyllaSkip.description())); diff --git a/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/session/CqlSessionRuleBuilder.java b/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/session/CqlSessionRuleBuilder.java index 8f392dca0bf..e529a00b6b2 100644 --- a/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/session/CqlSessionRuleBuilder.java +++ b/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/session/CqlSessionRuleBuilder.java @@ -17,84 +17,21 @@ */ package com.datastax.oss.driver.api.testinfra.session; -import static org.assertj.core.api.Assertions.assertThat; - -import com.datastax.dse.driver.api.core.config.DseDriverOption; import com.datastax.oss.driver.api.core.CqlSession; import com.datastax.oss.driver.api.core.config.DriverConfigLoader; import com.datastax.oss.driver.api.testinfra.CassandraResourceRule; import com.datastax.oss.driver.internal.core.config.typesafe.DefaultDriverConfigLoader; -import com.typesafe.config.Config; -import com.typesafe.config.ConfigValueFactory; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Supplier; public class CqlSessionRuleBuilder extends SessionRuleBuilder { - private static final AtomicInteger GRAPH_NAME_INDEX = new AtomicInteger(); - public CqlSessionRuleBuilder(CassandraResourceRule cassandraResource) { super(cassandraResource); } @Override public SessionRule build() { - - final String graphName; - final DriverConfigLoader actualLoader; - - Supplier actualSupplier; - - if (createGraph) { - graphName = "dsedrivertests_" + GRAPH_NAME_INDEX.getAndIncrement(); - - // Inject the generated graph name in the provided configuration, so that the test doesn't - // need to set it explicitly on every statement. - if (loader == null) { - // This would normally be handled in DseSessionBuilder, do it early because we need it now - loader = new DefaultDriverConfigLoader(); - } else { - // To keep this relatively simple we assume that if the config loader was provided in a - // test, it is the Typesafe-config based one. This is always true in our integration tests. - assertThat(loader).isInstanceOf(DefaultDriverConfigLoader.class); - } - Supplier originalSupplier = ((DefaultDriverConfigLoader) loader).getConfigSupplier(); - actualSupplier = - () -> - originalSupplier - .get() - .withValue( - DseDriverOption.GRAPH_NAME.getPath(), - ConfigValueFactory.fromAnyRef(graphName)); - } else { - graphName = null; - if (loader == null) { - loader = new DefaultDriverConfigLoader(); - } - - actualSupplier = ((DefaultDriverConfigLoader) loader).getConfigSupplier(); - } - - actualLoader = - new DefaultDriverConfigLoader( - () -> - graphProtocol != null - ? actualSupplier - .get() - .withValue( - DseDriverOption.GRAPH_SUB_PROTOCOL.getPath(), - ConfigValueFactory.fromAnyRef(graphProtocol)) - // will use the protocol from the config file (in application.conf if - // defined or in reference.conf) - : actualSupplier.get()); - + DriverConfigLoader actualLoader = loader == null ? new DefaultDriverConfigLoader() : loader; return new SessionRule<>( - cassandraResource, - createKeyspace, - nodeStateListener, - schemaChangeListener, - actualLoader, - graphName, - isCoreGraph); + cassandraResource, createKeyspace, nodeStateListener, schemaChangeListener, actualLoader); } } diff --git a/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/session/SessionRule.java b/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/session/SessionRule.java index 3b792374769..67072e29965 100644 --- a/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/session/SessionRule.java +++ b/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/session/SessionRule.java @@ -17,9 +17,7 @@ */ package com.datastax.oss.driver.api.testinfra.session; -import com.datastax.dse.driver.api.core.graph.ScriptGraphStatement; import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.Version; import com.datastax.oss.driver.api.core.config.DriverConfigLoader; import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; import com.datastax.oss.driver.api.core.cql.SimpleStatement; @@ -28,12 +26,8 @@ import com.datastax.oss.driver.api.core.metadata.schema.SchemaChangeListener; import com.datastax.oss.driver.api.core.session.Session; import com.datastax.oss.driver.api.testinfra.CassandraResourceRule; -import com.datastax.oss.driver.api.testinfra.ccm.BaseCcmRule; -import com.datastax.oss.driver.api.testinfra.ccm.CcmBridge; import com.datastax.oss.driver.api.testinfra.ccm.SchemaChangeSynchronizer; -import com.datastax.oss.driver.api.testinfra.requirement.BackendType; import com.datastax.oss.driver.api.testinfra.simulacron.SimulacronRule; -import java.util.Objects; import org.junit.rules.ExternalResource; /** @@ -63,16 +57,12 @@ */ public class SessionRule extends ExternalResource { - private static final Version V6_8_0 = Objects.requireNonNull(Version.parse("6.8.0")); - // the CCM or Simulacron rule to depend on private final CassandraResourceRule cassandraResource; private final NodeStateListener nodeStateListener; private final SchemaChangeListener schemaChangeListener; private final CqlIdentifier keyspace; private final DriverConfigLoader configLoader; - private final String graphName; - private final boolean isCoreGraph; // the session that is auto created for this rule and is tied to the given keyspace. private SessionT session; @@ -94,9 +84,7 @@ public SessionRule( boolean createKeyspace, NodeStateListener nodeStateListener, SchemaChangeListener schemaChangeListener, - DriverConfigLoader configLoader, - String graphName, - boolean isCoreGraph) { + DriverConfigLoader configLoader) { this.cassandraResource = cassandraResource; this.nodeStateListener = nodeStateListener; this.schemaChangeListener = schemaChangeListener; @@ -105,41 +93,6 @@ public SessionRule( ? null : SessionUtils.uniqueKeyspaceId(); this.configLoader = configLoader; - this.graphName = graphName; - this.isCoreGraph = isCoreGraph; - } - - public SessionRule( - CassandraResourceRule cassandraResource, - boolean createKeyspace, - NodeStateListener nodeStateListener, - SchemaChangeListener schemaChangeListener, - DriverConfigLoader configLoader, - String graphName) { - this( - cassandraResource, - createKeyspace, - nodeStateListener, - schemaChangeListener, - configLoader, - graphName, - false); - } - - public SessionRule( - CassandraResourceRule cassandraResource, - boolean createKeyspace, - NodeStateListener nodeStateListener, - SchemaChangeListener schemaChangeListener, - DriverConfigLoader configLoader) { - this( - cassandraResource, - createKeyspace, - nodeStateListener, - schemaChangeListener, - configLoader, - null, - false); } @Override @@ -154,46 +107,10 @@ protected void before() { SimpleStatement.newInstance(String.format("USE %s", keyspace.asCql(false))), Statement.SYNC); } - if (graphName != null) { - BaseCcmRule rule = - (cassandraResource instanceof BaseCcmRule) ? ((BaseCcmRule) cassandraResource) : null; - if (rule == null || !CcmBridge.isDistributionOf(BackendType.DSE)) { - throw new IllegalArgumentException("DseSessionRule should work with DSE."); - } - if (rule.getDistributionVersion().compareTo(V6_8_0) >= 0) { - session() - .execute( - ScriptGraphStatement.newInstance( - String.format( - "system.graph('%s').ifNotExists()%s.create()", - this.graphName, isCoreGraph ? ".coreEngine()" : ".classicEngine()")) - .setSystemQuery(true), - ScriptGraphStatement.SYNC); - } else { - if (isCoreGraph) { - throw new IllegalArgumentException( - "Core graph is not supported for DSE version < " + V6_8_0); - } - session() - .execute( - ScriptGraphStatement.newInstance( - String.format("system.graph('%s').ifNotExists().create()", this.graphName)) - .setSystemQuery(true), - ScriptGraphStatement.SYNC); - } - } } @Override protected void after() { - if (graphName != null) { - session() - .execute( - ScriptGraphStatement.newInstance( - String.format("system.graph('%s').drop()", this.graphName)) - .setSystemQuery(true), - ScriptGraphStatement.SYNC); - } if (keyspace != null) { SchemaChangeSynchronizer.withLock( () -> { @@ -217,10 +134,6 @@ public CqlIdentifier keyspace() { return keyspace; } - public String getGraphName() { - return graphName; - } - /** @return a config profile where the request timeout is 30 seconds. * */ public DriverExecutionProfile slowProfile() { return slowProfile; diff --git a/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/session/SessionRuleBuilder.java b/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/session/SessionRuleBuilder.java index 62c5babbf1d..b143ff4c7e9 100644 --- a/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/session/SessionRuleBuilder.java +++ b/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/session/SessionRuleBuilder.java @@ -33,9 +33,6 @@ public abstract class SessionRuleBuilder< protected NodeStateListener nodeStateListener; protected SchemaChangeListener schemaChangeListener; protected DriverConfigLoader loader; - protected boolean createGraph; - protected boolean isCoreGraph; - protected String graphProtocol; @SuppressWarnings("unchecked") protected final SelfT self = (SelfT) this; @@ -79,30 +76,5 @@ public SelfT withSchemaChangeListener(SchemaChangeListener listener) { return self; } - /** - * Configures the rule to create a new graph instance. - * - *

This assumes that the associated {@link CassandraResourceRule} is a DSE instance with the - * graph workload enabled. - * - *

The name of the graph will be injected in the session's configuration, so that all graph - * statements are automatically routed to it. It's also exposed via {@link - * SessionRule#getGraphName()}. - */ - public SelfT withCreateGraph() { - this.createGraph = true; - return self; - } - - public SelfT withCoreEngine() { - this.isCoreGraph = true; - return self; - } - - public SelfT withGraphProtocol(String graphProtocol) { - this.graphProtocol = graphProtocol; - return self; - } - public abstract SessionRule build(); } diff --git a/test-infra/src/main/java/com/datastax/oss/driver/internal/gremlin/PatchedGremlinDslProcessor.java b/test-infra/src/main/java/com/datastax/oss/driver/internal/gremlin/PatchedGremlinDslProcessor.java deleted file mode 100644 index e8639b2d396..00000000000 --- a/test-infra/src/main/java/com/datastax/oss/driver/internal/gremlin/PatchedGremlinDslProcessor.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.oss.driver.internal.gremlin; - -import java.util.Collections; -import java.util.Set; -import javax.annotation.processing.SupportedAnnotationTypes; -import javax.lang.model.SourceVersion; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.GremlinDslProcessor; - -@SupportedAnnotationTypes("org.apache.tinkerpop.gremlin.process.traversal.dsl.GremlinDsl") -public class PatchedGremlinDslProcessor extends GremlinDslProcessor { - - @Override - public Set getSupportedAnnotationTypes() { - return Collections.singleton("org.apache.tinkerpop.gremlin.process.traversal.dsl.GremlinDsl"); - } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latestSupported(); - } -} diff --git a/test-infra/src/test/java/com/datastax/oss/driver/api/testinfra/requirement/VersionRequirementTest.java b/test-infra/src/test/java/com/datastax/oss/driver/api/testinfra/requirement/VersionRequirementTest.java index ccddb18c80f..71933ac6c52 100644 --- a/test-infra/src/test/java/com/datastax/oss/driver/api/testinfra/requirement/VersionRequirementTest.java +++ b/test-infra/src/test/java/com/datastax/oss/driver/api/testinfra/requirement/VersionRequirementTest.java @@ -28,7 +28,7 @@ public class VersionRequirementTest { // backend aliases private static BackendType CASSANDRA = BackendType.CASSANDRA; - private static BackendType DSE = BackendType.DSE; + private static BackendType SCYLLA = BackendType.SCYLLA; // version numbers private static Version V_0_0_0 = Version.parse("0.0.0"); @@ -54,7 +54,7 @@ public class VersionRequirementTest { new VersionRequirement(CASSANDRA, "1.1.0", "", ""); private static VersionRequirement CASSANDRA_FROM_3_0_0_TO_3_1_0 = new VersionRequirement(CASSANDRA, "3.0.0", "3.1.0", ""); - private static VersionRequirement DSE_ANY = new VersionRequirement(DSE, "", "", ""); + private static VersionRequirement SCYLLA_ANY = new VersionRequirement(SCYLLA, "", "", ""); @Test public void empty_requirements() { @@ -62,24 +62,24 @@ public void empty_requirements() { assertThat(VersionRequirement.meetsAny(req, CASSANDRA, V_0_0_0)).isTrue(); assertThat(VersionRequirement.meetsAny(req, CASSANDRA, V_1_0_0)).isTrue(); - assertThat(VersionRequirement.meetsAny(req, DSE, V_0_0_0)).isTrue(); - assertThat(VersionRequirement.meetsAny(req, DSE, V_1_0_0)).isTrue(); + assertThat(VersionRequirement.meetsAny(req, SCYLLA, V_0_0_0)).isTrue(); + assertThat(VersionRequirement.meetsAny(req, SCYLLA, V_1_0_0)).isTrue(); } @Test public void single_requirement_any_version() { List anyCassandra = Collections.singletonList(CASSANDRA_ANY); - List anyDse = Collections.singletonList(DSE_ANY); + List anyScylla = Collections.singletonList(SCYLLA_ANY); assertThat(VersionRequirement.meetsAny(anyCassandra, CASSANDRA, V_0_0_0)).isTrue(); assertThat(VersionRequirement.meetsAny(anyCassandra, CASSANDRA, V_1_0_0)).isTrue(); - assertThat(VersionRequirement.meetsAny(anyDse, DSE, V_0_0_0)).isTrue(); - assertThat(VersionRequirement.meetsAny(anyDse, DSE, V_1_0_0)).isTrue(); + assertThat(VersionRequirement.meetsAny(anyScylla, SCYLLA, V_0_0_0)).isTrue(); + assertThat(VersionRequirement.meetsAny(anyScylla, SCYLLA, V_1_0_0)).isTrue(); - assertThat(VersionRequirement.meetsAny(anyDse, CASSANDRA, V_0_0_0)).isFalse(); - assertThat(VersionRequirement.meetsAny(anyDse, CASSANDRA, V_1_0_0)).isFalse(); - assertThat(VersionRequirement.meetsAny(anyCassandra, DSE, V_0_0_0)).isFalse(); - assertThat(VersionRequirement.meetsAny(anyCassandra, DSE, V_1_0_0)).isFalse(); + assertThat(VersionRequirement.meetsAny(anyScylla, CASSANDRA, V_0_0_0)).isFalse(); + assertThat(VersionRequirement.meetsAny(anyScylla, CASSANDRA, V_1_0_0)).isFalse(); + assertThat(VersionRequirement.meetsAny(anyCassandra, SCYLLA, V_0_0_0)).isFalse(); + assertThat(VersionRequirement.meetsAny(anyCassandra, SCYLLA, V_1_0_0)).isFalse(); } @Test @@ -91,7 +91,7 @@ public void single_requirement_min_only() { assertThat(VersionRequirement.meetsAny(req, CASSANDRA, V_1_1_0)).isTrue(); assertThat(VersionRequirement.meetsAny(req, CASSANDRA, V_2_0_0)).isTrue(); - assertThat(VersionRequirement.meetsAny(req, DSE, V_1_0_0)).isFalse(); + assertThat(VersionRequirement.meetsAny(req, SCYLLA, V_1_0_0)).isFalse(); assertThat(VersionRequirement.meetsAny(req, CASSANDRA, V_0_0_0)).isFalse(); assertThat(VersionRequirement.meetsAny(req, CASSANDRA, V_0_1_0)).isFalse(); } @@ -103,7 +103,7 @@ public void single_requirement_max_only() { assertThat(VersionRequirement.meetsAny(req, CASSANDRA, V_0_0_0)).isTrue(); assertThat(VersionRequirement.meetsAny(req, CASSANDRA, V_0_1_0)).isTrue(); - assertThat(VersionRequirement.meetsAny(req, DSE, V_0_0_0)).isFalse(); + assertThat(VersionRequirement.meetsAny(req, SCYLLA, V_0_0_0)).isFalse(); assertThat(VersionRequirement.meetsAny(req, CASSANDRA, V_1_0_0)).isFalse(); assertThat(VersionRequirement.meetsAny(req, CASSANDRA, V_1_0_1)).isFalse(); } @@ -116,7 +116,7 @@ public void single_requirement_min_and_max() { assertThat(VersionRequirement.meetsAny(req, CASSANDRA, V_1_0_1)).isTrue(); assertThat(VersionRequirement.meetsAny(req, CASSANDRA, V_1_1_0)).isTrue(); - assertThat(VersionRequirement.meetsAny(req, DSE, V_1_0_0)).isFalse(); + assertThat(VersionRequirement.meetsAny(req, SCYLLA, V_1_0_0)).isFalse(); assertThat(VersionRequirement.meetsAny(req, CASSANDRA, V_0_0_0)).isFalse(); assertThat(VersionRequirement.meetsAny(req, CASSANDRA, V_0_1_0)).isFalse(); assertThat(VersionRequirement.meetsAny(req, CASSANDRA, V_2_0_0)).isFalse(); @@ -125,20 +125,20 @@ public void single_requirement_min_and_max() { @Test public void multi_requirement_any_version() { - List req = ImmutableList.of(CASSANDRA_ANY, DSE_ANY); + List req = ImmutableList.of(CASSANDRA_ANY, SCYLLA_ANY); assertThat(VersionRequirement.meetsAny(req, CASSANDRA, V_1_0_0)).isTrue(); - assertThat(VersionRequirement.meetsAny(req, DSE, V_1_0_0)).isTrue(); + assertThat(VersionRequirement.meetsAny(req, SCYLLA, V_1_0_0)).isTrue(); } @Test public void multi_db_requirement_min_one_any_other() { - List req = ImmutableList.of(CASSANDRA_FROM_1_0_0, DSE_ANY); + List req = ImmutableList.of(CASSANDRA_FROM_1_0_0, SCYLLA_ANY); assertThat(VersionRequirement.meetsAny(req, CASSANDRA, V_1_0_0)).isTrue(); assertThat(VersionRequirement.meetsAny(req, CASSANDRA, V_2_0_0)).isTrue(); - assertThat(VersionRequirement.meetsAny(req, DSE, V_0_0_0)).isTrue(); - assertThat(VersionRequirement.meetsAny(req, DSE, V_1_0_0)).isTrue(); + assertThat(VersionRequirement.meetsAny(req, SCYLLA, V_0_0_0)).isTrue(); + assertThat(VersionRequirement.meetsAny(req, SCYLLA, V_1_0_0)).isTrue(); assertThat(VersionRequirement.meetsAny(req, CASSANDRA, V_0_0_0)).isFalse(); } @@ -152,7 +152,7 @@ public void multi_requirement_two_ranges() { assertThat(VersionRequirement.meetsAny(req, CASSANDRA, V_1_1_0)).isTrue(); assertThat(VersionRequirement.meetsAny(req, CASSANDRA, V_3_0_0)).isTrue(); - assertThat(VersionRequirement.meetsAny(req, DSE, V_1_0_0)).isFalse(); + assertThat(VersionRequirement.meetsAny(req, SCYLLA, V_1_0_0)).isFalse(); assertThat(VersionRequirement.meetsAny(req, CASSANDRA, V_0_0_0)).isFalse(); assertThat(VersionRequirement.meetsAny(req, CASSANDRA, V_2_0_0)).isFalse(); assertThat(VersionRequirement.meetsAny(req, CASSANDRA, V_3_1_0)).isFalse(); @@ -168,7 +168,7 @@ public void multi_requirement_overlapping() { assertThat(VersionRequirement.meetsAny(req, CASSANDRA, V_1_1_0)).isTrue(); assertThat(VersionRequirement.meetsAny(req, CASSANDRA, V_2_0_0)).isTrue(); - assertThat(VersionRequirement.meetsAny(req, DSE, V_1_0_0)).isFalse(); + assertThat(VersionRequirement.meetsAny(req, SCYLLA, V_1_0_0)).isFalse(); assertThat(VersionRequirement.meetsAny(req, CASSANDRA, V_0_0_0)).isFalse(); } diff --git a/upgrade_guide/README.md b/upgrade_guide/README.md index 8c4bf110560..817787c42a1 100644 --- a/upgrade_guide/README.md +++ b/upgrade_guide/README.md @@ -19,6 +19,19 @@ under the License. ## Upgrade guide +### 4.19.2.2 + +#### DataStax-only APIs removed + +This release removes the untested Astra, Insights, and DSE feature surface. Applications should use +`CqlSession`, `DriverConfigLoader`, `DefaultDriverOption`, and the standard load-balancing and +authentication implementations directly. DSE protocol versions, continuous paging, Graph, +geometry/DateRange types, metadata extensions, and query-builder extensions are no longer present. + +Reactive CQL and mapper APIs are retained. Their public types remain under the historical +`com.datastax.dse` namespace for compatibility, but they are generic and supported with Cassandra +and Scylla. + ### 4.19.2.1 #### The driver reports a session identifier, and its configuration, at connection time @@ -510,37 +523,6 @@ token map for these keyspaces, you now must modify the following configuration o [Metadata.getKeyspaces()]: https://docs.datastax.com/en/drivers/java/4.11/com/datastax/oss/driver/api/core/metadata/Metadata.html#getKeyspaces-- [TokenMap]: https://docs.datastax.com/en/drivers/java/4.11/com/datastax/oss/driver/api/core/metadata/TokenMap.html -#### DSE Graph dependencies are now optional - -Until driver 4.9.0, the driver declared a mandatory dependency to Apache TinkerPop, a library -required only when connecting to DSE Graph. The vast majority of Apache Cassandra users did not need -that library, but were paying the price of having that heavy-weight library in their application's -classpath. - -_Starting with driver 4.10.0, TinkerPop is now considered an optional dependency_. - -Regular users of Apache Cassandra that do not use DSE Graph will not notice any disruption. - -DSE Graph users, however, will now have to explicitly declare a dependency to Apache TinkerPop. This -can be achieved with Maven by adding the following dependencies to the `` section of -your POM file: - -```xml - - org.apache.tinkerpop - gremlin-core - ${tinkerpop.version} - - - org.apache.tinkerpop - tinkergraph-gremlin - ${tinkerpop.version} - -``` - -See the [integration](../manual/core/integration/#tinker-pop) section in the manual for more details -as well as a driver vs. TinkerPop version compatibility matrix. - ### 4.5.x - 4.6.0 These versions are subject to [JAVA-2676](https://datastax-oss.atlassian.net/browse/JAVA-2676), a @@ -557,13 +539,9 @@ separate DSE driver. The great news is that [reactive execution](../manual/core/reactive/) is now available for everyone. See the `CqlSession.executeReactive` methods. -Apart from that, the only visible change is that DSE-specific features are now exposed in the API: - -* new execution methods: `CqlSession.executeGraph`, `CqlSession.executeContinuously*`. They all - have default implementations so this doesn't break binary compatibility. You can just ignore them. -* new driver dependencies: TinkerPop, ESRI, Reactive Streams. If you want to keep your classpath - lean, you can exclude some dependencies when you don't use the corresponding DSE features; see the - [Integration>Driver dependencies](../manual/core/integration/#driver-dependencies) section. +The main visible change is the Reactive Streams dependency. If you want to keep your classpath +lean, you can exclude it when you don't use reactive execution; see the +[Integration>Driver dependencies](../manual/core/integration/#driver-dependencies) section. #### For DataStax Enterprise users diff --git a/upgrade_guide/from_3x/README.md b/upgrade_guide/from_3x/README.md index c9b0d7a297c..c74f105083b 100644 --- a/upgrade_guide/from_3x/README.md +++ b/upgrade_guide/from_3x/README.md @@ -462,6 +462,6 @@ queries (`execute(Statement)`, `prepare(String)`, etc). However, the request execution logic is completely pluggable, and supports arbitrary request types (as long as you write the boilerplate to convert them to protocol messages). -We use that in our DSE driver to implement a reactive API and support for DSE graph. You can also -take advantage of it to plug your own request types (if you're interested, take a look at +The driver uses this extension point for reactive CQL execution. You can also take advantage of it +to plug your own request types (if you're interested, take a look at `RequestProcessor` in the internal API).