X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.api.uuid%2Fsrc%2Forg%2Fargeo%2Fapi%2Fuuid%2FMacAddressUuidFactory.java;h=ab6d55d207ae9576dfd92dc32b5c90a660b17bc2;hb=73ff3654ba6d4a8381b9be5594d0d56f214fac58;hp=d1ce6ded851ded57825c20be3158498f32281f3e;hpb=e846ef84146b66ae543c29c5f17b2991ff0f5973;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.api.uuid/src/org/argeo/api/uuid/MacAddressUuidFactory.java b/org.argeo.api.uuid/src/org/argeo/api/uuid/MacAddressUuidFactory.java index d1ce6ded8..ab6d55d20 100644 --- a/org.argeo.api.uuid/src/org/argeo/api/uuid/MacAddressUuidFactory.java +++ b/org.argeo.api.uuid/src/org/argeo/api/uuid/MacAddressUuidFactory.java @@ -1,15 +1,71 @@ package org.argeo.api.uuid; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.Enumeration; +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 + */ public class MacAddressUuidFactory extends ConcurrentUuidFactory { public final static UuidFactory DEFAULT = new MacAddressUuidFactory(); public MacAddressUuidFactory() { - setNodeIdSupplier(() -> { - byte[] hardwareAddress = getHardwareAddress(); - byte[] macAddressNodeId = toNodeIdBytes(hardwareAddress, 0); - long nodeIdBase = NodeIdSupplier.toNodeIdBase(macAddressNodeId); - return nodeIdBase; - }); + this(0, localHardwareAddressAsNodeId()); + } + + public MacAddressUuidFactory(long initialClockRange) { + this(initialClockRange, localHardwareAddressAsNodeId()); + } + + public MacAddressUuidFactory(byte[] hardwareAddress) { + this(0, hardwareAddress); + } + + public MacAddressUuidFactory(long initialClockRange, byte[] hardwareAddress) { + super(initialClockRange, hardwareAddress); + } + + private static byte[] localHardwareAddressAsNodeId() { + InetAddress localHost; + try { + localHost = InetAddress.getLocalHost(); + NetworkInterface nic = NetworkInterface.getByInetAddress(localHost); + if (nic != null) + return hardwareAddressToNodeId(nic); + Enumeration netInterfaces = null; + try { + netInterfaces = NetworkInterface.getNetworkInterfaces(); + } catch (SocketException e) { + throw new IllegalStateException(e); + } + if (netInterfaces == null || !netInterfaces.hasMoreElements()) + throw new IllegalStateException("No interfaces"); + return hardwareAddressToNodeId(netInterfaces.nextElement()); + } catch (UnknownHostException | SocketException e) { + throw new IllegalStateException(e); + } + + } + + public static byte[] hardwareAddressToNodeId(NetworkInterface nic) { + try { + byte[] hardwareAddress = nic.getHardwareAddress(); + final int length = 6; + byte[] arr = new byte[length]; + for (int i = 0; i < length; i++) { + arr[i] = hardwareAddress[length - 1 - i]; + } + return arr; + } catch (SocketException e) { + throw new IllegalStateException("Cannot retrieve hardware address from NIC", e); + } } }