Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 12 additions & 0 deletions core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,18 @@
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.networknt</groupId>
<artifactId>json-schema-validator</artifactId>
<scope>test</scope>
<exclusions>
<!-- A build-time Surefire tree reporter pulled in as a compile dependency; not needed. -->
<exclusion>
<groupId>me.fabriciorby</groupId>
<artifactId>maven-surefire-junit5-tree-reporter</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.reactivex.rxjava2</groupId>
<artifactId>rxjava</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1175,16 +1175,21 @@ public enum DefaultDriverOption implements DriverOption {
*/
ADDRESS_TRANSLATOR_RESOLVE_ADDRESSES("advanced.address-translator.resolve-addresses"),
/**
* Whether the driver reports its effective configuration to ScyllaDB at connection time.
*
* <p>When {@code true}, the driver adds two entries to the CQL {@code STARTUP} options, which
* ScyllaDB stores in {@code system.clients.client_options} so operators can inspect driver
* settings while investigating incidents: a {@code SESSION_ID} on every connection (so the server
* can group a session's connections) and a compact JSON payload under the {@code DRIVER_CONFIG}
* key on the control connection only. At this stage the {@code DRIVER_CONFIG} payload carries
* only schema-version metadata (<code>{"version":1}</code>); reporting of the effective
* configuration fields is planned for a later stage. When {@code false}, neither entry is sent
* and there is no change on the wire.
* Whether the driver reports its effective configuration to the cluster at connection time.
* Defaults to {@code true}.
*
* <p>When {@code true}, the control connection adds a compact JSON payload under the {@code
* DRIVER_CONFIG} key to its CQL {@code STARTUP} options, which the server stores in its
* client-connection system table ({@code system.clients} on ScyllaDB, {@code
* system_views.clients} on Cassandra 4.1+) so operators can inspect driver settings while
* investigating incidents. It describes the effective configuration of the driver's default
* execution profile (connection/socket settings, timeouts, retry/reconnection/
* speculative-execution/load-balancing policies, connection pooling, query defaults, and TLS).
* Only the control connection sends it, since it describes the whole session. When {@code false},
* {@code DRIVER_CONFIG} is not sent.
*
* <p>Reporting is best-effort: if the report cannot be built, or would exceed 32 KiB, it is
* skipped (with a warning) rather than allowed to interfere with connecting.
*
* <p>Value type: boolean
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ protected static void fillWithDriverDefaults(OptionsMap map) {
// values) with no sensible scalar default, analogous to how CONFIG_RELOAD_INTERVAL is omitted.
map.put(TypedDriverOption.CLIENT_ROUTES_NATIVE_TRANSPORT_PORT, 9042);
map.put(TypedDriverOption.CLIENT_ROUTES_SHARD_AWARENESS_ENABLED, false);
map.put(TypedDriverOption.DRIVER_CONFIG_REPORTING_ENABLED, false);
map.put(TypedDriverOption.DRIVER_CONFIG_REPORTING_ENABLED, true);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}

@Immutable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -976,7 +976,7 @@ public String toString() {
new TypedDriverOption<>(
DefaultDriverOption.CLIENT_ROUTES_SHARD_AWARENESS_ENABLED, GenericType.BOOLEAN);

/** Whether the driver reports its configuration to ScyllaDB at connection time. */
/** Whether the driver reports its configuration to the cluster at connection time. */
public static final TypedDriverOption<Boolean> DRIVER_CONFIG_REPORTING_ENABLED =
new TypedDriverOption<>(
DefaultDriverOption.DRIVER_CONFIG_REPORTING_ENABLED, GenericType.BOOLEAN);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ public SSLEngine newSslEngine(@NonNull EndPoint remoteEndpoint) {
return engine;
}

@Override
public boolean isHostnameValidationRequired() {
return requireHostnameValidation;
}

@Override
public void close() {
// nothing to do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,22 @@ public interface SslEngineFactory extends AutoCloseable {
*/
@NonNull
SSLEngine newSslEngine(@NonNull EndPoint remoteEndpoint);

/**
* Whether this factory validates the server certificate against the node's host name.
*
* <p>This is a diagnostic accessor (reported in the driver-configuration blob sent to the server
* at connection time); it does not affect how {@link #newSslEngine} behaves.
*
* <p>The driver's built-in factories override this to return their real value. It is a {@code
* default} method so that existing implementations keep compiling, and the default returns {@code
* false} because the driver cannot assume an arbitrary custom factory performs host name
* validation, and must not over-report a security control that may not actually be active. Custom
* factories that do validate should override this to report accurately.
*
* @since 4.19.2.1
*/
default boolean isHostnameValidationRequired() {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,7 @@ public int getShardId() {
}

public ShardingInfo getShardingInfo() {
ConnectionShardingInfo info = getSupportedFeatures().getShardingInfo();
return info != null ? info.shardingInfo : null;
return getSupportedFeatures().getNodeShardingInfo();
}

public LwtInfo getLwtInfo() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,14 +191,25 @@ Message getRequest() {
return request = Options.INSTANCE;
case STARTUP:
Map<String, String> startupOptions = new HashMap<>(context.getStartupOptions());
if (featureStore != null) {
featureStore.populateStartupOptions(startupOptions);
featureStore.populateStartupOptions(startupOptions);
// The DRIVER_CONFIG blob describes the whole session, so only the control connection
// carries it (options.reportConfig); the other connections are correlated to it by the
// SESSION_ID that every connection already carries from context.getStartupOptions().
// No-op when driver config reporting is disabled.
if (options.reportConfig) {
// Sharding info is both of the backend-conditional signals the report needs, in
// one value: non-null is the driver's own proxy check for "this is ScyllaDB"
// (also used, independently, by
// CassandraSchemaQueries.shouldApplyUsingTimeout()), which gates ScyllaDB-only
// server-side behavior such as the USING TIMEOUT clause on schema queries; and
// its shard count is what ChannelPool keys its pools by, so the reported pool
// sizing can be per-shard rather than per-host. It is only populated once the
// OPTIONS/SUPPORTED handshake has run, which ChannelFactory always requests.
context
.getDriverConfigReporter()
.populateControlConnectionOptions(
startupOptions, featureStore.getNodeShardingInfo());
}
// Adds SESSION_ID on every connection and DRIVER_CONFIG on the control connection
// (options.reportConfig); no-op when driver config reporting is disabled.
context
.getDriverConfigReporter()
.populateStartupOptions(startupOptions, options.reportConfig);
return request = new Startup(startupOptions);
case GET_CLUSTER_NAME:
return request = CLUSTER_NAME_QUERY;
Expand Down
Loading
Loading