Skip to content

Commit 64ce57f

Browse files
author
alexsa
committed
Resolve addresses on init and use separate property to toggle address resolution
1 parent e07d17a commit 64ce57f

File tree

4 files changed

+47
-34
lines changed

4 files changed

+47
-34
lines changed

core/src/main/java/com/datastax/oss/driver/internal/core/addresstranslation/SubnetAddressTranslator.java

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
*/
1818
package com.datastax.oss.driver.internal.core.addresstranslation;
1919

20-
import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.RESOLVE_CONTACT_POINTS;
21-
2220
import com.datastax.oss.driver.api.core.addresstranslation.AddressTranslator;
2321
import com.datastax.oss.driver.api.core.config.DriverOption;
2422
import com.datastax.oss.driver.api.core.context.DriverContext;
@@ -74,6 +72,13 @@ public class SubnetAddressTranslator implements AddressTranslator {
7472
public static final String ADDRESS_TRANSLATOR_DEFAULT_ADDRESS =
7573
"advanced.address-translator.default-address";
7674

75+
/**
76+
* Whether to resolve the addresses on initialization (if true) or on each node (re-)connection
77+
* (if false). Defaults to false.
78+
*/
79+
public static final String ADDRESS_TRANSLATOR_RESOLVE_ADDRESSES =
80+
"advanced.address-translator.resolve-addresses";
81+
7782
public static DriverOption ADDRESS_TRANSLATOR_SUBNET_ADDRESSES_OPTION =
7883
new DriverOption() {
7984
@NonNull
@@ -92,13 +97,26 @@ public String getPath() {
9297
}
9398
};
9499

100+
public static DriverOption ADDRESS_TRANSLATOR_RESOLVE_ADDRESSES_OPTION =
101+
new DriverOption() {
102+
@NonNull
103+
@Override
104+
public String getPath() {
105+
return ADDRESS_TRANSLATOR_RESOLVE_ADDRESSES;
106+
}
107+
};
108+
95109
private final List<SubnetAddress> subnetAddresses;
96-
private final Optional<String> defaultAddress;
97-
private final boolean resolveAddresses;
110+
private final Optional<InetSocketAddress> defaultAddress;
98111
private final String logPrefix;
99112

100113
public SubnetAddressTranslator(@NonNull DriverContext context) {
101114
logPrefix = context.getSessionName();
115+
boolean resolveAddresses =
116+
context
117+
.getConfig()
118+
.getDefaultProfile()
119+
.getBoolean(ADDRESS_TRANSLATOR_RESOLVE_ADDRESSES_OPTION, false);
102120
this.subnetAddresses =
103121
context.getConfig().getDefaultProfile()
104122
.getStringMap(ADDRESS_TRANSLATOR_SUBNET_ADDRESSES_OPTION).entrySet().stream()
@@ -109,20 +127,18 @@ public SubnetAddressTranslator(@NonNull DriverContext context) {
109127
// "100.64.0.0/15" -> '"100.64.0.0/15"'
110128
String subnetCIDR = e.getKey().replaceAll("\"", "");
111129
String address = e.getValue();
112-
return new SubnetAddress(subnetCIDR, address);
130+
return new SubnetAddress(subnetCIDR, parseAddress(address, resolveAddresses));
113131
})
114132
.collect(Collectors.toList());
115133
this.defaultAddress =
116134
Optional.ofNullable(
117-
context
118-
.getConfig()
119-
.getDefaultProfile()
120-
.getString(ADDRESS_TRANSLATOR_DEFAULT_ADDRESS_OPTION, null));
121-
this.resolveAddresses =
122-
context.getConfig().getDefaultProfile().getBoolean(RESOLVE_CONTACT_POINTS, true);
135+
context
136+
.getConfig()
137+
.getDefaultProfile()
138+
.getString(ADDRESS_TRANSLATOR_DEFAULT_ADDRESS_OPTION, null))
139+
.map(address -> parseAddress(address, resolveAddresses));
123140

124141
validateSubnetsAreNotOverlapping(this.subnetAddresses);
125-
this.defaultAddress.ifPresent(SubnetAddressTranslator::validateAddress);
126142
}
127143

128144
@NonNull
@@ -131,32 +147,31 @@ public InetSocketAddress translate(@NonNull InetSocketAddress address) {
131147
InetSocketAddress translatedAddress = null;
132148
for (SubnetAddress subnetAddress : subnetAddresses) {
133149
if (subnetAddress.contains(address)) {
134-
translatedAddress = parseAddress(subnetAddress.address, resolveAddresses);
150+
translatedAddress = subnetAddress.address;
135151
}
136152
}
137153
if (translatedAddress == null && defaultAddress.isPresent()) {
138-
translatedAddress = parseAddress(defaultAddress.get(), resolveAddresses);
154+
translatedAddress = defaultAddress.get();
139155
}
140156
if (translatedAddress == null) {
141157
translatedAddress = address;
142158
}
143-
LOG.debug("[{}] Resolved {} to {}", logPrefix, address, translatedAddress);
159+
LOG.debug("[{}] Translated {} to {}", logPrefix, address, translatedAddress);
144160
return translatedAddress;
145161
}
146162

147163
@Override
148164
public void close() {}
149165

150166
@Nullable
151-
private static InetSocketAddress parseAddress(String address, boolean resolve) {
152-
return AddressUtils.extract(address, resolve).iterator().next();
153-
}
154-
155-
private static void validateAddress(String address) {
167+
private InetSocketAddress parseAddress(String address, boolean resolve) {
156168
try {
157-
parseAddress(address, false);
169+
InetSocketAddress parsedAddress = AddressUtils.extract(address, resolve).iterator().next();
170+
LOG.debug("[{}] Parsed {} to {}", logPrefix, address, parsedAddress);
171+
return parsedAddress;
158172
} catch (RuntimeException e) {
159-
throw new IllegalArgumentException("Invalid address: " + address, e);
173+
throw new IllegalArgumentException(
174+
String.format("Invalid address %s (%s)", address, e.getMessage()));
160175
}
161176
}
162177

@@ -177,13 +192,11 @@ private static void validateSubnetsAreNotOverlapping(List<SubnetAddress> subnetA
177192

178193
private static class SubnetAddress {
179194
private final IPAddress subnet;
180-
private final String address;
195+
private final InetSocketAddress address;
181196

182-
private SubnetAddress(String subnetCIDR, String address) {
197+
private SubnetAddress(String subnetCIDR, InetSocketAddress address) {
183198
this.subnet = parseSubnet(subnetCIDR);
184199
this.address = address;
185-
186-
validateAddress(this.address);
187200
}
188201

189202
private static IPAddress parseSubnet(String subnetCIDR) {

core/src/main/resources/reference.conf

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,8 +1044,9 @@ datastax-java-driver {
10441044
# }
10451045
# Optional. When configured, addresses not matching the configured subnets are translated to this address.
10461046
# default-address = "cassandra.datacenter1.com:9042"
1047-
# Note: `advanced.resolve-contact-points` (see below) is used to determine whether to resolve subnet
1048-
# and default address on translation.
1047+
# Whether to resolve the addresses once on initialization (if true) or on each node (re-)connection (if false).
1048+
# If not configured, defaults to false.
1049+
# resolve-addresses = false
10491050
}
10501051

10511052
# Whether to resolve the addresses passed to `basic.contact-points`.

core/src/test/java/com/datastax/oss/driver/internal/core/addresstranslation/SubnetAddressTranslatorTest.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
*/
1818
package com.datastax.oss.driver.internal.core.addresstranslation;
1919

20-
import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.RESOLVE_CONTACT_POINTS;
2120
import static org.assertj.core.api.Assertions.assertThat;
2221
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
2322
import static org.mockito.Mockito.mock;
@@ -135,7 +134,7 @@ public void should_fail_on_subnet_address_without_port() {
135134
DefaultDriverContext context = context(subnetAddresses);
136135
assertThatIllegalArgumentException()
137136
.isThrownBy(() -> new SubnetAddressTranslator(context))
138-
.withMessage("Invalid address: cassandra.datacenter1.com");
137+
.withMessage("Invalid address cassandra.datacenter1.com (expecting format host:port)");
139138
}
140139

141140
@Test
@@ -148,14 +147,13 @@ public void should_fail_on_default_address_without_port() {
148147
.thenReturn("cassandra.com");
149148
assertThatIllegalArgumentException()
150149
.isThrownBy(() -> new SubnetAddressTranslator(context))
151-
.withMessage("Invalid address: cassandra.com");
150+
.withMessage("Invalid address cassandra.com (expecting format host:port)");
152151
}
153152

154153
private static DefaultDriverContext context(Map<String, String> subnetAddresses) {
155154
DriverExecutionProfile profile = mock(DriverExecutionProfile.class);
156155
when(profile.getStringMap(SubnetAddressTranslator.ADDRESS_TRANSLATOR_SUBNET_ADDRESSES_OPTION))
157156
.thenReturn(subnetAddresses);
158-
when(profile.getBoolean(RESOLVE_CONTACT_POINTS, true)).thenReturn(false);
159157
return MockedDriverContextFactory.defaultDriverContext(Optional.of(profile));
160158
}
161159
}

manual/core/address_resolution/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,9 @@ datastax-java-driver.advanced.address-translator {
159159
}
160160
# Optional. When configured, addresses not matching the configured subnets are translated to this address.
161161
default-address = "cassandra.datacenter1.com:9042"
162-
# Note: `advanced.resolve-contact-points` is used to determine whether to resolve subnet and default address
163-
# on translation.
162+
# Whether to resolve the addresses once on initialization (if true) or on each node (re-)connection (if false).
163+
# If not configured, defaults to false.
164+
resolve-addresses = false
164165
}
165166
```
166167

0 commit comments

Comments
 (0)