Skip to content

Commit b0e0405

Browse files
nikagraCopilot
andcommitted
feat: update client routes configuration details for mutual exclusivity with AddressTranslator and cloud bundles
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent a5140da commit b0e0405

5 files changed

Lines changed: 32 additions & 25 deletions

File tree

core/src/main/java/com/datastax/oss/driver/api/core/config/ClientRoutesConfig.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,13 @@ public Builder addEndpoint(@NonNull ClientRoutesEndpoint endpoint) {
152152
@NonNull
153153
public Builder withEndpoints(@NonNull List<ClientRoutesEndpoint> endpoints) {
154154
Objects.requireNonNull(endpoints, "endpoints must not be null");
155+
if (endpoints.isEmpty()) {
156+
throw new IllegalArgumentException("endpoints must not be empty");
157+
}
155158
this.endpoints.clear();
156-
this.endpoints.addAll(endpoints);
159+
for (ClientRoutesEndpoint endpoint : endpoints) {
160+
addEndpoint(endpoint);
161+
}
157162
return this;
158163
}
159164

core/src/main/java/com/datastax/oss/driver/api/core/session/SessionBuilder.java

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525

2626
import com.datastax.oss.driver.api.core.CqlIdentifier;
2727
import com.datastax.oss.driver.api.core.CqlSession;
28-
import com.datastax.oss.driver.api.core.addresstranslation.AddressTranslator;
2928
import com.datastax.oss.driver.api.core.auth.AuthProvider;
3029
import com.datastax.oss.driver.api.core.auth.PlainTextAuthProviderBase;
3130
import com.datastax.oss.driver.api.core.auth.ProgrammaticPlainTextAuthProvider;
@@ -748,9 +747,9 @@ public SelfT withCloudProxyAddress(@Nullable InetSocketAddress cloudProxyAddress
748747
* table. Each endpoint is identified by a connection ID and maps to specific node addresses.
749748
*
750749
* <p>This configuration is mutually exclusive with a user-provided {@link AddressTranslator}. If
751-
* both are specified, an error will be thrown during session initialization. If you need custom
752-
* address translation behavior with client routes, the driver's internal client routes handler
753-
* will be used.
750+
* both are specified, a warning will be logged and the client routes configuration will take
751+
* precedence. If you need custom address translation behavior with client routes, consider
752+
* implementing that logic within your client routes endpoint mapping instead.
754753
*
755754
* <p>Example usage:
756755
*
@@ -939,6 +938,13 @@ protected final CompletionStage<CqlSession> buildDefaultSessionAsync() {
939938
withSslEngineFactory(cloudConfig.getSslEngineFactory());
940939
withCloudProxyAddress(cloudConfig.getProxyAddress());
941940
programmaticArguments = programmaticArgumentsBuilder.build();
941+
942+
// Check for mutual exclusivity with client routes
943+
if (clientRoutesConfig != null) {
944+
LOG.info(
945+
"Both a secure connect bundle and client routes configuration were provided. They are mutually exclusive. The configuration from the secure bundle will have priority.");
946+
clientRoutesConfig = null;
947+
}
942948
}
943949

944950
// Handle client routes configuration
@@ -951,9 +957,10 @@ protected final CompletionStage<CqlSession> buildDefaultSessionAsync() {
951957
if (!"PassThroughAddressTranslator".equals(translatorClass)
952958
&& !"com.datastax.oss.driver.internal.core.addresstranslation.PassThroughAddressTranslator"
953959
.equals(translatorClass)) {
954-
throw new IllegalArgumentException(
955-
"Client routes configuration is mutually exclusive with a custom AddressTranslator. "
956-
+ "Either remove the address translator configuration or do not use client routes.");
960+
LOG.info(
961+
"Both client routes configuration and a custom AddressTranslator were provided. They are mutually exclusive. The client routes configuration will have priority.");
962+
// Note: We don't clear clientRoutesConfig here - it takes precedence.
963+
// The AddressTranslator will be effectively ignored when client routes are active.
957964
}
958965
}
959966

@@ -962,18 +969,9 @@ protected final CompletionStage<CqlSession> buildDefaultSessionAsync() {
962969
for (ClientRoutesEndpoint endpoint : clientRoutesConfig.getEndpoints()) {
963970
if (endpoint.getConnectionAddr() != null) {
964971
String addr = endpoint.getConnectionAddr().trim();
965-
try {
966-
InetSocketAddress socketAddress =
967-
AddressParser.parseContactPoint(addr, endpoint.getConnectionId());
968-
programmaticContactPoints.add(new DefaultEndPoint(socketAddress));
969-
970-
} catch (Exception e) {
971-
throw new IllegalArgumentException(
972-
String.format(
973-
"Failed to parse client routes endpoint address '%s' (connection ID: %s): %s",
974-
addr, endpoint.getConnectionId(), e.getMessage()),
975-
e);
976-
}
972+
InetSocketAddress socketAddress =
973+
AddressParser.parseContactPoint(addr, endpoint.getConnectionId());
974+
programmaticContactPoints.add(new DefaultEndPoint(socketAddress));
977975
}
978976
}
979977
}

core/src/main/java/com/datastax/oss/driver/internal/core/util/AddressParser.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public static InetSocketAddress parseContactPoint(String address, UUID connectio
9292
String.format("Invalid port %d. Port must be between 1 and 65535.", port)));
9393
}
9494

95-
return new InetSocketAddress(host, port);
95+
return InetSocketAddress.createUnresolved(host, port);
9696

9797
} catch (java.net.URISyntaxException e) {
9898
throw new IllegalArgumentException(

core/src/main/resources/reference.conf

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,9 +1120,11 @@ datastax-java-driver {
11201120
# SessionBuilder.withClientRoutesConfig(). This configuration section only provides the
11211121
# system table name option.
11221122
#
1123-
# Client routes are mutually exclusive with a custom AddressTranslator. If client routes are
1124-
# configured programmatically, the address-translator.class option must be set to
1125-
# PassThroughAddressTranslator (the default), otherwise session initialization will fail.
1123+
# Client routes are mutually exclusive with:
1124+
# - A custom AddressTranslator: If both are configured, client routes take precedence
1125+
# and the AddressTranslator is effectively ignored (a warning is logged).
1126+
# - Cloud secure connect bundles: If both are configured, the cloud bundle takes precedence
1127+
# and client routes are ignored (a warning is logged).
11261128
#
11271129
# Required: no (programmatic configuration only)
11281130
# Modifiable at runtime: no

manual/core/address_resolution/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,9 @@ For cloud deployments using PrivateLink or similar private endpoint technologies
124124
accessed through private DNS endpoints rather than direct IP addresses. The driver provides a client routes feature
125125
to handle this topology.
126126

127-
Client routes configuration is done programmatically and is **mutually exclusive** with a custom `AddressTranslator`.
127+
Client routes configuration is done programmatically and is **mutually exclusive** with:
128+
- A custom `AddressTranslator` (if both are provided, client routes takes precedence)
129+
- Cloud secure connect bundles (if both are provided, the cloud bundle takes precedence)
128130

129131
Example configuration:
130132

0 commit comments

Comments
 (0)