(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:
parent
a69c0b2718
commit
73947d9eca
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user