Make MAC address UUID more robust
[lgpl/argeo-commons.git] / org.argeo.api.uuid / src / org / argeo / api / uuid / MacAddressUuidFactory.java
index ab6d55d207ae9576dfd92dc32b5c90a660b17bc2..6cbe98178123bb59b7a4342a87efdd7a260869f9 100644 (file)
@@ -11,11 +11,9 @@ import java.util.UUID;
  * An {@link UUID} factory whose node id (for time based UUIDs) is the hardware
  * MAC address as specified in RFC4122.
  * 
- * @see https://datatracker.ietf.org/doc/html/rfc4122.html#section-4.1.6
+ * @see "https://datatracker.ietf.org/doc/html/rfc4122.html#section-4.1.6"
  */
 public class MacAddressUuidFactory extends ConcurrentUuidFactory {
-       public final static UuidFactory DEFAULT = new MacAddressUuidFactory();
-
        public MacAddressUuidFactory() {
                this(0, localHardwareAddressAsNodeId());
        }
@@ -37,24 +35,26 @@ public class MacAddressUuidFactory extends ConcurrentUuidFactory {
                try {
                        localHost = InetAddress.getLocalHost();
                        NetworkInterface nic = NetworkInterface.getByInetAddress(localHost);
-                       if (nic != null)
+                       if (nic != null && nic.getHardwareAddress() != null)
                                return hardwareAddressToNodeId(nic);
                        Enumeration<NetworkInterface> netInterfaces = null;
-                       try {
-                               netInterfaces = NetworkInterface.getNetworkInterfaces();
-                       } catch (SocketException e) {
-                               throw new IllegalStateException(e);
-                       }
+                       netInterfaces = NetworkInterface.getNetworkInterfaces();
                        if (netInterfaces == null || !netInterfaces.hasMoreElements())
                                throw new IllegalStateException("No interfaces");
-                       return hardwareAddressToNodeId(netInterfaces.nextElement());
+                       while (netInterfaces.hasMoreElements()) {
+                               // TODO find out public/physical interfaces
+                               nic = netInterfaces.nextElement();
+                               if (nic.getHardwareAddress() != null)
+                                       return hardwareAddressToNodeId(nic);
+                       }
+                       throw new IllegalStateException("No interfaces with a MAC address");
                } catch (UnknownHostException | SocketException e) {
                        throw new IllegalStateException(e);
                }
 
        }
 
-       public static byte[] hardwareAddressToNodeId(NetworkInterface nic) {
+       public static byte[] hardwareAddressToNodeId(NetworkInterface nic) throws IllegalStateException {
                try {
                        byte[] hardwareAddress = nic.getHardwareAddress();
                        final int length = 6;