From 6fb77ab2682e5ee2657188b70ebe2573e7c44aff Mon Sep 17 00:00:00 2001
From: Nicolas Capponi <nicolas.capponi@forgerock.com>
Date: Fri, 01 Jul 2016 12:53:43 +0000
Subject: [PATCH] OPENDJ-2956 Issue warnings during schema validation of an attribute type if it references obsolete elements

---
 opendj-server-legacy/src/main/java/org/opends/server/backends/SchemaBackend.java  |   25 ------------
 opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AttributeTypeTest.java |   18 +++++++-
 opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AttributeType.java     |   16 +++++++-
 opendj-core/src/main/resources/com/forgerock/opendj/ldap/core.properties          |    5 ++
 4 files changed, 34 insertions(+), 30 deletions(-)

diff --git a/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AttributeType.java b/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AttributeType.java
index 8918f6e..790d11c 100644
--- a/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AttributeType.java
+++ b/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AttributeType.java
@@ -17,11 +17,9 @@
 package org.forgerock.opendj.ldap.schema;
 
 import static java.util.Arrays.*;
-
 import static org.forgerock.opendj.ldap.schema.SchemaConstants.*;
 import static org.forgerock.opendj.ldap.schema.SchemaOptions.ALLOW_ATTRIBUTE_TYPES_WITH_NO_SUP_OR_SYNTAX;
 import static org.forgerock.opendj.ldap.schema.SchemaUtils.*;
-
 import static com.forgerock.opendj.ldap.CoreMessages.*;
 import static com.forgerock.opendj.util.StaticUtils.*;
 
@@ -976,6 +974,10 @@
                 failValidation(invalidSchemaElements, warnings, message);
                 return false;
             }
+
+            if (!isObsolete() && superiorType.isObsolete()) {
+                warnings.add(WARN_ATTR_TYPE_HAS_OBSOLETE_SUPERIOR_TYPE.get(getNameOrOID(), oid));
+            }
         }
 
         if (syntaxOID != null) {
@@ -1015,6 +1017,7 @@
             // Use default for syntax
             equalityMatchingRule = getSyntax().getEqualityMatchingRule();
         }
+        checkMatchingRuleIsNotObsolete(equalityMatchingRule, warnings);
 
         if (orderingMatchingRuleOID != null) {
             // Use explicitly defined matching rule first.
@@ -1034,6 +1037,7 @@
             // Use default for syntax
             orderingMatchingRule = getSyntax().getOrderingMatchingRule();
         }
+        checkMatchingRuleIsNotObsolete(orderingMatchingRule, warnings);
 
         if (substringMatchingRuleOID != null) {
             // Use explicitly defined matching rule first.
@@ -1054,6 +1058,7 @@
             // Use default for syntax
             substringMatchingRule = getSyntax().getSubstringMatchingRule();
         }
+        checkMatchingRuleIsNotObsolete(substringMatchingRule, warnings);
 
         if (approximateMatchingRuleOID != null) {
             // Use explicitly defined matching rule first.
@@ -1074,6 +1079,7 @@
             // Use default for syntax
             approximateMatchingRule = getSyntax().getApproximateMatchingRule();
         }
+        checkMatchingRuleIsNotObsolete(approximateMatchingRule, warnings);
 
         // If the attribute type is COLLECTIVE, then it must have a usage of
         // userApplications.
@@ -1094,6 +1100,12 @@
         return isValid = true;
     }
 
+    private void checkMatchingRuleIsNotObsolete(MatchingRule rule, final List<LocalizableMessage> warnings) {
+        if (!isObsolete() && rule != null && rule.isObsolete()) {
+            warnings.add(WARN_ATTR_TYPE_HAS_OBSOLETE_MR.get(getNameOrOID(), rule.getOID()));
+        }
+    }
+
     private void failValidation(final List<AttributeType> invalidSchemaElements,
             final List<LocalizableMessage> warnings, final LocalizableMessage message) {
         invalidSchemaElements.add(this);
diff --git a/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core.properties b/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core.properties
index 2711ef2..dfb8df2 100644
--- a/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core.properties
+++ b/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core.properties
@@ -1657,6 +1657,11 @@
  specifies the matching rule "%s" which is marked as OBSOLETE in the schema
 WARN_MATCHING_RULE_USE_HAS_OBSOLETE_ATTR=The matching rule use "%s" specifies the \
  attribute type "%s" which is marked as OBSOLETE in the schema
+WARN_ATTR_TYPE_HAS_OBSOLETE_SUPERIOR_TYPE=The attribute type "%s" specifies the \
+ superior type "%s" which is marked as OBSOLETE in the schema
+WARN_ATTR_TYPE_HAS_OBSOLETE_MR=The attribute type "%s" specifies the \
+ matching rule "%s" which is marked as OBSOLETE in the schema
+
 # Labels for generated documentation
 DOC_LOCALE_TAG=Code tag: %s
 DOC_LOCALE_OID=Collation order object identifier: %s
diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AttributeTypeTest.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AttributeTypeTest.java
index 7a59c95..05b2158 100644
--- a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AttributeTypeTest.java
+++ b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AttributeTypeTest.java
@@ -16,13 +16,16 @@
  */
 package org.forgerock.opendj.ldap.schema;
 
+import static org.assertj.core.api.Assertions.fail;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.forgerock.opendj.ldap.schema.SchemaConstants.*;
 
+import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
+import org.forgerock.i18n.LocalizableMessage;
 import org.forgerock.i18n.LocalizedIllegalArgumentException;
 import org.forgerock.opendj.ldap.DecodeException;
 import org.testng.Assert;
@@ -76,8 +79,16 @@
                 + " USAGE dSAOperation NO-USER-MODIFICATION )", false);
 
         schema = builder.toSchema();
-        if (!schema.getWarnings().isEmpty()) {
-            throw new Exception("Base schema not valid!");
+        // Attribute type 1.2.2 is obsolete
+        ensureSchemaHasOnlyOneObsoleteWarning(schema);
+    }
+
+    private void ensureSchemaHasOnlyOneObsoleteWarning(Schema aSchema) {
+        Collection<LocalizableMessage> schemaWarnings = aSchema.getWarnings();
+        if (schemaWarnings.isEmpty()) {
+            fail("Expected one warning for the obsolete attribute type 1.2.2");
+        } else if (schemaWarnings.size() != 1 || !schemaWarnings.iterator().next().toString().contains("OBSOLETE")) {
+            fail("Base schema is not valid, it contains unexpected schema warnings. Warnings=" + schemaWarnings);
         }
     }
 
@@ -96,7 +107,8 @@
         builder.addAttributeType("(1.2.8.5 NAME 'testtype' DESC 'full type' " + " SUP '1.2.5' "
                 + " EQUALITY 'caseIgnoreMatch' "
                 + " SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' USAGE dSAOperation )", false);
-        Assert.assertTrue(builder.toSchema().getWarnings().isEmpty());
+        Schema finalSchema = builder.toSchema();
+        ensureSchemaHasOnlyOneObsoleteWarning(finalSchema);
     }
 
     @Test(expectedExceptions = LocalizedIllegalArgumentException.class)
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/SchemaBackend.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/SchemaBackend.java
index 07d1692..0131773 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/SchemaBackend.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/SchemaBackend.java
@@ -995,22 +995,6 @@
       }
     }
 
-    // Make sure that the new attribute type doesn't reference an
-    // OBSOLETE superior attribute type.
-    AttributeType superiorType = attributeType.getSuperiorType();
-    if (superiorType != null && superiorType.isObsolete())
-    {
-      LocalizableMessage message = ERR_SCHEMA_MODIFY_OBSOLETE_SUPERIOR_ATTRIBUTE_TYPE.get(
-          attributeType.getNameOrOID(), superiorType.getNameOrOID());
-      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message);
-    }
-
-    // Make sure that none of the associated matching rules are marked OBSOLETE.
-    throwIfObsoleteMatchingRule(attributeType, attributeType.getEqualityMatchingRule());
-    throwIfObsoleteMatchingRule(attributeType, attributeType.getOrderingMatchingRule());
-    throwIfObsoleteMatchingRule(attributeType, attributeType.getSubstringMatchingRule());
-    throwIfObsoleteMatchingRule(attributeType, attributeType.getApproximateMatchingRule());
-
     // If there is no existing type, then we're adding a new attribute.
     // Otherwise, we're replacing an existing one.
     if (existingType.isPlaceHolder())
@@ -1025,15 +1009,6 @@
     }
   }
 
-  private void throwIfObsoleteMatchingRule(AttributeType attributeType, MatchingRule mr) throws DirectoryException
-  {
-    if (mr != null && mr.isObsolete())
-    {
-      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
-          ERR_SCHEMA_MODIFY_ATTRTYPE_OBSOLETE_MR.get(attributeType.getNameOrOID(), mr.getNameOrOID()));
-    }
-  }
-
   /**
    * Update list of modified files and return the schema file to use for the
    * added element (may be null).

--
Gitblit v1.10.0