Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions core/revapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -7383,6 +7383,11 @@
"old": "method <T extends java.lang.Number> com.datastax.oss.driver.api.core.type.reflect.GenericType<com.datastax.oss.driver.api.core.data.CqlVector<T>> com.datastax.oss.driver.api.core.type.reflect.GenericType<T>::vectorOf(java.lang.Class<T>)",
"new": "method <T> com.datastax.oss.driver.api.core.type.reflect.GenericType<com.datastax.oss.driver.api.core.data.CqlVector<T>> com.datastax.oss.driver.api.core.type.reflect.GenericType<T>::vectorOf(java.lang.Class<T>)",
"justification": "JAVA-3143: Extend driver vector support to arbitrary subtypes and fix handling of variable length types (OSS C* 5.0)"
},
{
"code": "java.method.addedToInterface",
"new": "method java.util.Optional<com.datastax.oss.driver.api.core.tracker.RequestIdGenerator> com.datastax.oss.driver.api.core.context.DriverContext::getRequestIdGenerator()",
"justification": "CASSJAVA-97: Let users inject an ID for each request and write to the custom payload"
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1073,7 +1073,60 @@ public enum DefaultDriverOption implements DriverOption {
* <p>Value-type: string
*/
LOAD_BALANCING_DEFAULT_LWT_REQUEST_ROUTING_METHOD(
"advanced.load-balancing-policy.default-lwt-request-routing-method");
"advanced.load-balancing-policy.default-lwt-request-routing-method"),
/**
* The class of session-wide component that generates request IDs.
*
* <p>Value-type: {@link String}
*/
REQUEST_ID_GENERATOR_CLASS("advanced.request-id.generator.class"),
/**
* An address to always translate all node addresses to that same proxy hostname no matter what IP
* address a node has, but still using its native transport port.
*
* <p>Value-Type: {@link String}
*/
ADDRESS_TRANSLATOR_ADVERTISED_HOSTNAME("advanced.address-translator.advertised-hostname"),
/**
* A map of Cassandra node subnets (CIDR notations) to target addresses, for example (note quoted
* keys):
*
* <pre>
* advanced.address-translator.subnet-addresses {
* "100.64.0.0/15" = "cassandra.datacenter1.com:9042"
* "100.66.0.0/15" = "cassandra.datacenter2.com:9042"
* # IPv6 example:
* # "::ffff:6440:0/111" = "cassandra.datacenter1.com:9042"
* # "::ffff:6442:0/111" = "cassandra.datacenter2.com:9042"
* }
* </pre>
*
* Note: subnets must be represented as prefix blocks, see {@code
* inet.ipaddr.Address#isPrefixBlock()}.
*
* <p>Value type: {@link java.util.Map Map}&#60;{@link String},{@link String}&#62;
*/
ADDRESS_TRANSLATOR_SUBNET_ADDRESSES("advanced.address-translator.subnet-addresses"),
/**
* A default address to fallback to if Cassandra node IP isn't contained in any of the configured
* subnets.
*
* <p>Value-Type: {@link String}
*/
ADDRESS_TRANSLATOR_DEFAULT_ADDRESS("advanced.address-translator.default-address"),
/**
* Whether to resolve the addresses on initialization (if true) or on each node (re-)connection
* (if false). Defaults to false.
*
* <p>Value-Type: boolean
*/
ADDRESS_TRANSLATOR_RESOLVE_ADDRESSES("advanced.address-translator.resolve-addresses"),
/**
* Whether or not to do a DNS reverse-lookup of provided server addresses for SAN addresses.
*
* <p>Value-type: boolean
*/
SSL_ALLOW_DNS_REVERSE_LOOKUP_SAN("advanced.ssl-engine-factory.allow-dns-reverse-lookup-san");

private final String path;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,10 @@ public String toString() {
*/
public static final TypedDriverOption<Boolean> SSL_HOSTNAME_VALIDATION =
new TypedDriverOption<>(DefaultDriverOption.SSL_HOSTNAME_VALIDATION, GenericType.BOOLEAN);

public static final TypedDriverOption<Boolean> SSL_ALLOW_DNS_REVERSE_LOOKUP_SAN =
new TypedDriverOption<>(
DefaultDriverOption.SSL_ALLOW_DNS_REVERSE_LOOKUP_SAN, GenericType.BOOLEAN);
/** The location of the keystore file. */
public static final TypedDriverOption<String> SSL_KEYSTORE_PATH =
new TypedDriverOption<>(DefaultDriverOption.SSL_KEYSTORE_PATH, GenericType.STRING);
Expand Down Expand Up @@ -296,6 +300,10 @@ public String toString() {
new TypedDriverOption<>(
DefaultDriverOption.REQUEST_TRACKER_CLASSES, GenericType.listOf(String.class));

/** The class of a session-wide component that generates request IDs. */
public static final TypedDriverOption<String> REQUEST_ID_GENERATOR_CLASS =
new TypedDriverOption<>(DefaultDriverOption.REQUEST_ID_GENERATOR_CLASS, GenericType.STRING);

/** Whether to log successful requests. */
public static final TypedDriverOption<Boolean> REQUEST_LOGGER_SUCCESS_ENABLED =
new TypedDriverOption<>(
Expand Down Expand Up @@ -923,6 +931,20 @@ public String toString() {
DefaultDriverOption.LOAD_BALANCING_DC_FAILOVER_ALLOW_FOR_LOCAL_CONSISTENCY_LEVELS,
GenericType.BOOLEAN);

public static final TypedDriverOption<String> ADDRESS_TRANSLATOR_ADVERTISED_HOSTNAME =
new TypedDriverOption<>(
DefaultDriverOption.ADDRESS_TRANSLATOR_ADVERTISED_HOSTNAME, GenericType.STRING);
public static final TypedDriverOption<Map<String, String>> ADDRESS_TRANSLATOR_SUBNET_ADDRESSES =
new TypedDriverOption<>(
DefaultDriverOption.ADDRESS_TRANSLATOR_SUBNET_ADDRESSES,
GenericType.mapOf(GenericType.STRING, GenericType.STRING));
public static final TypedDriverOption<String> ADDRESS_TRANSLATOR_DEFAULT_ADDRESS =
new TypedDriverOption<>(
DefaultDriverOption.ADDRESS_TRANSLATOR_DEFAULT_ADDRESS, GenericType.STRING);
public static final TypedDriverOption<Boolean> ADDRESS_TRANSLATOR_RESOLVE_ADDRESSES =
new TypedDriverOption<>(
DefaultDriverOption.ADDRESS_TRANSLATOR_RESOLVE_ADDRESSES, GenericType.BOOLEAN);

/**
* Ordered preference list of remote dcs optionally supplied for automatic failover and included
* in query plan. This feature is enabled only when max-nodes-per-remote-dc is greater than 0.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import com.datastax.oss.driver.api.core.specex.SpeculativeExecutionPolicy;
import com.datastax.oss.driver.api.core.ssl.SslEngineFactory;
import com.datastax.oss.driver.api.core.time.TimestampGenerator;
import com.datastax.oss.driver.api.core.tracker.RequestIdGenerator;
import com.datastax.oss.driver.api.core.tracker.RequestTracker;
import edu.umd.cs.findbugs.annotations.NonNull;
import java.util.Map;
Expand Down Expand Up @@ -139,6 +140,10 @@ default SpeculativeExecutionPolicy getSpeculativeExecutionPolicy(@NonNull String
@NonNull
RequestTracker getRequestTracker();

/** @return The driver's request ID generator; never {@code null}. */
@NonNull
Optional<RequestIdGenerator> getRequestIdGenerator();

/** @return The driver's request throttler; never {@code null}. */
@NonNull
RequestThrottler getRequestThrottler();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.datastax.oss.driver.api.core.tracker.RequestTracker;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;
import java.util.Collections;
import java.util.Map;
import java.util.Optional;
import java.util.Queue;
Expand Down Expand Up @@ -76,6 +77,12 @@ default Optional<RequestTracker> getRequestTracker() {
*/
void init(@NonNull Map<UUID, Node> nodes, @NonNull DistanceReporter distanceReporter);

/** Returns map containing details that impact C* node connectivity. */
@NonNull
default Map<String, ?> getStartupConfiguration() {
return Collections.emptyMap();
}

/**
* Returns the coordinators to use for a new query.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.datastax.oss.driver.api.core.metadata.NodeStateListener;
import com.datastax.oss.driver.api.core.metadata.schema.SchemaChangeListener;
import com.datastax.oss.driver.api.core.ssl.SslEngineFactory;
import com.datastax.oss.driver.api.core.tracker.RequestIdGenerator;
import com.datastax.oss.driver.api.core.tracker.RequestTracker;
import com.datastax.oss.driver.api.core.type.codec.TypeCodec;
import com.datastax.oss.driver.api.core.type.codec.registry.MutableCodecRegistry;
Expand Down Expand Up @@ -59,6 +60,7 @@ public static Builder builder() {
private final NodeStateListener nodeStateListener;
private final SchemaChangeListener schemaChangeListener;
private final RequestTracker requestTracker;
private final RequestIdGenerator requestIdGenerator;
private final Map<String, String> localDatacenters;
private final Map<String, Predicate<Node>> nodeFilters;
private final Map<String, NodeDistanceEvaluator> nodeDistanceEvaluators;
Expand All @@ -77,6 +79,7 @@ private ProgrammaticArguments(
@Nullable NodeStateListener nodeStateListener,
@Nullable SchemaChangeListener schemaChangeListener,
@Nullable RequestTracker requestTracker,
@Nullable RequestIdGenerator requestIdGenerator,
@NonNull Map<String, String> localDatacenters,
@NonNull Map<String, Predicate<Node>> nodeFilters,
@NonNull Map<String, NodeDistanceEvaluator> nodeDistanceEvaluators,
Expand All @@ -94,6 +97,7 @@ private ProgrammaticArguments(
this.nodeStateListener = nodeStateListener;
this.schemaChangeListener = schemaChangeListener;
this.requestTracker = requestTracker;
this.requestIdGenerator = requestIdGenerator;
this.localDatacenters = localDatacenters;
this.nodeFilters = nodeFilters;
this.nodeDistanceEvaluators = nodeDistanceEvaluators;
Expand Down Expand Up @@ -128,6 +132,11 @@ public RequestTracker getRequestTracker() {
return requestTracker;
}

@Nullable
public RequestIdGenerator getRequestIdGenerator() {
return requestIdGenerator;
}

@NonNull
public Map<String, String> getLocalDatacenters() {
return localDatacenters;
Expand Down Expand Up @@ -196,6 +205,7 @@ public static class Builder {
private NodeStateListener nodeStateListener;
private SchemaChangeListener schemaChangeListener;
private RequestTracker requestTracker;
private RequestIdGenerator requestIdGenerator;
private ImmutableMap.Builder<String, String> localDatacentersBuilder = ImmutableMap.builder();
private final ImmutableMap.Builder<String, Predicate<Node>> nodeFiltersBuilder =
ImmutableMap.builder();
Expand Down Expand Up @@ -294,6 +304,12 @@ public Builder addRequestTracker(@NonNull RequestTracker requestTracker) {
return this;
}

@NonNull
public Builder withRequestIdGenerator(@Nullable RequestIdGenerator requestIdGenerator) {
this.requestIdGenerator = requestIdGenerator;
return this;
}

@NonNull
public Builder withLocalDatacenter(
@NonNull String profileName, @NonNull String localDatacenter) {
Expand Down Expand Up @@ -417,6 +433,7 @@ public ProgrammaticArguments build() {
nodeStateListener,
schemaChangeListener,
requestTracker,
requestIdGenerator,
localDatacentersBuilder.build(),
nodeFiltersBuilder.build(),
nodeDistanceEvaluatorsBuilder.build(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import com.datastax.oss.driver.api.core.metadata.schema.SchemaChangeListener;
import com.datastax.oss.driver.api.core.ssl.ProgrammaticSslEngineFactory;
import com.datastax.oss.driver.api.core.ssl.SslEngineFactory;
import com.datastax.oss.driver.api.core.tracker.RequestIdGenerator;
import com.datastax.oss.driver.api.core.tracker.RequestTracker;
import com.datastax.oss.driver.api.core.type.codec.TypeCodec;
import com.datastax.oss.driver.api.core.type.codec.registry.MutableCodecRegistry;
Expand All @@ -53,6 +54,7 @@
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;
Expand Down Expand Up @@ -89,6 +91,8 @@
@NotThreadSafe
public abstract class SessionBuilder<SelfT extends SessionBuilder, SessionT> {

public static final String ASTRA_PAYLOAD_KEY = "traceparent";

private static final Logger LOG = LoggerFactory.getLogger(SessionBuilder.class);

@SuppressWarnings("unchecked")
Expand Down Expand Up @@ -324,6 +328,17 @@ public SelfT addRequestTracker(@NonNull RequestTracker requestTracker) {
return self;
}

/**
* Registers a request ID generator. The driver will use the generated ID in the logs and
* optionally add to the custom payload so that users can correlate logs about the same request
* from the Cassandra side.
*/
@NonNull
public SelfT withRequestIdGenerator(@NonNull RequestIdGenerator requestIdGenerator) {
this.programmaticArgumentsBuilder.withRequestIdGenerator(requestIdGenerator);
return self;
}

/**
* Registers an authentication provider to use with the session.
*
Expand Down Expand Up @@ -868,6 +883,13 @@ protected final CompletionStage<CqlSession> buildDefaultSessionAsync() {
List<String> 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.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@
/**
* Limits the number of concurrent requests executed by the driver.
*
* <p>Usage in non-blocking applications: beware that all built-in implementations of this interface
* use locks for internal coordination, and do not qualify as lock-free, with the obvious exception
* of {@code PassThroughRequestThrottler}. If your application enforces strict lock-freedom, then
* request throttling should not be enabled.
* <p>Usage in non-blocking applications: beware that some implementations of this interface use
* locks for internal coordination, and do not qualify as lock-free. If your application enforces
* strict lock-freedom, then you should use the {@code PassThroughRequestThrottler} or the {@code
* ConcurrencyLimitingRequestThrottler}.
*/
public interface RequestThrottler extends Closeable {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public class ProgrammaticSslEngineFactory implements SslEngineFactory {
protected final SSLContext sslContext;
protected final String[] cipherSuites;
protected final boolean requireHostnameValidation;
protected final boolean allowDnsReverseLookupSan;

/**
* Creates an instance with the given {@link SSLContext}, default cipher suites and no host name
Expand Down Expand Up @@ -80,9 +81,28 @@ public ProgrammaticSslEngineFactory(
@NonNull SSLContext sslContext,
@Nullable String[] cipherSuites,
boolean requireHostnameValidation) {
this(sslContext, cipherSuites, requireHostnameValidation, true);
}

/**
* Creates an instance with the given {@link SSLContext}, cipher suites and host name validation.
*
* @param sslContext the {@link SSLContext} to use.
* @param cipherSuites the cipher suites to use, or null to use the default ones.
* @param requireHostnameValidation whether to enable host name validation. If enabled, host name
* validation will be done using HTTPS algorithm.
* @param allowDnsReverseLookupSan whether to allow raw server IPs to be DNS reverse-resolved to
* choose the appropriate Subject Alternative Name.
*/
public ProgrammaticSslEngineFactory(
@NonNull SSLContext sslContext,
@Nullable String[] cipherSuites,
boolean requireHostnameValidation,
boolean allowDnsReverseLookupSan) {
this.sslContext = sslContext;
this.cipherSuites = cipherSuites;
this.requireHostnameValidation = requireHostnameValidation;
this.allowDnsReverseLookupSan = allowDnsReverseLookupSan;
}

@NonNull
Expand All @@ -92,7 +112,12 @@ public SSLEngine newSslEngine(@NonNull EndPoint remoteEndpoint) {
SocketAddress remoteAddress = remoteEndpoint.resolve();
if (remoteAddress instanceof InetSocketAddress) {
InetSocketAddress socketAddress = (InetSocketAddress) remoteAddress;
engine = sslContext.createSSLEngine(socketAddress.getHostName(), socketAddress.getPort());
engine =
sslContext.createSSLEngine(
allowDnsReverseLookupSan
? socketAddress.getHostName()
: socketAddress.getHostString(),
socketAddress.getPort());
} else {
engine = sslContext.createSSLEngine();
}
Expand Down
Loading
Loading