(zk-registry) Filter out phantom addresses in the registry

The change adds a hostname validation step to remove endpoints from the ZkServiceRegistry when they do not resolve.  This is a scenario that primarily happens when running in docker, and the entire system is started and stopped.
This commit is contained in:
Viktor Lofgren 2024-02-20 18:09:11 +01:00
parent a69c0b2718
commit 73947d9eca
2 changed files with 40 additions and 9 deletions

View File

@ -192,10 +192,18 @@ public class ZkServiceRegistry implements ServiceRegistryIf {
.getData()
.forPath(ZKPaths.makePath(restRoot, uuid));
String hostAndPort = new String(data);
ret.add(RestEndpoint
var address = RestEndpoint
.parse(hostAndPort)
.asInstance(UUID.fromString(uuid))
);
.asInstance(UUID.fromString(uuid));
// Ensure that the address is resolvable
// (this reduces the risk of exceptions when trying to connect to the service)
if (!address.endpoint().validateHost()) {
logger.warn("Omitting stale address {}, address does not resolve", address);
continue;
}
ret.add(address);
}
@ -221,11 +229,20 @@ public class ZkServiceRegistry implements ServiceRegistryIf {
byte[] data = curatorFramework
.getData()
.forPath(ZKPaths.makePath(restRoot, uuid));
String hostAndPort = new String(data);
ret.add(GrpcEndpoint
var address = GrpcEndpoint
.parse(hostAndPort)
.asInstance(UUID.fromString(uuid))
);
.asInstance(UUID.fromString(uuid));
// Ensure that the address is resolvable
// (this reduces the risk of exceptions when trying to connect to the service)
if (!address.endpoint().validateHost()) {
logger.warn("Omitting stale address {}, address does not resolve", address);
continue;
}
ret.add(address);
}

View File

@ -3,9 +3,7 @@ package nu.marginalia.service.discovery.property;
import lombok.SneakyThrows;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.URL;
import java.net.*;
import java.util.UUID;
public sealed interface ServiceEndpoint {
@ -17,6 +15,22 @@ public sealed interface ServiceEndpoint {
return new InetSocketAddress(host(), port());
}
/** Validate the host by checking if it is a valid IP address or a hostname that can be resolved.
*
* @return true if the host is a valid
*/
default boolean validateHost() {
try {
// Throws UnknownHostException if the host is not a valid IP address or hostname
// (this should not be slow since the DNS lookup should be local, and if it isn't;
// should be cached by the OS or the JVM)
InetAddress.getByName(host());
return true;
} catch (UnknownHostException e) {
return false;
}
}
static ServiceEndpoint forSchema(ApiSchema schema, String host, int port) {
return switch (schema) {
case REST -> new RestEndpoint(host, port);