Client config reporting (3.x) — stage 2: full DRIVER_CONFIG report - #974
Draft
nikagra wants to merge 2 commits into
Draft
Client config reporting (3.x) — stage 2: full DRIVER_CONFIG report#974nikagra wants to merge 2 commits into
nikagra wants to merge 2 commits into
Conversation
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
nikagra
added a commit
to nikagra/java-driver
that referenced
this pull request
Jul 30, 2026
…stage 1) Stage 1 (groundwork) of client configuration reporting for the 3.x driver -- the 3.x counterpart of the 4.x feature (DRIVER-381/scylladb#967). Lets the driver report its effective configuration to ScyllaDB at connection time via new STARTUP options, so operators can inspect driver settings (system.clients.client_options) while investigating incidents. Gated behind Cluster.builder().withDriverConfigReporting(boolean), which ships disabled (zero change on the wire when off). When enabled: - SESSION_ID: a dedicated, driver-generated per-session UUID, sent on every connection (control and pool) so the server can group all of a session's connections. Independent of the user-settable CLIENT_ID. - DRIVER_CONFIG: a compact JSON blob, sent only on the control connection. Stage 1 emits only {"version":1}; the full report follows in stage 2 (scylladb#974). Reporting is fail-safe: any failure while building the report is swallowed and never breaks connection initialization. New DriverConfigReporter / DefaultDriverConfigReporter (package com.datastax.driver.core), mirroring the existing ApplicationInfo pattern, invoked from Connection.onOptionsReady(). The control connection is marked via a new reportConfig flag threaded from ControlConnection.tryConnect through a new Connection.Factory.open(host, reportConfig) overload -- 3.x has no pre-existing signal identifying the control connection at STARTUP time. Fixes DRIVER-382
nikagra
added a commit
to nikagra/java-driver
that referenced
this pull request
Jul 30, 2026
…stage 1) Stage 1 (groundwork) of client configuration reporting for the 3.x driver -- the 3.x counterpart of the 4.x feature (DRIVER-381/scylladb#967). Lets the driver report its effective configuration to ScyllaDB at connection time via new STARTUP options, so operators can inspect driver settings (system.clients.client_options) while investigating incidents. Gated behind Cluster.builder().withDriverConfigReporting(boolean), which ships disabled (zero change on the wire when off). When enabled: - SESSION_ID: a dedicated, driver-generated per-session UUID, sent on every connection (control and pool) so the server can group all of a session's connections. Independent of the user-settable CLIENT_ID. - DRIVER_CONFIG: a compact JSON blob, sent only on the control connection. Stage 1 emits only {"version":1}; the full report follows in stage 2 (scylladb#974). Reporting is fail-safe: any failure while building the report is swallowed and never breaks connection initialization. New DriverConfigReporter / DefaultDriverConfigReporter (package com.datastax.driver.core), mirroring the existing ApplicationInfo pattern, invoked from Connection.onOptionsReady(). The control connection is marked via a new reportConfig flag threaded from ControlConnection.tryConnect through a new Connection.Factory.open(host, reportConfig) overload -- 3.x has no pre-existing signal identifying the control connection at STARTUP time. Fixes DRIVER-382
nikagra
force-pushed
the
feature/driver-config-reporting-3x-phase2
branch
from
July 30, 2026 20:40
d00e683 to
12571f1
Compare
nikagra
added a commit
to nikagra/java-driver
that referenced
this pull request
Jul 30, 2026
…stage 1) Stage 1 (groundwork) of driver configuration reporting for the 3.x driver -- the 3.x counterpart of the 4.x feature (DRIVER-381/scylladb#967). Lets the driver report its effective configuration to ScyllaDB at connection time via new STARTUP options, so operators can inspect driver settings (system.clients.client_options) while investigating incidents. Gated behind Cluster.builder().withDriverConfigReporting(boolean), which ships disabled (zero change on the wire when off). When enabled: - SESSION_ID: a dedicated, driver-generated UUID, sent on every connection (control and pool) so the server can group all of a Cluster's connections -- including across multiple Sessions obtained from the same Cluster, since the control connection has no affiliation with any single Session. Independent of the user-settable CLIENT_ID. - DRIVER_CONFIG: a compact JSON blob, sent only on the control connection. Stage 1 emits only {"version":1}; the full report follows in stage 2 (scylladb#974). Reporting is fail-safe: any failure while building the report is swallowed and never breaks connection initialization. New DriverConfigReporter / DefaultDriverConfigReporter (package com.datastax.driver.core), mirroring the existing ApplicationInfo pattern, invoked from Connection.onOptionsReady(). Only constructed when reporting is enabled -- a new NoopDriverConfigReporter is used otherwise, so Jackson (used to build the JSON blob) is never loaded when the feature is off; jackson-core/jackson-databind are marked optional in driver-core/pom.xml accordingly. The control connection is marked via a new reportConfig flag threaded from ControlConnection.tryConnect through a new Connection.Factory.open(host, reportConfig) overload -- 3.x has no pre-existing signal identifying the control connection at STARTUP time. system.clients.client_options is per node, so DRIVER_CONFIG only appears on the node holding the control connection. Fixes DRIVER-382
nikagra
force-pushed
the
feature/driver-config-reporting-3x-phase2
branch
from
July 30, 2026 20:54
12571f1 to
4ef72fd
Compare
nikagra
added a commit
to nikagra/java-driver
that referenced
this pull request
Jul 30, 2026
…stage 1) Stage 1 (groundwork) of driver configuration reporting for the 3.x driver -- the 3.x counterpart of the 4.x feature (DRIVER-381/scylladb#967). Lets the driver report its effective configuration to ScyllaDB at connection time via new STARTUP options, so operators can inspect driver settings (system.clients.client_options) while investigating incidents. Gated behind Cluster.builder().withDriverConfigReporting(boolean), which ships disabled (zero change on the wire when off). When enabled: - SESSION_ID: a dedicated, driver-generated UUID, sent on every connection (control and pool) so the server can group all of a Cluster's connections -- including across multiple Sessions obtained from the same Cluster, since the control connection has no affiliation with any single Session. Independent of the user-settable CLIENT_ID. - DRIVER_CONFIG: a compact JSON blob, sent only on the control connection. Stage 1 emits only {"version":1}; the full report follows in stage 2 (scylladb#974). Reporting is fail-safe: any failure while building the report is swallowed and never breaks connection initialization. New DriverConfigReporter / DefaultDriverConfigReporter (package com.datastax.driver.core), mirroring the existing ApplicationInfo pattern, invoked from Connection.onOptionsReady(). Only constructed when reporting is enabled -- a new NoopDriverConfigReporter is used otherwise, so Jackson (used to build the JSON blob) is never loaded when the feature is off; jackson-core/jackson-databind are marked optional in driver-core/pom.xml accordingly. The control connection is marked via a new reportConfig flag threaded from ControlConnection.tryConnect through a new Connection.Factory.open(host, reportConfig) overload -- 3.x has no pre-existing signal identifying the control connection at STARTUP time. system.clients.client_options is per node, so DRIVER_CONFIG only appears on the node holding the control connection. Fixes DRIVER-382
nikagra
force-pushed
the
feature/driver-config-reporting-3x-phase2
branch
from
July 30, 2026 23:53
4ef72fd to
2120a94
Compare
…stage 1) Stage 1 (groundwork) of driver configuration reporting for the 3.x driver -- the 3.x counterpart of the 4.x feature (DRIVER-381/scylladb#967). Lets the driver report its effective configuration to ScyllaDB at connection time via new STARTUP options, so operators can inspect driver settings (system.clients.client_options) while investigating incidents. Two STARTUP options are added: - SESSION_ID: a dedicated, driver-generated UUID sent on every connection (control and pool) unconditionally, like DRIVER_NAME and DRIVER_VERSION, so the server can group all of a Cluster's connections -- including across multiple Sessions obtained from the same Cluster, since the control connection has no affiliation with any single Session. Independent of the user-settable CLIENT_ID. - DRIVER_CONFIG: a compact JSON blob describing the effective configuration, sent only on the control connection. Stage 1 emits only {"version":1}; the full report follows in stage 2 (scylladb#974). Enabled by default; opt out with Cluster.builder().withDriverConfigReporting(false). The report is built once, while the Cluster initializes, and the resulting string is reused for every control connection that Cluster opens -- it is never rebuilt while the session is in flight. Building it is fail-safe: any failure is swallowed and simply leaves DRIVER_CONFIG unset instead of breaking cluster initialization. New DriverConfigReporter / DefaultDriverConfigReporter (package com.datastax.driver.core) build the blob. Connection.Factory, of which there is one per Cluster, holds that Cluster's session id and the built report, and hands the report to the control connection as a constructor argument -- null everywhere else, which is what suppresses reporting. The control connection is identified by threading a reportConfig flag from ControlConnection.tryConnect through a new Connection.Factory.open(host, reportConfig) overload, since 3.x has no pre-existing signal identifying the control connection at STARTUP time. jackson-core/jackson-databind are enforced as plain required dependencies (as they already were in released 3.11.5.17), used to build the JSON blob; the orphaned jackson-dataformat-yaml dependency (dead since the Scylla Cloud config code was removed) is dropped, so consumers no longer inherit SnakeYAML. system.clients.client_options is per node, so DRIVER_CONFIG only appears on the node holding the control connection. Fixes DRIVER-382 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Fills in the full DRIVER_CONFIG JSON report in the approved v2
cross-driver schema shape, replacing the stage-1 {"version":1}
placeholder. All groups are populated from Configuration and Policies
when the report is built, i.e. once per Cluster as it initializes.
Adds public getters to DCAwareRoundRobinPolicy and
RackAwareRoundRobinPolicy needed to report node-location-preference
and dc-failover, and makes PagingOptimizingLoadBalancingPolicy
implement ChainableLoadBalancingPolicy so the reporter can unwrap the
LB policy Cluster.Manager wraps at runtime.
Adds a JSON-Schema conformance test suite (mirroring the 4.x sibling
PR scylladb#968): the normative schema is shipped as a test resource and
validated via com.networknt:json-schema-validator (pinned to 1.5.x,
the last line still targeting Java 8), covering every discriminated-
union branch and optional group the 3.x reporter can emit, plus a
negative test proving additionalProperties=false is enforced.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
nikagra
force-pushed
the
feature/driver-config-reporting-3x-phase2
branch
from
July 31, 2026 17:01
2120a94 to
b2d9bab
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Stage 2 of driver configuration reporting for the 3.x driver: fills in the full
DRIVER_CONFIGJSON report, replacing the stage-1{"version":1}placeholder. When driver config reporting is enabled, the control connection now reports the driver's effective configuration in the approved v2 cross-driver schema shape.The report (v2 schema)
All groups are populated from
Configuration+Policieson each control-connection init, so the report reflects the current configuration. v2 conventions: kebab-case keys, nested objects, and omission (nevernull) of any key/group with no value.customfallback carrying the class name.token-aware,dc-failover,latency-awareness,shuffle), obtained by unwrapping the policy chain.dc/rack/dc-auto/rack-auto).To feed
node-location-preferenceanddc-failover, this adds public getters toDCAwareRoundRobinPolicyandRackAwareRoundRobinPolicy(getLocalDc/getLocalRack/isLocalDcExplicit/isLocalRackExplicit/getUsedHostsPerRemoteDc), and makesPagingOptimizingLoadBalancingPolicyimplementChainableLoadBalancingPolicy(exposinggetChildPolicy) — at runtimeCluster.Managerwraps every session's LB policy in it, so without unwrapping the report would degrade to{type:"custom"}and lose the flags and location preference.Reporting remains fail-safe: any failure while building the report is swallowed;
SESSION_IDis still emitted and only the config blob is dropped.Reconciliation decisions (3.x ↔ schema)
PoolingOptionsis stillUNSET— the report is built on the control connection, before pool sizing is finalized.connection-pool.type→"host"(3.x has a single per-host pool class; shard distribution is handled inside it).load-balancing-policy.shuffle→false(3.x has no replica-shuffle getter).{type:"custom", name:<class simple name>}(no reflective attribute dump in v1).Several settings have no public getter (or no equivalent) in the 3.x driver, so per v2's "omit what doesn't apply" they are left out of the report rather than guessed:
connection.write(write timeout)connection.heartbeatcontrol-plane.….server-side-msUSING TIMEOUT) timeoutreconnection-policy.max-attemptsspeculative-execution-policyparams{type:"custom"}Constant/Percentileparams are not introspectable (no getters); omitted entirely when no speculative execution is configuredload-balancing-policy.shufflefalsetls.hostname-verificationfalse(trueonly forSniSSLOptions)SSLContext; the schema requires a boolean so it is not omittednode-location-preferenceEverything else in the schema is populated from public getters.
Testing
Unit —
DefaultDriverConfigReporterTest(27 tests, green on JDK 8/11)SESSION_ID/ fail-safe (6): the stage-1 cases (reporting disabled, session-id-only on pool connections, fail-safe on a build error, session-id sharing/uniqueness).PagingOptimizingunwrapping, explicit dc/racknode-location-preference, server-side timestamps, TLS enabled, socket overrides.driver-core/src/test/resources/config/driver-config-report-v1.schema.json) and validated viacom.networknt:json-schema-validator(pinned to1.5.x, the last minor line still targeting Java 8). One test per discriminated-union branch/optional-group case the 3.x reporter can emit, plus a negative test provingadditionalProperties: falseis actually enforced (an unknown top-level key is rejected).Plus
NoopDriverConfigReporterTest(2 tests, unchanged from stage 1).Integration —
DriverConfigReportingCcmTest(3 tests) against live ScyllaDB 2026.1.0 (via CCM)Covers, all live-verified:
SESSION_IDshared across every connection of a session and across multipleSessions from the sameCluster;DRIVER_CONFIGstored on exactly the control connection as the full v2 report (spot-checked forconnection,load-balancing-policy,connection-pool.shard-aware.enabled— no truncation); nothing stored when reporting is disabled.The stored
DRIVER_CONFIGfor the control connection, formatted:{ "version": 1, "connection": { "connect": { "timeout-ms": 5000 }, "read": { "timeout-ms": 12000 } }, "socket": { "tcp-no-delay": true, "keep-alive": false, "reuse-address": false }, "control-plane": { "system-queries": { "timeout": { "client-side-ms": 12000 } }, "schema-agreement": { "timeout-ms": 10000 } }, "reconnection-policy": { "type": "exponential", "base-ms": 1000, "max-ms": 600000 }, "retry-policy": { "type": "standard-error-aware" }, "load-balancing-policy": { "type": "token-aware", "token-aware": true, "shuffle": false, "dc-failover": false, "latency-awareness": false }, "node-location-preference": { "type": "dc-auto" }, "connection-pool": { "type": "host", "desired-connections-count": 1, "connection": { "max-requests": 1024 }, "shard-aware": { "enabled": true } }, "query-defaults": { "page": { "size": 5000 }, "consistency": "LOCAL_ONE", "serial-consistency": "SERIAL", "idempotence": false, "client-timestamps": true, "request": { "timeout-ms": 12000 } }, "tls": { "enabled": false, "hostname-verification": false } }Follow-up
STARTUPkey tolerance +client_optionsvalue-length — validated above for 2026.1.0).Fixes DRIVER-382
🤖 Generated with Claude Code