From c1bc7cf24af7708c3f79d6266ba37ccf77b8661c Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Tue, 08 Mar 2016 10:26:16 +0000
Subject: [PATCH] OPENDJ-2747 Ensure that schema remains consistent when attribute types, matching rules, or syntaxes are removed

---
 opendj-server-legacy/src/main/java/org/opends/server/core/AttributeSyntaxConfigManager.java |   20 +++++++++-
 opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java              |    8 +++-
 opendj-server-legacy/src/main/java/org/opends/server/core/MatchingRuleConfigManager.java    |   20 +++++++++-
 opendj-server-legacy/src/main/java/org/opends/server/types/Schema.java                      |   37 ++++++++++--------
 opendj-server-legacy/src/test/java/org/opends/server/schema/LDAPSyntaxTest.java             |   11 +++++
 5 files changed, 73 insertions(+), 23 deletions(-)

diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/AttributeSyntaxConfigManager.java b/opendj-server-legacy/src/main/java/org/opends/server/core/AttributeSyntaxConfigManager.java
index 5e94726..df9afe9 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/AttributeSyntaxConfigManager.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/core/AttributeSyntaxConfigManager.java
@@ -271,7 +271,15 @@
     if (syntax != null)
     {
       Syntax sdkSyntax = syntax.getSDKSyntax(serverContext.getSchemaNG());
-      serverContext.getSchema().deregisterSyntax(sdkSyntax);
+      try
+      {
+        serverContext.getSchema().deregisterSyntax(sdkSyntax);
+      }
+      catch (DirectoryException e)
+      {
+        ccr.addMessage(e.getMessageObject());
+        ccr.setResultCodeIfSuccess(e.getResultCode());
+      }
       syntax.finalizeSyntax();
     }
 
@@ -346,7 +354,15 @@
       if (existingSyntax != null)
       {
         Syntax sdkSyntax = existingSyntax.getSDKSyntax(serverContext.getSchemaNG());
-        serverContext.getSchema().deregisterSyntax(sdkSyntax);
+        try
+        {
+          serverContext.getSchema().deregisterSyntax(sdkSyntax);
+        }
+        catch (DirectoryException e)
+        {
+          ccr.addMessage(e.getMessageObject());
+          ccr.setResultCodeIfSuccess(e.getResultCode());
+        }
         AttributeSyntax<?> syntax = syntaxes.remove(configuration.dn());
         if (syntax != null)
         {
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java b/opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java
index 5aebedc..8d24fd3 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java
@@ -2314,8 +2314,10 @@
    * Deregisters the provided matching rule with the Directory Server.
    *
    * @param  matchingRule  The matching rule to deregister with the server.
+   * @throws DirectoryException
+   *           If the matching rule is referenced by another schema element.
    */
-  public static void deregisterMatchingRule(MatchingRule matchingRule)
+  public static void deregisterMatchingRule(MatchingRule matchingRule) throws DirectoryException
   {
     directoryServer.schema.deregisterMatchingRule(matchingRule);
   }
@@ -2561,8 +2563,10 @@
    *
    * @param  attributeType  The attribute type to deregister with the Directory
    *                        Server.
+   * @throws DirectoryException
+   *           If the attribute type is referenced by another schema element.
    */
-  public static void deregisterAttributeType(AttributeType attributeType)
+  public static void deregisterAttributeType(AttributeType attributeType) throws DirectoryException
   {
     directoryServer.schema.deregisterAttributeType(attributeType);
   }
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 d0f2d67..c0b6f0a 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
@@ -289,7 +289,15 @@
     {
       for(MatchingRule matchingRule: factory.getMatchingRules())
       {
-        DirectoryServer.deregisterMatchingRule(matchingRule);
+        try
+        {
+          DirectoryServer.deregisterMatchingRule(matchingRule);
+        }
+        catch (DirectoryException e)
+        {
+          ccr.addMessage(e.getMessageObject());
+          ccr.setResultCodeIfSuccess(e.getResultCode());
+        }
       }
       factory.finalizeMatchingRule();
     }
@@ -401,7 +409,15 @@
       {
         for(MatchingRule existingRule: existingFactory.getMatchingRules())
         {
-          DirectoryServer.deregisterMatchingRule(existingRule);
+          try
+          {
+            DirectoryServer.deregisterMatchingRule(existingRule);
+          }
+          catch (DirectoryException e)
+          {
+            ccr.addMessage(e.getMessageObject());
+            ccr.setResultCodeIfSuccess(e.getResultCode());
+          }
         }
         matchingRuleFactories.remove(configuration.dn());
         existingFactory.finalizeMatchingRule();
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 7a62acb..9e51d83 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
@@ -512,8 +512,10 @@
    * Deregisters the provided attribute type definition with this schema.
    *
    * @param  attributeType  The attribute type to deregister with this schema.
+   * @throws DirectoryException
+   *           If the attribute type is referenced by another schema element.
    */
-  public void deregisterAttributeType(final AttributeType attributeType)
+  public void deregisterAttributeType(final AttributeType attributeType) throws DirectoryException
   {
     exclusiveLock.lock();
     try
@@ -526,7 +528,7 @@
         {
           deregisterSubordinateType(attributeType, superiorType);
         }
-        setSchemaNG(builder.toSchema());
+        switchSchema(builder.toSchema());
       }
     }
     finally
@@ -535,15 +537,6 @@
     }
   }
 
-  private void setSchemaNG(org.forgerock.opendj.ldap.schema.Schema newSchemaNG)
-  {
-    schemaNG = newSchemaNG.asNonStrictSchema();
-    if (DirectoryServer.getSchema() == this)
-    {
-      org.forgerock.opendj.ldap.schema.Schema.setDefaultSchema(schemaNG);
-    }
-  }
-
   private void updateSubordinateTypes(AttributeType attributeType)
   {
     AttributeType superiorType = attributeType.getSuperiorType();
@@ -894,15 +887,17 @@
    * Deregisters the provided attribute syntax definition with this schema.
    *
    * @param  syntax  The attribute syntax to deregister with this schema.
+   * @throws DirectoryException
+   *           If the LDAP syntax is referenced by another schema element.
    */
-  public void deregisterSyntax(final Syntax syntax)
+  public void deregisterSyntax(final Syntax syntax) throws DirectoryException
   {
     exclusiveLock.lock();
     try
     {
       SchemaBuilder builder = new SchemaBuilder(schemaNG);
       builder.removeSyntax(syntax.getOID());
-      setSchemaNG(builder.toSchema());
+      switchSchema(builder.toSchema());
     }
     finally
     {
@@ -994,8 +989,10 @@
    *
    * @param syntaxDesc
    *          The ldap syntax to deregister with this schema.
+   * @throws DirectoryException
+   *           If the LDAP syntax is referenced by another schema element.
    */
-  public void deregisterLdapSyntaxDescription(LDAPSyntaxDescription syntaxDesc)
+  public void deregisterLdapSyntaxDescription(LDAPSyntaxDescription syntaxDesc) throws DirectoryException
   {
     exclusiveLock.lock();
     try
@@ -1119,15 +1116,17 @@
    *
    * @param matchingRule
    *          The matching rule to deregister with this schema.
+   * @throws DirectoryException
+   *           If the matching rule is referenced by another schema element.
    */
-  public void deregisterMatchingRule(final MatchingRule matchingRule)
+  public void deregisterMatchingRule(final MatchingRule matchingRule) throws DirectoryException
   {
     exclusiveLock.lock();
     try
     {
       SchemaBuilder builder = new SchemaBuilder(schemaNG);
       builder.removeMatchingRule(matchingRule.getNameOrOID());
-      setSchemaNG(builder.toSchema());
+      switchSchema(builder.toSchema());
     }
     finally
     {
@@ -2651,7 +2650,11 @@
   private void switchSchema(org.forgerock.opendj.ldap.schema.Schema newSchema) throws DirectoryException
   {
     rejectSchemaWithWarnings(newSchema);
-    setSchemaNG(newSchema);
+    schemaNG = newSchema.asNonStrictSchema();
+    if (DirectoryServer.getSchema() == this)
+    {
+      org.forgerock.opendj.ldap.schema.Schema.setDefaultSchema(schemaNG);
+    }
   }
 
   private void rejectSchemaWithWarnings(org.forgerock.opendj.ldap.schema.Schema newSchema) throws DirectoryException
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/schema/LDAPSyntaxTest.java b/opendj-server-legacy/src/test/java/org/opends/server/schema/LDAPSyntaxTest.java
index 11ebacc..0f2d14e 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/schema/LDAPSyntaxTest.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/schema/LDAPSyntaxTest.java
@@ -271,6 +271,17 @@
      }
      finally
      {
+       int resultCode = TestCaseUtils.applyModifications(true,
+         "dn: cn=schema",
+         "changetype: modify",
+         "delete: objectclasses",
+         "objectclasses: ( oc-oid NAME 'testOC' SUP top AUXILIARY MUST test-attr)",
+         "-",
+         "delete: attributetypes",
+         "attributetypes: ( test-oid NAME 'test-attr' SYNTAX 9.9.9 )"
+       );
+       assertThat(resultCode).isEqualTo(0);
+
        deleteSubstitutionSyntax();
      }
    }

--
Gitblit v1.10.0