org.deeplearning4j.spark.util.UIDProvider Maven / Gradle / Ivy
package org.deeplearning4j.spark.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.NetworkInterface;
import java.rmi.server.UID;
import java.util.Enumeration;
/**
* Static methods for obtaining unique identifiers for both the machine (hardware) and the JVM.
*
* Note: the unique hardware identifier does NOT provide any strong guarantees of uniqueness of the returned identifier
* with respect to machine restarts and hardware changes, and should not be relied upon for anything where guarantees
* are required.
* Note also that as a fallback, if no hardware UID can be determined, the JVM UID will be returned as the hardware UID also.
*
* @author Alex Black
*/
public class UIDProvider {
private static final Logger log = LoggerFactory.getLogger(UIDProvider.class);
private static final String jvmUid;
private static final String hardwareUid;
static {
UID jvmUIDSource = new UID();
String asString = jvmUIDSource.toString();
//Format here: hexStringFromRandomNumber:hexStringFromSystemClock:hexStringOfUIDInstance
//The first two components here will be identical for all UID instances in a JVM, where as the 'hexStringOfUIDInstance'
// will vary (increment) between UID object instances. So we'll only be using the first two components here
int lastIdx = asString.lastIndexOf(":");
jvmUid = asString.substring(0, lastIdx).replaceAll(":","");
//Assumptions here:
//1. getNetworkInterfaces() returns at least one non-null element
// This is guaranteed by getNetworkInterfaces() Javadoc: "The {@code Enumeration} contains at least one element..."
//2. That the iteration order for network interfaces is consistent between JVM instances on the same hardware
// This appears to hold, but no formal guarantees seem to be available here
//3. That MAC addresses are 'unique enough' for our purposes
byte[] address = null;
boolean noInterfaces = false;
Enumeration niEnumeration = null;
try {
niEnumeration = NetworkInterface.getNetworkInterfaces();
}catch(Exception e) {
noInterfaces = true;
}
if(niEnumeration != null ) {
while (niEnumeration.hasMoreElements()) {
NetworkInterface ni = niEnumeration.nextElement();
byte[] addr;
try {
addr = ni.getHardwareAddress();
} catch (Exception e) {
continue;
}
if (addr == null || addr.length != 6)
continue; //May be null (if it can't be obtained) or not standard 6 byte MAC-48 representation
address = addr;
break;
}
}
if(address == null){
log.warn("Could not generate hardware UID{}. Using fallback: JVM UID as hardware UID.", (noInterfaces ? " (no interfaces)" : ""));
hardwareUid = jvmUid;
} else {
StringBuilder sb = new StringBuilder();
for(byte b : address){
sb.append(String.format("%02x",b));
}
hardwareUid = sb.toString();
}
}
private UIDProvider() {
}
public static String getJVMUID(){
return jvmUid;
}
public static String getHardwareUID(){
return hardwareUid;
}
}