1
0

[HUDI-3827] Promote the inetAddress picking strategy for NetworkUtils#getHostname (#5260)

This commit is contained in:
Danny Chan
2022-04-08 14:33:56 +08:00
committed by GitHub
parent 7a6272fba1
commit 67215abaf0

View File

@@ -22,11 +22,14 @@ import org.apache.hudi.exception.HoodieException;
import java.io.IOException;
import java.net.DatagramSocket;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* A utility class for network.
@@ -34,28 +37,51 @@ import java.util.Enumeration;
public class NetworkUtils {
public static synchronized String getHostname() {
try {
Enumeration<NetworkInterface> networkInterfaceEnumeration = NetworkInterface.getNetworkInterfaces();
while (networkInterfaceEnumeration.hasMoreElements()) {
for (InterfaceAddress interfaceAddress : networkInterfaceEnumeration.nextElement().getInterfaceAddresses()) {
InetAddress address = interfaceAddress.getAddress();
if (!address.isLinkLocalAddress() && !address.isLoopbackAddress() && !address.isAnyLocalAddress()) {
return address.getHostAddress();
}
}
}
} catch (SocketException e) {
throw new HoodieException("Unable to find server port", e);
}
// fallback
InetAddress localAddress;
try (DatagramSocket s = new DatagramSocket()) {
// see https://stackoverflow.com/questions/9481865/getting-the-ip-address-of-the-current-machine-using-java
// for details.
s.connect(InetAddress.getByName("8.8.8.8"), 10002);
return s.getLocalAddress().getHostAddress();
localAddress = s.getLocalAddress();
if (validAddress(localAddress)) {
return localAddress.getHostAddress();
}
} catch (IOException e) {
throw new HoodieException("Unable to find server port", e);
}
// fallback
try {
List<NetworkInterface> activeNetworkIFs = Collections.list(NetworkInterface.getNetworkInterfaces());
// On unix-like system, getNetworkInterfaces returns ifs in reverse order
// compared to ifconfig output order,
// pick ip address following system output order.
Collections.reverse(activeNetworkIFs);
for (NetworkInterface ni : activeNetworkIFs) {
List<InetAddress> addresses = Collections.list(ni.getInetAddresses()).stream()
.filter(NetworkUtils::validAddress)
.collect(Collectors.toList());
if (addresses.size() > 0) {
// IPv4 has higher priority
InetAddress address = addresses.stream()
.filter(addr -> addr instanceof Inet4Address).findAny()
.orElse(addresses.get(0));
try {
// Inet6Address.toHostName may add interface at the end if it knows about it
return InetAddress.getByAddress(address.getAddress()).getHostAddress();
} catch (UnknownHostException e) {
throw new HoodieException("Unable to fetch raw IP address for: " + address);
}
}
}
return localAddress.getHostAddress();
} catch (SocketException e) {
throw new HoodieException("Unable to find server port", e);
}
}
private static boolean validAddress(InetAddress address) {
return !(address.isLinkLocalAddress() || address.isLoopbackAddress() || address.isAnyLocalAddress());
}
}