[jboss-cvs] JBoss Messaging SVN: r5765 - in trunk: tests/src/org/jboss/messaging/tests/unit/util and 1 other directory.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Fri Jan 30 05:00:05 EST 2009
Author: jmesnil
Date: 2009-01-30 05:00:04 -0500 (Fri, 30 Jan 2009)
New Revision: 5765
Added:
trunk/tests/src/org/jboss/messaging/tests/unit/util/UUIDGeneratorTest.java
Modified:
trunk/src/main/org/jboss/messaging/util/UUIDGenerator.java
trunk/tests/src/org/jboss/messaging/tests/unit/util/UUIDTest.java
Log:
JBMESSAGING-1494: UUIDGenerator does not use a different network address
* refactored the algorithm to chose the spatial part of the UUID:
1. use the MAC address on Java 6
2. use a non-loopback non-local-site InetAddress
3. if both 1 and 2 fails (e.g. on java 5 or in a restricted environment), generate a random address
* the call to NetworkInterface.getHardwareAddress() is done by reflection so that the source remains 1.5 compatible.
* the choice of the address is done only the 1st time a UUID is generated
Modified: trunk/src/main/org/jboss/messaging/util/UUIDGenerator.java
===================================================================
--- trunk/src/main/org/jboss/messaging/util/UUIDGenerator.java 2009-01-29 22:27:33 UTC (rev 5764)
+++ trunk/src/main/org/jboss/messaging/util/UUIDGenerator.java 2009-01-30 10:00:04 UTC (rev 5765)
@@ -15,15 +15,22 @@
package org.jboss.messaging.util;
+import java.lang.reflect.Method;
import java.net.InetAddress;
-import java.net.UnknownHostException;
+import java.net.NetworkInterface;
+import java.net.SocketException;
import java.security.SecureRandom;
+import java.util.Enumeration;
import java.util.Random;
+import org.jboss.messaging.core.logging.Logger;
+
public final class UUIDGenerator
{
private final static UUIDGenerator sSingleton = new UUIDGenerator();
+ private static final Logger log = Logger.getLogger(UUIDGenerator.class);
+
/**
* Random-generator, used by various UUID-generation methods:
*/
@@ -31,6 +38,8 @@
private final Object mTimerLock = new Object();
private UUIDTimer mTimer = null;
+ private byte[] address;
+
/**
* Constructor is private to enforce singleton access.
@@ -73,10 +82,9 @@
return mRnd;
}
- public final UUID generateTimeBasedUUID(InetAddress addr)
+ public final UUID generateTimeBasedUUID(byte[] byteAddr)
{
byte[] contents = new byte[16];
- byte[] byteAddr = addr.getAddress();
int pos = 12;
for (int i = 0; i < 4; ++i)
{
@@ -96,77 +104,174 @@
return new UUID(UUID.TYPE_TIME_BASED, contents);
}
- private InetAddress address;
+ public final byte[] generateDummyAddress()
+ {
+ Random rnd = getRandomNumberGenerator();
+ byte[] dummy = new byte[6];
+ rnd.nextBytes(dummy);
+ /* Need to set the broadcast bit to indicate it's not a real
+ * address.
+ */
+ dummy[0] |= (byte) 0x01;
+
+ if (log.isDebugEnabled())
+ {
+ log.debug("using dummy address " + asString(dummy));
+ }
+ return dummy;
+ }
+
+ /**
+ * If running java 6 or above, returns {@link NetworkInterface#getHardwareAddress()}, else return <code>null</code>.
+ * The first hardware address is returned when iterating all the NetworkInterfaces
+ */
+ public final static byte[] getHardwareAddress()
+ {
+ Method getHardwareAddressMethod;
+ try
+ {
+ getHardwareAddressMethod = NetworkInterface.class.getMethod("getHardwareAddress", null);
+ }
+ catch (Throwable t)
+ {
+ // not on Java 6 or not enough security permission
+ return null;
+ }
+
+ try {
+ Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
+ while (networkInterfaces.hasMoreElements())
+ {
+ NetworkInterface networkInterface = (NetworkInterface)networkInterfaces.nextElement();
+ Object res = getHardwareAddressMethod.invoke(networkInterface, null);
+ if (res instanceof byte[])
+ {
+ byte[] address = (byte[])res;
+ if (log.isDebugEnabled())
+ {
+ log.debug("using hardware address " + asString(address));
+ }
+ return address;
+ }
+ }
+ } catch (Throwable t)
+ {
+ }
+
+ return null;
+ }
- private final InetAddress getAddress()
+ /**
+ * Browse all the network interfaces and their addresses until we find the 1st InetAddress which
+ * is neither a loopback address nor a site local address.
+ * Returns <code>null</code> if no such address is found.
+ */
+ public final static InetAddress getInetAddress()
{
- if (address == null)
- {
- address = null;
-
try
{
- address = InetAddress.getLocalHost();
+ Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
+ while (networkInterfaces.hasMoreElements())
+ {
+ NetworkInterface networkInterface = (NetworkInterface)networkInterfaces.nextElement();
+ Enumeration<InetAddress> inetAddresses = networkInterface.getInetAddresses();
+ while (inetAddresses.hasMoreElements())
+ {
+ InetAddress inetAddress = (InetAddress)inetAddresses.nextElement();
+ if (!inetAddress.isLoopbackAddress()
+ && !inetAddress.isSiteLocalAddress())
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("using inet address " + inetAddress);
+ }
+ return inetAddress;
+ }
+ }
+ }
}
- catch (UnknownHostException e)
- {
+ catch (SocketException e)
+ {
}
- }
- return address;
+ return null;
}
public final SimpleString generateSimpleStringUUID()
{
- InetAddress localHost = getAddress();
-
- SimpleString uid;
- if (localHost == null)
+ byte[] address = getAddressBytes();
+ if (address == null)
{
- uid = new SimpleString(java.util.UUID.randomUUID().toString());
+ return new SimpleString(java.util.UUID.randomUUID().toString());
}
else
{
UUIDGenerator gen = UUIDGenerator.getInstance();
- uid = new SimpleString(gen.generateTimeBasedUUID(localHost).toString());
+ return new SimpleString(gen.generateTimeBasedUUID(address).toString());
}
-
- return uid;
}
- public final SimpleString generateSimpleStringUUID2()
- {
- UUID uuid = generateUUID();
-
- SimpleString str = new SimpleString(uuid.asBytes());
-
- return str;
- }
-
public final UUID generateUUID()
{
- InetAddress localHost = getAddress();
+ byte[] address = getAddressBytes();
UUIDGenerator gen = UUIDGenerator.getInstance();
- UUID uid = gen.generateTimeBasedUUID(localHost);
+ UUID uid = gen.generateTimeBasedUUID(address);
return uid;
}
public final String generateStringUUID()
{
- InetAddress localHost = getAddress();
+ byte[] address = getAddressBytes();
- String uid;
- if (localHost == null)
+ if (address == null)
{
- uid = java.util.UUID.randomUUID().toString();
+ return java.util.UUID.randomUUID().toString();
}
else
{
UUIDGenerator gen = UUIDGenerator.getInstance();
- uid = gen.generateTimeBasedUUID(localHost).toString();
+ return gen.generateTimeBasedUUID(address).toString();
}
+ }
+
+ // Private -------------------------------------------------------
+
+ private final byte[] getAddressBytes()
+ {
+ if (address == null)
+ {
+ address = getHardwareAddress();
+ if (address == null)
+ {
+ InetAddress addr = getInetAddress();
+ if (addr != null)
+ {
+ address = addr.getAddress();
+ }
+ }
+ if (address == null)
+ {
+ address = generateDummyAddress();
+ }
+ }
- return uid;
+ return address;
}
+
+ private static final String asString(byte[] bytes)
+ {
+ if (bytes == null)
+ {
+ return null;
+ }
+
+ String s = "";
+ for (int i = 0; i < bytes.length - 1; i++)
+ {
+ s += Integer.toHexString(bytes[i]) + ":";
+ }
+ s += bytes[bytes.length - 1];
+ return s;
+ }
}
Added: trunk/tests/src/org/jboss/messaging/tests/unit/util/UUIDGeneratorTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/util/UUIDGeneratorTest.java (rev 0)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/util/UUIDGeneratorTest.java 2009-01-30 10:00:04 UTC (rev 5765)
@@ -0,0 +1,78 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.messaging.tests.unit.util;
+
+import java.net.InetAddress;
+
+import junit.framework.TestCase;
+
+import org.jboss.messaging.util.UUIDGenerator;
+
+/**
+ * @author <a href="mailto:jmesnil at redhat.com">Jeff Mesnil</a>
+ *
+ * @version <tt>$Revision$</tt>
+ *
+ */
+public class UUIDGeneratorTest extends TestCase
+{
+ // Constants -----------------------------------------------------
+
+ // Attributes ----------------------------------------------------
+
+ // Static --------------------------------------------------------
+
+ // Constructors --------------------------------------------------
+
+ // Public --------------------------------------------------------
+
+ public void testGetHardwareAddress() throws Exception
+ {
+ String javaVersion = System.getProperty("java.vm.version");
+ if (javaVersion.startsWith("1.5"))
+ {
+ assertNull(UUIDGenerator.getHardwareAddress());
+ } else if (javaVersion.startsWith("1.6"))
+ {
+ assertNotNull(UUIDGenerator.getHardwareAddress());
+ }
+ }
+
+ public void testGetInetAddress() throws Exception
+ {
+ InetAddress address = UUIDGenerator.getInetAddress();
+ if (address != null)
+ {
+ assertFalse(address.isLoopbackAddress());
+ assertFalse(address.isSiteLocalAddress());
+ }
+ }
+
+ // Package protected ---------------------------------------------
+
+ // Protected -----------------------------------------------------
+
+ // Private -------------------------------------------------------
+
+ // Inner classes -------------------------------------------------
+}
Modified: trunk/tests/src/org/jboss/messaging/tests/unit/util/UUIDTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/util/UUIDTest.java 2009-01-29 22:27:33 UTC (rev 5764)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/util/UUIDTest.java 2009-01-30 10:00:04 UTC (rev 5765)
@@ -22,7 +22,6 @@
package org.jboss.messaging.tests.unit.util;
-import java.net.InetAddress;
import java.util.HashSet;
import java.util.Set;
@@ -54,24 +53,22 @@
Set<String> uuidsSet = new HashSet<String>();
UUIDGenerator gen = UUIDGenerator.getInstance();
- InetAddress addr = InetAddress.getLocalHost();
-
for (int i = 0; i < MANY_TIMES; i++)
{
- uuidsSet.add(gen.generateTimeBasedUUID(addr).toString());
+ uuidsSet.add(gen.generateStringUUID());
}
// we put them in a set to check duplicates
assertEquals(MANY_TIMES, uuidsSet.size());
}
-
+
// Package protected ---------------------------------------------
// Protected -----------------------------------------------------
protected int getTimes()
{
- return 1000;
+ return 100000;
}
// Private -------------------------------------------------------
More information about the jboss-cvs-commits
mailing list