Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Curator Service Discovery and Spring Cloud ZooKeeper #2749

Merged
merged 16 commits into from Jun 3, 2020
Expand Up @@ -24,20 +24,20 @@
import com.linecorp.armeria.client.Endpoint;
import com.linecorp.armeria.internal.common.zookeeper.CuratorXNodeValueCodec;

final class CuratorXZookeeperDiscoverySpec implements ZookeeperDiscoverySpec {
final class CuratorDiscoverySpec implements ZookeeperDiscoverySpec {

private final String serviceName;
private final String path;
private final Function<? super ServiceInstance<?>, Endpoint> converter;

CuratorXZookeeperDiscoverySpec(
CuratorDiscoverySpec(
String serviceName, Function<? super ServiceInstance<?>, Endpoint> converter) {
this.serviceName = serviceName;
path = '/' + serviceName;
trustin marked this conversation as resolved.
Show resolved Hide resolved
this.converter = converter;
}

@Override
public String path() {
return '/' + serviceName;
return path;
}

@Override
Expand All @@ -48,7 +48,7 @@ public Endpoint decode(byte[] data) {
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("serviceName", serviceName)
.add("path", path)
.add("converter", converter)
.toString();
}
Expand Down
Expand Up @@ -28,9 +28,9 @@

/**
* Builds a {@link ZookeeperDiscoverySpec} for
* <a href="https://curator.apache.org/curator-x-discovery/index.html">Curator-X-Discovery</a>.
* <a href="https://curator.apache.org/curator-x-discovery/index.html">Curator Service Discovery</a>.
*/
public final class CuratorXZookeeperDiscoverySpecBuilder {
public final class CuratorDiscoverySpecBuilder {

private final String serviceName;
@Nullable
Expand All @@ -43,15 +43,15 @@ public final class CuratorXZookeeperDiscoverySpecBuilder {
/**
* Creates a new instance.
*/
CuratorXZookeeperDiscoverySpecBuilder(String serviceName) {
CuratorDiscoverySpecBuilder(String serviceName) {
this.serviceName = requireNonNull(serviceName, "serviceName");
}

/**
* Sets the specified instance ID. If this is set, the {@link ZooKeeperEndpointGroup} will only connect to
* the instance.
*/
public CuratorXZookeeperDiscoverySpecBuilder instanceId(String instanceId) {
public CuratorDiscoverySpecBuilder instanceId(String instanceId) {
checkState(converter == null, "converter() and instanceId() are mutually exclusive.");
this.instanceId = requireNonNull(instanceId, "instanceId");
return this;
Expand All @@ -60,7 +60,7 @@ public CuratorXZookeeperDiscoverySpecBuilder instanceId(String instanceId) {
/**
* Sets whether to connect an {@link Endpoint} using {@code sslPort} of {@link ServiceInstance}.
*/
public CuratorXZookeeperDiscoverySpecBuilder useSsl(boolean useSsl) {
public CuratorDiscoverySpecBuilder useSsl(boolean useSsl) {
checkState(converter == null, "converter() and useSsl() are mutually exclusive.");
this.useSsl = useSsl;
return this;
Expand All @@ -70,7 +70,7 @@ public CuratorXZookeeperDiscoverySpecBuilder useSsl(boolean useSsl) {
* Sets the specified converter to convert a {@link ServiceInstance} into an {@link Endpoint}.
* If you don't want to connect to the service, you can simply return {@code null} in the converter.
*/
public CuratorXZookeeperDiscoverySpecBuilder converter(
public CuratorDiscoverySpecBuilder converter(
Function<? super ServiceInstance<?>, Endpoint> converter) {
checkState(instanceId == null, "converter() and instanceId() are mutually exclusive.");
checkState(useSsl == null, "converter() and useSsl() are mutually exclusive.");
Expand Down Expand Up @@ -104,6 +104,6 @@ private Function<? super ServiceInstance<?>, Endpoint> converter() {
* Returns a newly-created {@link ZookeeperDiscoverySpec} based on the properties set so far.
*/
public ZookeeperDiscoverySpec build() {
return new CuratorXZookeeperDiscoverySpec(serviceName, converter());
return new CuratorDiscoverySpec(serviceName, converter());
}
}
Expand Up @@ -30,21 +30,21 @@ public interface ZookeeperDiscoverySpec {

/**
* Returns a {@link ZookeeperDiscoverySpec} that is compatible with
* <a href="https://curator.apache.org/curator-x-discovery/index.html">Curator-X-Discovery</a>.
* This is also, compatible with
* <a href="https://curator.apache.org/curator-x-discovery/index.html">Curator Service Discovery</a>.
* This is also compatible with
* <a href="https://cloud.spring.io/spring-cloud-zookeeper/reference/html/">Spring Cloud Zookeeper</a>.
*/
static ZookeeperDiscoverySpec ofCuratorX(String serviceName) {
return builderForCuratorX(serviceName).build();
static ZookeeperDiscoverySpec curator(String serviceName) {
return builderForCurator(serviceName).build();
}

/**
* Returns a new {@link CuratorXZookeeperDiscoverySpecBuilder}. The specification is compatible with
* <a href="https://curator.apache.org/curator-x-discovery/index.html">Curator-X-Discovery</a> and
* Returns a new {@link CuratorDiscoverySpecBuilder}. The specification is compatible with
* <a href="https://curator.apache.org/curator-x-discovery/index.html">Curator Service Discovery</a> and
* <a href="https://cloud.spring.io/spring-cloud-zookeeper/reference/html/">Spring Cloud Zookeeper</a>.
*/
static CuratorXZookeeperDiscoverySpecBuilder builderForCuratorX(String serviceName) {
return new CuratorXZookeeperDiscoverySpecBuilder(serviceName);
static CuratorDiscoverySpecBuilder builderForCurator(String serviceName) {
return new CuratorDiscoverySpecBuilder(serviceName);
}

/**
Expand All @@ -59,7 +59,7 @@ static CuratorXZookeeperDiscoverySpecBuilder builderForCuratorX(String serviceNa
* </ul>
* Note that the port number must be specified when you want to specify the weight.
*/
static ZookeeperDiscoverySpec ofLegacy() {
static ZookeeperDiscoverySpec legacy() {
return LegacyZookeeperDiscoverySpec.INSTANCE;
}

Expand Down
Expand Up @@ -29,7 +29,7 @@
import com.linecorp.armeria.client.endpoint.EndpointGroupException;

/**
* A codec for Curator-X-Discovery.
* A codec for Curator Service Discovery.
*/
public enum CuratorXNodeValueCodec {
INSTANCE;
Expand Down
Expand Up @@ -21,14 +21,14 @@

import com.linecorp.armeria.internal.common.zookeeper.CuratorXNodeValueCodec;

final class CuratorXZookeeperRegistrationSpec implements ZookeeperRegistrationSpec {
final class CuratorRegistrationSpec implements ZookeeperRegistrationSpec {

private final ServiceInstance<?> serviceInstance;
private final String pathForRegistration;
private final String path;

CuratorXZookeeperRegistrationSpec(ServiceInstance<?> serviceInstance) {
CuratorRegistrationSpec(ServiceInstance<?> serviceInstance) {
this.serviceInstance = serviceInstance;
pathForRegistration = '/' + serviceInstance.getName() + '/' + serviceInstance.getId();
path = '/' + serviceInstance.getName() + '/' + serviceInstance.getId();
}

ServiceInstance<?> serviceInstance() {
Expand All @@ -37,7 +37,7 @@ ServiceInstance<?> serviceInstance() {

@Override
public String path() {
return pathForRegistration;
return path;
}

@Override
Expand All @@ -49,7 +49,7 @@ public byte[] encodedInstance() {
public String toString() {
return MoreObjects.toStringHelper(this)
.add("serviceInstance", serviceInstance)
.add("pathForRegistration", pathForRegistration)
.add("path", path)
.toString();
}
}
Expand Up @@ -28,9 +28,9 @@

/**
* Builds an {@link ZookeeperRegistrationSpec} for
* <a href="https://curator.apache.org/curator-x-discovery/index.html">Curator-X-Discovery</a>..
* <a href="https://curator.apache.org/curator-x-discovery/index.html">Curator Service Discovery</a>.
*/
public final class CuratorXZookeeperRegistrationSpecBuilder {
public final class CuratorRegistrationSpecBuilder {

private final String serviceName;
@Nullable
Expand All @@ -50,22 +50,22 @@ public final class CuratorXZookeeperRegistrationSpecBuilder {
/**
* Creates a new instance.
*/
CuratorXZookeeperRegistrationSpecBuilder(String serviceName) {
CuratorRegistrationSpecBuilder(String serviceName) {
this.serviceName = requireNonNull(serviceName, "serviceName");
}

/**
* Sets the service address.
*/
public CuratorXZookeeperRegistrationSpecBuilder serviceAddress(String serviceAddress) {
public CuratorRegistrationSpecBuilder serviceAddress(String serviceAddress) {
this.serviceAddress = requireNonNull(serviceAddress, "serviceAddress");
return this;
}

/**
* Sets the port.
*/
public CuratorXZookeeperRegistrationSpecBuilder port(int port) {
public CuratorRegistrationSpecBuilder port(int port) {
checkArgument(port > 0, "port: %s (expected: > 0)", port);
this.port = port;
return this;
Expand All @@ -74,7 +74,7 @@ public CuratorXZookeeperRegistrationSpecBuilder port(int port) {
/**
* Sets the SSL port.
*/
public CuratorXZookeeperRegistrationSpecBuilder sslPort(int sslPort) {
public CuratorRegistrationSpecBuilder sslPort(int sslPort) {
checkArgument(sslPort > 0, "sslPort: %s (expected: > 0)", sslPort);
this.sslPort = sslPort;
return this;
Expand All @@ -83,31 +83,31 @@ public CuratorXZookeeperRegistrationSpecBuilder sslPort(int sslPort) {
/**
* Sets the service ID.
*/
public CuratorXZookeeperRegistrationSpecBuilder serviceId(String serviceId) {
public CuratorRegistrationSpecBuilder serviceId(String serviceId) {
this.serviceId = requireNonNull(serviceId, "serviceId");
return this;
}

/**
* Sets the payload.
*/
public <T> CuratorXZookeeperRegistrationSpecBuilder payload(T payload) {
public <T> CuratorRegistrationSpecBuilder payload(T payload) {
this.payload = requireNonNull(payload, "payload");
return this;
}

/**
* Sets the {@link ServiceType}.
*/
public CuratorXZookeeperRegistrationSpecBuilder serviceType(ServiceType serviceType) {
public CuratorRegistrationSpecBuilder serviceType(ServiceType serviceType) {
this.serviceType = requireNonNull(serviceType, "serviceType");
return this;
}

/**
* Sets the {@link UriSpec}.
*/
public CuratorXZookeeperRegistrationSpecBuilder uriSpec(UriSpec uriSpec) {
public CuratorRegistrationSpecBuilder uriSpec(UriSpec uriSpec) {
this.uriSpec = requireNonNull(uriSpec, "uriSpec");
return this;
}
Expand All @@ -120,6 +120,6 @@ public ZookeeperRegistrationSpec build() {
final ServiceInstance<?> serviceInstance =
new ServiceInstance<>(serviceName, serviceId, serviceAddress, port, sslPort,
payload, System.currentTimeMillis(), serviceType, uriSpec);
return new CuratorXZookeeperRegistrationSpec(serviceInstance);
return new CuratorRegistrationSpec(serviceInstance);
}
}
Expand Up @@ -25,11 +25,11 @@
final class LegacyZookeeperRegistrationSpec implements ZookeeperRegistrationSpec {

private final Endpoint endpoint;
private final String pathForRegistration;
private final String path;

LegacyZookeeperRegistrationSpec(Endpoint endpoint) {
this.endpoint = requireNonNull(endpoint, "endpoint");
pathForRegistration = '/' + endpoint.host() + '_' + endpoint.port();
path = '/' + endpoint.host() + '_' + endpoint.port();
}

Endpoint endpoint() {
Expand All @@ -38,7 +38,7 @@ Endpoint endpoint() {

@Override
public String path() {
return pathForRegistration;
return path;
}

@Override
Expand All @@ -50,7 +50,7 @@ public byte[] encodedInstance() {
public String toString() {
return MoreObjects.toStringHelper(this)
.add("endpoint", endpoint)
.add("pathForRegistration", pathForRegistration)
.add("path", path)
.toString();
}
}
Expand Up @@ -51,7 +51,7 @@ public final class ZooKeeperUpdatingListener extends ServerListenerAdapter {
* Creates a ZooKeeper server listener, which registers the {@link Server} into ZooKeeper.
*
* <p>If you need a fully customized {@link ZooKeeperUpdatingListener} instance, use
* {@link #builder(String, String)} instead.
* {@link #builder(String, String, ZookeeperRegistrationSpec)} instead.
*
* @param zkConnectionStr the ZooKeeper connection string
* @param zNodePath the ZooKeeper node to register
Expand All @@ -66,7 +66,7 @@ public static ZooKeeperUpdatingListener of(
* Creates a ZooKeeper server listener, which registers the {@link Server} into ZooKeeper.
*
* <p>If you need a fully customized {@link ZooKeeperUpdatingListener} instance, use
* {@link #builder(CuratorFramework, String)} instead.
* {@link #builder(CuratorFramework, String, ZookeeperRegistrationSpec)} instead.
*
* @param client the curator framework instance
* @param zNodePath the ZooKeeper node to register
Expand Down Expand Up @@ -134,10 +134,10 @@ private static ZookeeperRegistrationSpec fillAndCreateNewRegistrationSpec(
}
final ServerPort serverPort = server.activePort();
assert serverPort != null;
return ZookeeperRegistrationSpec.ofLegacy(endpoint.withPort(serverPort.localAddress().getPort()));
} else if (spec instanceof CuratorXZookeeperRegistrationSpec) {
return ZookeeperRegistrationSpec.legacy(endpoint.withPort(serverPort.localAddress().getPort()));
} else if (spec instanceof CuratorRegistrationSpec) {
final ServiceInstance<?> serviceInstance =
((CuratorXZookeeperRegistrationSpec) spec).serviceInstance();
((CuratorRegistrationSpec) spec).serviceInstance();
return fillAndCreateNewRegistrationSpec(serviceInstance, server);
} else {
return spec;
Expand All @@ -146,8 +146,8 @@ private static ZookeeperRegistrationSpec fillAndCreateNewRegistrationSpec(

private static ZookeeperRegistrationSpec fillAndCreateNewRegistrationSpec(
ServiceInstance<?> serviceInstance, Server server) {
final CuratorXZookeeperRegistrationSpecBuilder builder =
ZookeeperRegistrationSpec.builderForCuratorX(serviceInstance.getName());
final CuratorRegistrationSpecBuilder builder =
ZookeeperRegistrationSpec.builderForCurator(serviceInstance.getName());
builder.serviceId(serviceInstance.getId());
final String address;
if (serviceInstance.getAddress() != null) {
Expand Down
Expand Up @@ -23,36 +23,22 @@
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory.Builder;

import com.linecorp.armeria.client.Endpoint;
import com.linecorp.armeria.common.util.SystemInfo;
import com.linecorp.armeria.common.zookeeper.AbstractCuratorFrameworkBuilder;
import com.linecorp.armeria.server.Server;

/**
* Builds a new {@link ZooKeeperUpdatingListener}, which registers the server to a ZooKeeper cluster.
* <pre>{@code
* ZooKeeperUpdatingListener listener =
* ZooKeeperUpdatingListener.builder("myZooKeeperHost:2181", "/myProductionEndpoints")
* .sessionTimeoutMillis(10000)
* .build();
* ServerBuilder sb = Server.builder();
* sb.addListener(listener);
* }</pre>
* This registers the {@link Server} with the information that are automatically found from
* {@link SystemInfo#defaultNonLoopbackIpV4Address()} and {@link Server#activePort()} in the form as specified
* in {@link ZookeeperRegistrationSpec#ofLegacy(Endpoint)}.
* If you want to use
* <a href="https://curator.apache.org/curator-x-discovery/index.html">Curator-X-Discovery</a>, please use
* {@link ZookeeperRegistrationSpec#ofCuratorXRegistration(String)}.
* <pre>{@code
* RegistrationSpec spec = RegistrationSpec.ofCuratorXInstance("myServices");
* ZookeeperRegistrationSpec spec = ZookeeperRegistrationSpec.curator("myServices");
* ZooKeeperUpdatingListener listener =
* ZooKeeperUpdatingListener.builder("myZooKeeperHost:2181", "/myProductionEndpoints", spec)
* .sessionTimeoutMillis(10000)
* .build();
* ServerBuilder sb = Server.builder();
* sb.addListener(listener);
* }</pre>
* This registers the {@link Server} using the format compatible with
* <a href="https://curator.apache.org/curator-x-discovery/index.html">Curator Service Discovery</a>.
*
* <p>You can also specify the {@link CuratorFramework} instance to use. In this case,
* invoking {@link #connectTimeout(Duration)}, {@link #connectTimeoutMillis(long)},
Expand Down