From 40723b2f1f0143d5cd284c537c91398b88a1e561 Mon Sep 17 00:00:00 2001
From: Jean-Noël Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Mon, 06 Jun 2016 07:06:54 +0000
Subject: [PATCH] OPENDJ-3037 On startup, bulk register matching rules to reduce jitter

---
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/RemoteSchemaLoader.java |    3 
 opendj-server-legacy/src/test/java/org/opends/server/tasks/AddSchemaFileTaskTestCase.java        |    3 
 opendj-server-legacy/src/main/java/org/opends/server/core/MatchingRuleConfigManager.java         |    5 -
 opendj-server-legacy/src/main/java/org/opends/server/types/Schema.java                           |   77 ++++++++++++++++---------
 opendj-server-legacy/src/test/java/org/opends/server/backends/SchemaBackendTestCase.java         |   54 ++++++++++--------
 5 files changed, 83 insertions(+), 59 deletions(-)

diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/RemoteSchemaLoader.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/RemoteSchemaLoader.java
index d1cc4f2..fc56b84 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/RemoteSchemaLoader.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/RemoteSchemaLoader.java
@@ -16,6 +16,7 @@
  */
 package org.opends.guitools.controlpanel.util;
 
+import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Set;
 
@@ -145,7 +146,7 @@
                                                                 .implementation(impl)
                                                                 .addToSchema().toSchema().getMatchingRule(oid);
     }
-    schema.registerMatchingRule(matchingRule, true);
+    schema.registerMatchingRules(Arrays.asList(matchingRule), true);
   }
 
   private void registerSchemaAttr(final CustomSearchResult csr, final String schemaAttr) throws DirectoryException
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/MatchingRuleConfigManager.java b/opendj-server-legacy/src/main/java/org/opends/server/core/MatchingRuleConfigManager.java
index b2f52a6..401a5b4 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/MatchingRuleConfigManager.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/core/MatchingRuleConfigManager.java
@@ -186,10 +186,7 @@
       throws InitializationException, DirectoryException
   {
     MatchingRuleFactory<?> factory = loadMatchingRuleFactory(className, configuration, true);
-    for (MatchingRule matchingRule: factory.getMatchingRules())
-    {
-      DirectoryServer.getSchema().registerMatchingRule(matchingRule, false);
-    }
+    DirectoryServer.getSchema().registerMatchingRules(factory.getMatchingRules(), false);
     matchingRuleFactories.put(configuration.dn(),factory);
   }
 
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/types/Schema.java b/opendj-server-legacy/src/main/java/org/opends/server/types/Schema.java
index 146badd..6dfacbb 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/types/Schema.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/types/Schema.java
@@ -16,6 +16,7 @@
  */
 package org.opends.server.types;
 
+import static org.forgerock.opendj.ldap.ResultCode.*;
 import static org.forgerock.opendj.ldap.schema.CoreSchema.*;
 import static org.forgerock.opendj.ldap.schema.SchemaOptions.*;
 import static org.opends.messages.BackendMessages.*;
@@ -1058,13 +1059,11 @@
     return schemaNG.getMatchingRule(nameOrOid);
   }
 
-
-
   /**
-   * Registers the provided matching rule definition with this schema.
+   * Registers the provided matching rule definitions with this schema.
    *
-   * @param matchingRule
-   *          The matching rule to register with this schema.
+   * @param matchingRules
+   *          The matching rules to register with this schema.
    * @param overwriteExisting
    *          Indicates whether to overwrite an existing mapping if there are
    *          any conflicts (i.e., another matching rule with the same OID or
@@ -1073,40 +1072,30 @@
    *           If a conflict is encountered and the
    *           {@code overwriteExisting} flag is set to {@code false}
    */
-  public void registerMatchingRule(final MatchingRule matchingRule, final boolean overwriteExisting)
-         throws DirectoryException
+  public void registerMatchingRules(Collection<MatchingRule> matchingRules, boolean overwriteExisting)
+      throws DirectoryException
   {
     exclusiveLock.lock();
     try
     {
       if (!overwriteExisting)
       {
-        // check all names of the matching rules because it is not checked by SDK schema
-        for (String name : matchingRule.getNames())
-        {
-          if (schemaNG.hasMatchingRule(name))
-          {
-            Collection<MatchingRule> conflictingRules = schemaNG.getMatchingRulesWithName(name);
-            // there should be only one
-            MatchingRule conflictingRule = conflictingRules.iterator().next();
-
-            LocalizableMessage message =
-                ERR_SCHEMA_CONFLICTING_MR_NAME.get(matchingRule.getOID(), name, conflictingRule.getOID());
-            throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message);
-          }
-        }
+        // Not checked by SDK schema
+        checkNoConflictingMatchingRuleNames(matchingRules);
       }
 
-      // now register the matching rule
       SchemaBuilder builder = new SchemaBuilder(schemaNG);
-      MatchingRule.Builder b = builder.buildMatchingRule(matchingRule);
-      if (overwriteExisting)
+      for (MatchingRule matchingRule : matchingRules)
       {
-        b.addToSchemaOverwrite();
-      }
-      else
-      {
-        b.addToSchema();
+        MatchingRule.Builder b = builder.buildMatchingRule(matchingRule);
+        if (overwriteExisting)
+        {
+          b.addToSchemaOverwrite();
+        }
+        else
+        {
+          b.addToSchema();
+        }
       }
       switchSchema(builder.toSchema());
     }
@@ -1120,6 +1109,36 @@
     }
   }
 
+  private void checkNoConflictingMatchingRuleNames(Collection<MatchingRule> matchingRules) throws DirectoryException
+  {
+    final Map<String, MatchingRule> rules = new HashMap<>();
+    for (MatchingRule matchingRule : matchingRules)
+    {
+      for (String name : matchingRule.getNames())
+      {
+        if (schemaNG.hasMatchingRule(name))
+        {
+          // there should be only one
+          MatchingRule conflictingRule = schemaNG.getMatchingRulesWithName(name).iterator().next();
+          throw conflictingMatchingRuleName(name, matchingRule, conflictingRule);
+        }
+        MatchingRule conflictingRule = rules.get(name);
+        if (conflictingRule != null)
+        {
+          throw conflictingMatchingRuleName(name, matchingRule, conflictingRule);
+        }
+        rules.put(name, matchingRule);
+      }
+    }
+  }
+
+  private DirectoryException conflictingMatchingRuleName(
+      String name, MatchingRule matchingRule, MatchingRule conflictingRule)
+  {
+    return new DirectoryException(CONSTRAINT_VIOLATION,
+        ERR_SCHEMA_CONFLICTING_MR_NAME.get(matchingRule.getOID(), name, conflictingRule.getOID()));
+  }
+
   /**
    * Deregisters the provided matching rule definition with this schema.
    *
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/backends/SchemaBackendTestCase.java b/opendj-server-legacy/src/test/java/org/opends/server/backends/SchemaBackendTestCase.java
index cad27ff..0117c3f 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/backends/SchemaBackendTestCase.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/backends/SchemaBackendTestCase.java
@@ -846,8 +846,8 @@
   @Test
   public void testAddAttributeTypeObsoleteEMR() throws Exception
   {
-    MatchingRule matchingRule = getMatchingRule("testAddATObsoleteEMRMatch", "1.3.6.1.4.1.26027.1.999.20", true);
-    DirectoryServer.getSchema().registerMatchingRule(matchingRule, false);
+    MatchingRule matchingRule =
+        registerNewMatchingRule("testAddATObsoleteEMRMatch", "1.3.6.1.4.1.26027.1.999.20", true);
 
     try
     {
@@ -1189,8 +1189,8 @@
   @Test
   public void testRemoveAttributeTypeReferencedByMRU() throws Exception
   {
-    MatchingRule matchingRule = getMatchingRule("testRemoveATRefByMRUMatch", "1.3.6.1.4.1.26027.1.999.17", false);
-    DirectoryServer.getSchema().registerMatchingRule(matchingRule, false);
+    MatchingRule matchingRule =
+        registerNewMatchingRule("testRemoveATRefByMRUMatch", "1.3.6.1.4.1.26027.1.999.17", false);
 
     try
     {
@@ -3695,8 +3695,8 @@
   @Test
   public void testAddMatchingRuleUseSuccessful() throws Exception
   {
-    MatchingRule matchingRule = getMatchingRule("testAddMRUSuccessfulMatch", "1.3.6.1.4.1.26027.1.999.10", false);
-    DirectoryServer.getSchema().registerMatchingRule(matchingRule, false);
+    MatchingRule matchingRule =
+        registerNewMatchingRule("testAddMRUSuccessfulMatch", "1.3.6.1.4.1.26027.1.999.10", false);
 
     try
     {
@@ -3730,8 +3730,8 @@
   @Test
   public void testAddMatchingRuleUseToAltSchemaFile() throws Exception
   {
-    MatchingRule matchingRule = getMatchingRule("testAddMRUToAltSchemaFileMatch", "1.3.6.1.4.1.26027.1.999.18", false);
-    DirectoryServer.getSchema().registerMatchingRule(matchingRule, false);
+    MatchingRule matchingRule =
+        registerNewMatchingRule("testAddMRUToAltSchemaFileMatch", "1.3.6.1.4.1.26027.1.999.18", false);
 
     try
     {
@@ -3775,8 +3775,8 @@
   @Test
   public void testReplaceMatchingRuleUseSuccessful() throws Exception
   {
-    MatchingRule matchingRule = getMatchingRule("testReplaceMRUSuccessfulMatch", "1.3.6.1.4.1.26027.1.999.11", false);
-    DirectoryServer.getSchema().registerMatchingRule(matchingRule, false);
+    MatchingRule matchingRule =
+        registerNewMatchingRule("testReplaceMRUSuccessfulMatch", "1.3.6.1.4.1.26027.1.999.11", false);
 
     try
     {
@@ -3817,8 +3817,8 @@
   @Test
   public void testRemoveAndAddMatchingRuleUse() throws Exception
   {
-    MatchingRule matchingRule = getMatchingRule("testRemoveAndAddMRUMatch", "1.3.6.1.4.1.26027.1.999.12", false);
-    DirectoryServer.getSchema().registerMatchingRule(matchingRule, false);
+    MatchingRule matchingRule =
+        registerNewMatchingRule("testRemoveAndAddMRUMatch", "1.3.6.1.4.1.26027.1.999.12", false);
 
     try
     {
@@ -3865,8 +3865,8 @@
   @Test
   public void testAddMatchingRuleUseMRConflict() throws Exception
   {
-    MatchingRule matchingRule = getMatchingRule("testAddMRUMRConflictMatch", "1.3.6.1.4.1.26027.1.999.14", false);
-    DirectoryServer.getSchema().registerMatchingRule(matchingRule, false);
+    MatchingRule matchingRule =
+        registerNewMatchingRule("testAddMRUMRConflictMatch", "1.3.6.1.4.1.26027.1.999.14", false);
 
     try
     {
@@ -3935,8 +3935,8 @@
   @Test
   public void testAddMatchingRuleUseAttributeTypeUndefined() throws Exception
   {
-    MatchingRule matchingRule = getMatchingRule("testAddMRUATUndefinedMatch", "1.3.6.1.4.1.26027.1.999.16", false);
-    DirectoryServer.getSchema().registerMatchingRule(matchingRule, false);
+    MatchingRule matchingRule =
+        registerNewMatchingRule("testAddMRUATUndefinedMatch", "1.3.6.1.4.1.26027.1.999.16", false);
 
     try
     {
@@ -3969,8 +3969,7 @@
   public void testAddMatchingRuleUseAttributeTypeMultipleUndefined() throws Exception
   {
     MatchingRule matchingRule =
-        getMatchingRule("testAddMRUATMultipleUndefinedMatch", "1.3.6.1.4.1.26027.1.999.19", false);
-    DirectoryServer.getSchema().registerMatchingRule(matchingRule, false);
+        registerNewMatchingRule("testAddMRUATMultipleUndefinedMatch", "1.3.6.1.4.1.26027.1.999.19", false);
 
     try
     {
@@ -4010,8 +4009,8 @@
   @Test
   public void testAddMatchingRuleUseObsoleteMatchingRule() throws Exception
   {
-    MatchingRule matchingRule = getMatchingRule("testAddMRUObsoleteMRMatch", "1.3.6.1.4.1.26027.1.999.21", true);
-    DirectoryServer.getSchema().registerMatchingRule(matchingRule, false);
+    MatchingRule matchingRule =
+        registerNewMatchingRule("testAddMRUObsoleteMRMatch", "1.3.6.1.4.1.26027.1.999.21", true);
 
     try
     {
@@ -4042,8 +4041,8 @@
   @Test
   public void testAddMatchingRuleUseObsoleteAttributeType() throws Exception
   {
-    MatchingRule matchingRule = getMatchingRule("testAddMRUObsoleteATMatch", "1.3.6.1.4.1.26027.1.999.22", false);
-    DirectoryServer.getSchema().registerMatchingRule(matchingRule, false);
+    MatchingRule matchingRule =
+        registerNewMatchingRule("testAddMRUObsoleteATMatch", "1.3.6.1.4.1.26027.1.999.22", false);
 
     try
     {
@@ -4071,6 +4070,13 @@
     }
   }
 
+  private MatchingRule registerNewMatchingRule(String name, String oid, boolean obsolete) throws DirectoryException
+  {
+    MatchingRule matchingRule = getMatchingRule(name, oid, obsolete);
+    DirectoryServer.getSchema().registerMatchingRules(Arrays.asList(matchingRule), false);
+    return matchingRule;
+  }
+
   private void runModify(String[] args, String ldifContent, ResultCode expectedRC)
   {
     runModify(args, ldifContent, null, expectedRC);
@@ -4111,8 +4117,8 @@
   @Test
   public void testRemoveMatchingRuleUseSuccessful() throws Exception
   {
-    MatchingRule matchingRule = getMatchingRule("testRemoveMRUSuccessfulMatch", "1.3.6.1.4.1.26027.1.999.13", false);
-    DirectoryServer.getSchema().registerMatchingRule(matchingRule, false);
+    MatchingRule matchingRule =
+        registerNewMatchingRule("testRemoveMRUSuccessfulMatch", "1.3.6.1.4.1.26027.1.999.13", false);
 
     try
     {
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/tasks/AddSchemaFileTaskTestCase.java b/opendj-server-legacy/src/test/java/org/opends/server/tasks/AddSchemaFileTaskTestCase.java
index a28f211..a8fc1d5 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/tasks/AddSchemaFileTaskTestCase.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/tasks/AddSchemaFileTaskTestCase.java
@@ -21,6 +21,7 @@
 import java.io.FileWriter;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 import org.forgerock.opendj.ldap.DN;
@@ -80,7 +81,7 @@
         .addToSchema()
         .toSchema()
         .getMatchingRule(oid);
-    DirectoryServer.getSchema().registerMatchingRule(matchingRule, false);
+    DirectoryServer.getSchema().registerMatchingRules(Arrays.asList(matchingRule), false);
     matchingRulesToRemove.add(matchingRule);
   }
 

--
Gitblit v1.10.0