Skip to content

Commit 65d2c19

Browse files
authored
JAVA-3022: Implementation of address translator for fixed hostname (#1597)
1 parent 43a6ac5 commit 65d2c19

File tree

3 files changed

+121
-0
lines changed

3 files changed

+121
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright DataStax, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.datastax.oss.driver.internal.core.addresstranslation;
17+
18+
import com.datastax.oss.driver.api.core.addresstranslation.AddressTranslator;
19+
import com.datastax.oss.driver.api.core.config.DriverOption;
20+
import com.datastax.oss.driver.api.core.context.DriverContext;
21+
import edu.umd.cs.findbugs.annotations.NonNull;
22+
import java.net.InetSocketAddress;
23+
import org.slf4j.Logger;
24+
import org.slf4j.LoggerFactory;
25+
26+
/**
27+
* This translator always returns same hostname, no matter what IP address a node has but still
28+
* using its native transport port.
29+
*
30+
* <p>The translator can be used for scenarios when all nodes are behind some kind of proxy, and it
31+
* is not tailored for one concrete use case. One can use this, for example, for AWS PrivateLink as
32+
* all nodes would be exposed to consumer - behind one hostname pointing to AWS Endpoint.
33+
*/
34+
public class FixedHostNameAddressTranslator implements AddressTranslator {
35+
36+
private static final Logger LOG = LoggerFactory.getLogger(FixedHostNameAddressTranslator.class);
37+
38+
public static final String ADDRESS_TRANSLATOR_ADVERTISED_HOSTNAME =
39+
"advanced.address-translator.advertised-hostname";
40+
41+
public static DriverOption ADDRESS_TRANSLATOR_ADVERTISED_HOSTNAME_OPTION =
42+
new DriverOption() {
43+
@NonNull
44+
@Override
45+
public String getPath() {
46+
return ADDRESS_TRANSLATOR_ADVERTISED_HOSTNAME;
47+
}
48+
};
49+
50+
private final String advertisedHostname;
51+
private final String logPrefix;
52+
53+
public FixedHostNameAddressTranslator(@NonNull DriverContext context) {
54+
logPrefix = context.getSessionName();
55+
advertisedHostname =
56+
context
57+
.getConfig()
58+
.getDefaultProfile()
59+
.getString(ADDRESS_TRANSLATOR_ADVERTISED_HOSTNAME_OPTION);
60+
}
61+
62+
@NonNull
63+
@Override
64+
public InetSocketAddress translate(@NonNull InetSocketAddress address) {
65+
final int port = address.getPort();
66+
LOG.debug("[{}] Resolved {}:{} to {}:{}", logPrefix, address, port, advertisedHostname, port);
67+
return new InetSocketAddress(advertisedHostname, port);
68+
}
69+
70+
@Override
71+
public void close() {}
72+
}

core/src/main/resources/reference.conf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -990,13 +990,16 @@ datastax-java-driver {
990990
#
991991
# The driver provides the following implementations out of the box:
992992
# - PassThroughAddressTranslator: returns all addresses unchanged
993+
# - FixedHostNameAddressTranslator: translates all addresses to a specific hostname.
993994
# - Ec2MultiRegionAddressTranslator: suitable for an Amazon multi-region EC2 deployment where
994995
# clients are also deployed in EC2. It optimizes network costs by favoring private IPs over
995996
# public ones whenever possible.
996997
#
997998
# You can also specify a custom class that implements AddressTranslator and has a public
998999
# constructor with a DriverContext argument.
9991000
class = PassThroughAddressTranslator
1001+
# This property has to be set only in case you use FixedHostNameAddressTranslator.
1002+
# advertised-hostname = mycustomhostname
10001003
}
10011004

10021005
# Whether to resolve the addresses passed to `basic.contact-points`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright DataStax, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.datastax.oss.driver.internal.core.addresstranslation;
17+
18+
import static org.assertj.core.api.Assertions.assertThat;
19+
import static org.mockito.Mockito.mock;
20+
import static org.mockito.Mockito.when;
21+
22+
import com.datastax.oss.driver.api.core.config.DriverExecutionProfile;
23+
import com.datastax.oss.driver.internal.core.context.DefaultDriverContext;
24+
import com.datastax.oss.driver.internal.core.context.MockedDriverContextFactory;
25+
import java.net.InetSocketAddress;
26+
import java.util.Optional;
27+
import org.junit.Test;
28+
29+
public class FixedHostNameAddressTranslatorTest {
30+
31+
@Test
32+
public void should_translate_address() {
33+
DriverExecutionProfile defaultProfile = mock(DriverExecutionProfile.class);
34+
when(defaultProfile.getString(
35+
FixedHostNameAddressTranslator.ADDRESS_TRANSLATOR_ADVERTISED_HOSTNAME_OPTION))
36+
.thenReturn("myaddress");
37+
DefaultDriverContext defaultDriverContext =
38+
MockedDriverContextFactory.defaultDriverContext(Optional.of(defaultProfile));
39+
40+
FixedHostNameAddressTranslator translator =
41+
new FixedHostNameAddressTranslator(defaultDriverContext);
42+
InetSocketAddress address = new InetSocketAddress("192.0.2.5", 6061);
43+
44+
assertThat(translator.translate(address)).isEqualTo(new InetSocketAddress("myaddress", 6061));
45+
}
46+
}

0 commit comments

Comments
 (0)