All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.deeplearning4j.spark.util.UIDProvider Maven / Gradle / Ivy

There is a newer version: 1.0.0-beta_spark_2
Show newest version
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;
    }



}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy