Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,15 @@ void buildingWithSingleResolvedHost() throws Exception {
assertThat(b.endpointGroup()).isEqualTo(Endpoint.of("1.2.3.4", 36462));
}

@Test
void buildingWithSingleResolvedHostWithTls() throws Exception {
final ArmeriaCentralDogmaBuilder b = new ArmeriaCentralDogmaBuilder();
b.healthCheckIntervalMillis(0);
b.useTls();
b.host("1.2.3.4");
assertThat(b.endpointGroup()).isEqualTo(Endpoint.of("1.2.3.4", 443));
}

@Test
void buildingSingleResolvedHostWithHealthCheck() throws Exception {
final ArmeriaCentralDogmaBuilder b = new ArmeriaCentralDogmaBuilder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ public abstract class AbstractCentralDogmaBuilder<B extends AbstractCentralDogma
ImmutableList.of(TEST_PROFILE_RESOURCE_PATH, PROFILE_RESOURCE_PATH);

static final int DEFAULT_PORT = 36462;
static final int DEFAULT_TLS_PORT = 443;

// A sentinel meaning 'use DEFAULT_PORT or DEFAULT_TLS_PORT depending on useTls', resolved in hosts().
private static final int UNSPECIFIED_PORT = 0;

private static final int DEFAULT_MAX_NUM_RETRIES_ON_REPLICATION_LAG = 5;
private static final int DEFAULT_RETRY_INTERVAL_ON_REPLICATION_LAG_SECONDS = 2;
Expand Down Expand Up @@ -107,12 +111,13 @@ public final B uri(String uri) {

/**
* Adds the host name or IP address of the Central Dogma Server and uses the default port number of
* {@value #DEFAULT_PORT}.
* {@value #DEFAULT_PORT}. If TLS is enabled with {@link #useTls()}, the default port number of
* {@value #DEFAULT_TLS_PORT} is used instead.
*
* @param host the host name or IP address of the Central Dogma server
*/
public final B host(String host) {
return host(host, DEFAULT_PORT);
return host0(host, UNSPECIFIED_PORT);
}

/**
Expand All @@ -123,8 +128,13 @@ public final B host(String host) {
*/
public final B host(String host, int port) {
requireNonNull(host, "host");
checkArgument(!host.startsWith("group:"), "host: %s (must not start with 'group:')", host);
checkArgument(port >= 1 && port < 65536, "port: %s (expected: 1 .. 65535)", port);
return host0(host, port);
}

private B host0(String host, int port) {
requireNonNull(host, "host");
checkArgument(!host.startsWith("group:"), "host: %s (must not start with 'group:')", host);

final InetSocketAddress addr = newEndpoint(host, port);
checkState(selectedProfile == null, "profile() and host() cannot be used together.");
Expand All @@ -133,14 +143,16 @@ public final B host(String host, int port) {
}

/**
* Sets the client to use TLS.
* Sets the client to use TLS. A host added via {@link #host(String)} without a port number will use
* the default port number of {@value #DEFAULT_TLS_PORT}.
*/
public final B useTls() {
return useTls(true);
}

/**
* Sets whether the client uses TLS or not.
* Sets whether the client uses TLS or not. If TLS is enabled, a host added via {@link #host(String)}
* without a port number will use the default port number of {@value #DEFAULT_TLS_PORT}.
*/
public final B useTls(boolean useTls) {
checkState(selectedProfile == null, "useTls() cannot be called once a profile is selected.");
Expand Down Expand Up @@ -337,9 +349,21 @@ protected final String selectedProfile() {

/**
* Returns the hosts added via {@link #host(String, int)} or {@link #profile(String...)}.
* A host added via {@link #host(String)} without a port number gets the default port number of
* {@value #DEFAULT_PORT}, or {@value #DEFAULT_TLS_PORT} if TLS is enabled with {@link #useTls()}.
*/
protected final Set<InetSocketAddress> hosts() {
return hosts;
final int defaultPort = useTls ? DEFAULT_TLS_PORT : DEFAULT_PORT;
final ImmutableSet.Builder<InetSocketAddress> builder =
ImmutableSet.builderWithExpectedSize(hosts.size());
for (InetSocketAddress addr : hosts) {
if (addr.getPort() == UNSPECIFIED_PORT) {
builder.add(newEndpoint(addr.getHostString(), defaultPort));
} else {
builder.add(addr);
}
}
return builder.build();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,69 @@ void singleHost() {
assertThat(b.hosts()).containsExactly(InetSocketAddress.createUnresolved("foo", 36462));
}

@Test
void tlsHostWithoutPort() {
// useTls() before host()
final CentralDogmaBuilder b1 = new CentralDogmaBuilder();
b1.useTls();
b1.host("foo");
assertThat(b1.hosts()).containsExactly(InetSocketAddress.createUnresolved("foo", 443));

// useTls() after host()
final CentralDogmaBuilder b2 = new CentralDogmaBuilder();
b2.host("foo");
b2.useTls();
assertThat(b2.hosts()).containsExactly(InetSocketAddress.createUnresolved("foo", 443));

// An IP address without a port number
final CentralDogmaBuilder b3 = new CentralDogmaBuilder();
b3.host("192.168.0.1");
b3.useTls();
assertThat(b3.hosts()).containsExactly(new InetSocketAddress("192.168.0.1", 443));

// An IPv6 address without a port number
final CentralDogmaBuilder b4 = new CentralDogmaBuilder();
b4.host("::1");
b4.useTls();
assertThat(b4.hosts()).containsExactly(new InetSocketAddress("::1", 443));

// useTls(false) keeps the default cleartext port.
final CentralDogmaBuilder b5 = new CentralDogmaBuilder();
b5.host("foo");
b5.useTls(false);
assertThat(b5.hosts()).containsExactly(InetSocketAddress.createUnresolved("foo", 36462));
}

@Test
void tlsHostWithExplicitPort() {
final CentralDogmaBuilder b = new CentralDogmaBuilder();
b.host("foo", 36462);
b.useTls();
assertThat(b.hosts()).containsExactly(InetSocketAddress.createUnresolved("foo", 36462));
}

@Test
void tlsHostDeduplication() {
// A host added with and without an explicit port collapses into one entry once resolved.
final CentralDogmaBuilder b = new CentralDogmaBuilder();
b.host("foo");
b.host("foo", 443);
b.useTls();
assertThat(b.hosts()).containsExactly(InetSocketAddress.createUnresolved("foo", 443));
}

@Test
void uriWithoutPort() {
final CentralDogmaBuilder b1 = new CentralDogmaBuilder();
b1.uri("tbinary+https://foo/cd/thrift/v1");
b1.useTls();
assertThat(b1.hosts()).containsExactly(InetSocketAddress.createUnresolved("foo", 443));

final CentralDogmaBuilder b2 = new CentralDogmaBuilder();
b2.uri("tbinary+http://foo/cd/thrift/v1");
assertThat(b2.hosts()).containsExactly(InetSocketAddress.createUnresolved("foo", 36462));
}

@Test
void multipleHosts() {
final CentralDogmaBuilder b = new CentralDogmaBuilder();
Expand Down
3 changes: 2 additions & 1 deletion site/src/sphinx/client-java.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ First, we should create a new instance of :api:`com.linecorp.centraldogma.client
CentralDogma dogma = new ArmeriaCentralDogmaBuilder()
.host("127.0.0.1")
.build();
// You can specify an alternative port or enable TLS as well:
// You can specify an alternative port or enable TLS as well.
// When TLS is enabled, the default port 443 is used if unspecified.
CentralDogma dogma2 = new ArmeriaCentralDogmaBuilder()
.useTls() // Enable TLS.
.host("example.com", 8443) // Use port 8443.
Expand Down
Loading