mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Nicolas Capponi
29.39.2016 6fb77ab2682e5ee2657188b70ebe2573e7c44aff
OPENDJ-2956 Issue warnings during schema validation of an attribute type if it references obsolete elements
4 files modified
64 ■■■■ changed files
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AttributeType.java 16 ●●●● patch | view | raw | blame | history
opendj-core/src/main/resources/com/forgerock/opendj/ldap/core.properties 5 ●●●●● patch | view | raw | blame | history
opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AttributeTypeTest.java 18 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/SchemaBackend.java 25 ●●●●● patch | view | raw | blame | history
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);
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
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)
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).