4.x: PrivateLink Support Phase 3: Query Implementation, DNS Resolution & Unit Tests 🔌#807
Merged
dkropachev merged 2 commits intoscylladb:scylla-4.xfrom Mar 14, 2026
Conversation
57574a3 to
26aebdd
Compare
There was a problem hiding this comment.
Pull request overview
This PR completes Phase 3 of PrivateLink support for the Java driver, implementing the runtime components required for ScyllaDB Cloud deployments. Building on Phase 2's infrastructure (#804), it adds DNS resolution, query execution, and complete lifecycle integration for the client routes feature.
Changes:
- Implements TTL-based caching DNS resolver with last-known-good fallback and concurrency control
- Adds query execution for
system.client_routestable with hostname resolution and route map management - Integrates client routes initialization into session startup and control-connection reconnect lifecycle
- Implements backward-compatible event negotiation to handle older ScyllaDB versions that don't support
CLIENT_ROUTES_CHANGEevents
Reviewed changes
Copilot reviewed 29 out of 29 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| pom.xml | Upgrades native protocol to 1.5.2.2 to support CLIENT_ROUTES_CHANGE event |
| manual/core/address_resolution/README.md | Documents client routes configuration and usage with examples |
| core/.../util/AddressParser.java | New utility for parsing contact point addresses with IPv4/IPv6/hostname support |
| core/.../clientroutes/DnsResolver.java | Interface defining DNS resolution with caching requirements |
| core/.../clientroutes/CachingDnsResolver.java | TTL-based DNS caching implementation with semaphore-based concurrency control |
| core/.../clientroutes/ClientRouteInfo.java | Data structure representing raw client_routes table rows |
| core/.../clientroutes/ResolvedClientRoute.java | Resolved route with DNS resolution capability |
| core/.../clientroutes/ClientRoutesHandler.java | Main coordinator implementing query execution and route management |
| core/.../clientroutes/ClientRoutesAddressTranslator.java | AddressTranslator implementation delegating to handler |
| core/.../session/DefaultSession.java | Integrates client routes initialization into session startup |
| core/.../metadata/DefaultTopologyMonitor.java | Passes node metadata (hostId, datacenter, rack) to address translator |
| core/.../control/ControlConnection.java | Adds CLIENT_ROUTES_CHANGE event handling and reconnect integration |
| core/.../context/DefaultDriverContext.java | Wires client routes handler into driver context |
| core/.../context/InternalDriverContext.java | Adds getClientRoutesHandler() method |
| core/.../channel/ProtocolInitHandler.java | Implements backward-compatible event negotiation for CLIENT_ROUTES_CHANGE |
| core/.../session/SessionBuilder.java | Adds withClientRoutesConfig() with mutual exclusivity validation |
| core/.../session/ProgrammaticArguments.java | Stores client routes config in programmatic arguments |
| core/.../config/ClientRoutesConfig.java | Configuration class for client routes with builder |
| core/.../config/ClientRoutesEndpoint.java | Represents a single client routes endpoint |
| core/.../addresstranslation/AddressTranslator.java | Adds overloaded translate() method accepting node metadata |
| core/.../config/DefaultDriverOption.java | Minor formatting cleanup (blank line removal) |
| core/src/main/resources/reference.conf | Minor formatting cleanup (blank line removal) |
| core/src/test/.../util/AddressParserTest.java | Comprehensive unit tests for address parsing |
| core/src/test/.../clientroutes/CachingDnsResolverTest.java | Unit tests for DNS resolver cache behavior |
| core/src/test/.../clientroutes/ClientRoutesHandlerTest.java | Unit tests for handler translate() method |
| core/src/test/.../clientroutes/ClientRoutesAddressTranslatorTest.java | Unit tests for address translator delegation |
| core/src/test/.../session/ClientRoutesSessionBuilderTest.java | Unit tests for session builder configuration |
| core/src/test/.../config/ClientRoutesConfigTest.java | Unit tests for configuration validation |
| core/src/test/.../metadata/DefaultTopologyMonitorTest.java | Updates test verification counts for additional getString() calls |
core/src/main/java/com/datastax/oss/driver/internal/core/channel/ProtocolInitHandler.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/datastax/oss/driver/internal/core/channel/ProtocolInitHandler.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/datastax/oss/driver/internal/core/clientroutes/CachingDnsResolver.java
Outdated
Show resolved
Hide resolved
...src/test/java/com/datastax/oss/driver/internal/core/metadata/DefaultTopologyMonitorTest.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/datastax/oss/driver/internal/core/clientroutes/ClientRoutesHandler.java
Outdated
Show resolved
Hide resolved
...rc/test/java/com/datastax/oss/driver/internal/core/clientroutes/ClientRoutesHandlerTest.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/datastax/oss/driver/internal/core/metadata/DefaultTopologyMonitor.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/datastax/oss/driver/internal/core/clientroutes/CachingDnsResolver.java
Outdated
Show resolved
Hide resolved
c24ab8c to
dcf7511
Compare
This was referenced Mar 6, 2026
b8b99ec to
9149786
Compare
dkropachev
reviewed
Mar 9, 2026
core/src/main/java/com/datastax/oss/driver/api/core/config/ClientRoutesEndpoint.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/datastax/oss/driver/api/core/config/DefaultDriverOption.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/datastax/oss/driver/api/core/session/SessionBuilder.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/datastax/oss/driver/internal/core/clientroutes/CachingDnsResolver.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/datastax/oss/driver/internal/core/clientroutes/ResolvedClientRoute.java
Outdated
Show resolved
Hide resolved
...rc/main/java/com/datastax/oss/driver/internal/core/metadata/ClientRoutesTopologyMonitor.java
Outdated
Show resolved
Hide resolved
...rc/main/java/com/datastax/oss/driver/internal/core/metadata/ClientRoutesTopologyMonitor.java
Outdated
Show resolved
Hide resolved
...rc/main/java/com/datastax/oss/driver/internal/core/metadata/ClientRoutesTopologyMonitor.java
Outdated
Show resolved
Hide resolved
...rc/main/java/com/datastax/oss/driver/internal/core/metadata/ClientRoutesTopologyMonitor.java
Outdated
Show resolved
Hide resolved
...rc/main/java/com/datastax/oss/driver/internal/core/metadata/ClientRoutesTopologyMonitor.java
Outdated
Show resolved
Hide resolved
cd23bae to
942f9f5
Compare
dkropachev
reviewed
Mar 10, 2026
core/src/main/java/com/datastax/oss/driver/api/core/addresstranslation/AddressTranslator.java
Outdated
Show resolved
Hide resolved
bedea4d to
a64a501
Compare
84ca83a to
2f9ded7
Compare
nikagra
commented
Mar 13, 2026
...rc/main/java/com/datastax/oss/driver/internal/core/metadata/ClientRoutesTopologyMonitor.java
Outdated
Show resolved
Hide resolved
nikagra
commented
Mar 13, 2026
...rc/main/java/com/datastax/oss/driver/internal/core/metadata/ClientRoutesTopologyMonitor.java
Outdated
Show resolved
Hide resolved
nikagra
commented
Mar 13, 2026
core/src/main/java/com/datastax/oss/driver/internal/core/metadata/ClientRoutesEndPoint.java
Outdated
Show resolved
Hide resolved
nikagra
commented
Mar 13, 2026
core/src/test/java/com/datastax/oss/driver/internal/core/metadata/ClientRoutesEndPointTest.java
Outdated
Show resolved
Hide resolved
nikagra
commented
Mar 13, 2026
...rc/main/java/com/datastax/oss/driver/internal/core/metadata/ClientRoutesTopologyMonitor.java
Outdated
Show resolved
Hide resolved
nikagra
commented
Mar 13, 2026
...rc/main/java/com/datastax/oss/driver/internal/core/metadata/ClientRoutesTopologyMonitor.java
Outdated
Show resolved
Hide resolved
nikagra
commented
Mar 13, 2026
core/src/main/java/com/datastax/oss/driver/api/core/config/ClientRouteContactPoint.java
Outdated
Show resolved
Hide resolved
dkropachev
added a commit
to nikagra/java-driver
that referenced
this pull request
Mar 14, 2026
- Rewrite connectionAddrOverrides loop with stream API
- Replace FQN java.io.IOException/UncheckedIOException with imports
in ClientRoutesEndPoint and ClientRoutesEndPointTest
- Fix containsPort(":9042") bug: leading-colon strings were accepted
as valid addresses; add unit test
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
dkropachev
added a commit
to nikagra/java-driver
that referenced
this pull request
Mar 14, 2026
- Rewrite connectionAddrOverrides loop with stream API
- Replace FQN java.io.IOException/UncheckedIOException with imports
in ClientRoutesEndPoint and ClientRoutesEndPointTest
- Fix containsPort(":9042") bug: leading-colon strings were accepted
as valid addresses; add unit test
e291988 to
13221b3
Compare
Add support for PrivateLink/NLB client routes that allows the driver to discover and connect through private endpoints. This includes: - ClientRoutesConfig and ClientRouteProxy for configuration - ClientRoutesTopologyMonitor for route discovery and refresh - ClientRoutesEndPoint for DNS-based endpoint resolution - Protocol-level CLIENT_ROUTES_CHANGE event handling - Coalescing queue for efficient route refresh deduplication - Integration tests with NLB simulator proxy
75afb07 to
c6a5370
Compare
dkropachev
approved these changes
Mar 14, 2026
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.
4.x: PrivateLink Support Phase 3: Query Implementation, DNS Resolution & Tests 🔌
Previous phases:
Overview
Completes the runtime implementation of PrivateLink/client-routes support for ScyllaDB Cloud. The
driver can now query
system.client_routesat startup and on control-connection reconnect, resolvenode hostnames to
InetSocketAddressvia a TTL-aware caching DNS resolver, and dynamicallytranslate addresses used for every CQL connection.
Server-side feature requires scylladb/scylladb#27323.
Changes
Event Negotiation Fix —
ProtocolInitHandler(SCYLLADB-850)registerEventTypeslist (copy ofoptions.eventTypes) so the REGISTERstep can be retried with a narrowed event set without mutating the original channel options.
PROTOCOL_ERRORwhose message containsCLIENT_ROUTES_CHANGE, the driver logs a warning, removes that event type, and retries REGISTERwith the remaining types (
SCHEMA_CHANGE,STATUS_CHANGE,TOPOLOGY_CHANGE).setConnectSuccess()directly,skipping REGISTER altogether.
queries may still work on those versions, but live push-updates via the event are disabled.
DNS Resolution —
CachingDnsResolver(new)ConcurrentHashMap<String, CacheEntry>with per-hostnameSemaphore(1)to prevent concurrent re-resolution storms.UnknownHostException, the previous successful resolution isreturned and a warning is logged.
clearCache()preserves last-known-good entries so a full session re-init survives transient DNSfailures.
Client Routes Query —
ClientRoutesHandlerqueryAndResolveRoutes()implemented: executesSELECT connection_id, host_id, address, port, tls_port FROM %s WHERE connection_id IN :connectionIds ALLOW FILTERINGvia
AdminRequestHandler.CachingDnsResolverwired in, replacing the Phase 2 no-op stub.AtomicReference.set()so in-flight translations see aconsistent snapshot.
Session Lifecycle —
DefaultSessioninitClientRoutes()inserted betweentopologyMonitor.init()andmetadataManager.refreshNodes()in the startup chain.falls back to direct addressing.
Reconnect Integration —
ControlConnectionclientRoutesHandler.refresh()is awaited beforerefreshNodes(),so translated addresses are current before nodes are re-evaluated.
Tests
Unit Tests — 22 new tests across 3 suites
CachingDnsResolverTestclearCache()ClientRoutesHandlerTestClientRoutesAddressTranslatorTestIntegration Tests — 6 new tests across 2 suites
ClientRoutesITrefresh()picks up new rows; session opens with empty table; TLS port selection; auto-refresh on control-connection reconnectClientRoutesUnsupportedVersionITnullwhensystem.client_routesis absent (graceful degradation)Both integration test suites are
@Category(IsolatedTests.class)and@ScyllaOnly. Positive testsuse a user-space mirror table (
test_client_routes.client_routes) to avoid requiring privilegedwrite access to
system.Additional notes
This PR also uses workaround for SCYLLADB-850: older ScyllaDB Enterprise versions (< 2026.1) reject the
CLIENT_ROUTES_CHANGEREGISTER event with aPROTOCOL_ERROR, which previously caused connection initialisation to fail. The driver now gracefully handles this by stripping the unsupported event and retrying REGISTER with the remaining types, so sessions succeed on any server version.Related to DRIVER-86, DRIVER-88, SCYLLADB-850