From 830a63f9611fa0407ad6b488347a22c907328cee Mon Sep 17 00:00:00 2001 From: Valera V Harseko Date: Fri, 3 Jul 2026 23:11:50 +0300 Subject: [PATCH] Generate entryUUID from a per-thread SecureRandom MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The EntryUUID plugin runs for every LDAP add and used UUID.randomUUID(), which draws from a single shared SecureRandom whose engine is synchronized — one more monitor all concurrent adds serialize on. Generate the RFC 4122 version 4 UUID from a ThreadLocal instead: same format (version and variant bits set identically, verified against UUID.randomUUID), same uniqueness guarantees, no shared state. The deterministic DN-based UUID used for LDIF import is unchanged. No measurable local throughput change is expected or claimed: the add path is dominated by JE record-lock waits on shared index keys; this removes a JDK-internal serialization point that grows with core count. --- .../server/plugins/EntryUUIDPlugin.java | 43 ++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/opendj-server-legacy/src/main/java/org/opends/server/plugins/EntryUUIDPlugin.java b/opendj-server-legacy/src/main/java/org/opends/server/plugins/EntryUUIDPlugin.java index 6c5b16f9ad..37a81cd01a 100644 --- a/opendj-server-legacy/src/main/java/org/opends/server/plugins/EntryUUIDPlugin.java +++ b/opendj-server-legacy/src/main/java/org/opends/server/plugins/EntryUUIDPlugin.java @@ -13,12 +13,14 @@ * * Copyright 2006-2008 Sun Microsystems, Inc. * Portions Copyright 2014-2016 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC */ package org.opends.server.plugins; import static org.forgerock.opendj.ldap.schema.CoreSchema.*; import static org.opends.messages.PluginMessages.*; +import java.security.SecureRandom; import java.util.List; import java.util.Set; import java.util.UUID; @@ -55,9 +57,48 @@ public final class EntryUUIDPlugin { /** The attribute type for the "entryUUID" attribute. */ private static final AttributeType entryUUIDType = getEntryUUIDAttributeType(); + + /** + * Per-thread random source for entryUUID generation. This plugin runs for + * every LDAP add, and {@code UUID.randomUUID()} draws from a single shared + * {@code SecureRandom} whose engine is synchronized, serializing all + * concurrent adds on one monitor. + */ + private static final ThreadLocal RANDOM = new ThreadLocal() + { + @Override + protected SecureRandom initialValue() + { + return new SecureRandom(); + } + }; + /** The current configuration for this plugin. */ private EntryUUIDPluginCfg currentConfig; + /** + * Returns a version 4 (random) UUID per RFC 4122, equivalent to + * {@code UUID.randomUUID()} but drawn from a per-thread random source. + */ + private static UUID newRandomUUID() + { + final byte[] data = new byte[16]; + RANDOM.get().nextBytes(data); + data[6] = (byte) ((data[6] & 0x0f) | 0x40); // version 4 + data[8] = (byte) ((data[8] & 0x3f) | 0x80); // IETF variant + long msb = 0; + long lsb = 0; + for (int i = 0; i < 8; i++) + { + msb = (msb << 8) | (data[i] & 0xff); + } + for (int i = 8; i < 16; i++) + { + lsb = (lsb << 8) | (data[i] & 0xff); + } + return new UUID(msb, lsb); + } + /** Mandatory default constructor of this Directory Server plugin. */ public EntryUUIDPlugin() { @@ -129,7 +170,7 @@ public final void finalizePlugin() } // Construct a new random UUID. - addOperation.setAttribute(entryUUIDType, toAttributeList(UUID.randomUUID())); + addOperation.setAttribute(entryUUIDType, toAttributeList(newRandomUUID())); return PluginResult.PreOperation.continueOperationProcessing(); }