Usage:
try {
String[] ips = {"192.168.1.10"};
String hostName = "myhost.com";
InetAddressCacheUtil.setInetAddressCache(hostName, ips, InetAddressCacheUtil.NEVER_EXPIRATION);
}catch (Exception ex){
...
}
Code:
package io.kafka.connect.log.anlaytics.util;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentSkipListSet;
public class InetAddressCacheUtil {
public static final long NEVER_EXPIRATION = Long.MAX_VALUE;
public static void setInetAddressCache(String host, String[] ips, long expireMillis) throws Exception {
Object cachedAddresses = newCachedAddresses(host, ips, expireMillis);
getCacheOfInetAddress().put(host, cachedAddresses);
getInetAddressExpiries().add(cachedAddresses);
}
private static Object newCachedAddresses(String host, String[] ips, long expiration)
throws ClassNotFoundException, UnknownHostException, IllegalAccessException,
InvocationTargetException, InstantiationException {
final Class<?> clazz = Class.forName("java.net.InetAddress$CachedAddresses");
final Constructor<?> constructor = clazz.getDeclaredConstructors()[0];
constructor.setAccessible(true);
return constructor.newInstance(host, toInetAddressArray(host, ips), expiration);
}
private static ConcurrentMap<String, Object> getCacheOfInetAddress()
throws NoSuchFieldException, IllegalAccessException {
return (ConcurrentMap<String, Object>) getAddressCacheAndExpirySet()[0];
}
private static Object[] getAddressCacheAndExpirySet() throws NoSuchFieldException, IllegalAccessException {
Object[] addressCacheAndExpirySet = null;
final Field cacheField = InetAddress.class.getDeclaredField("cache");
cacheField.setAccessible(true);
final Field expirySetField = InetAddress.class.getDeclaredField("expirySet");
expirySetField.setAccessible(true);
addressCacheAndExpirySet = new Object[]{
cacheField.get(InetAddress.class),
expirySetField.get(InetAddress.class)
};
return addressCacheAndExpirySet;
}
private static ConcurrentSkipListSet<Object> getInetAddressExpiries()
throws NoSuchFieldException, IllegalAccessException {
return (ConcurrentSkipListSet<Object>) getAddressCacheAndExpirySet()[1];
}
static InetAddress[] toInetAddressArray(String host, String[] ips) throws UnknownHostException {
InetAddress[] addresses = new InetAddress[ips.length];
for (int i = 0; i < addresses.length; i++) {
addresses[i] = InetAddress.getByAddress(host, ipAddressToByteArray(ips[i]));
}
return addresses;
}
static byte[] ipAddressToByteArray(String ip) throws IllegalArgumentException{
byte[] address = ip2bytes(ip);
if (address != null) {
return address;
}
throw new IllegalArgumentException(ip + ": INVALID_IP_ADDRESS");
}
public static byte[] ip2bytes(String ipAddr) {
byte[] ret = new byte[4];
try {
String[] ipArr = ipAddr.split("\\.");
ret[0] = (byte) (Integer.parseInt(ipArr[0]) & 0xFF);
ret[1] = (byte) (Integer.parseInt(ipArr[1]) & 0xFF);
ret[2] = (byte) (Integer.parseInt(ipArr[2]) & 0xFF);
ret[3] = (byte) (Integer.parseInt(ipArr[3]) & 0xFF);
return ret;
} catch (Exception e) {
throw new IllegalArgumentException(ipAddr + " is invalid IP");
}
}
}