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

neil_a_wilson
19.57.2007 cb23b6feb6d13d49534294af0ffd625a4926b39a
opendj-sdk/opends/src/server/org/opends/server/backends/SchemaBackend.java
@@ -74,6 +74,7 @@
import org.opends.server.schema.AttributeTypeSyntax;
import org.opends.server.schema.DITContentRuleSyntax;
import org.opends.server.schema.DITStructureRuleSyntax;
import org.opends.server.schema.GeneralizedTimeSyntax;
import org.opends.server.schema.MatchingRuleUseSyntax;
import org.opends.server.schema.NameFormSyntax;
import org.opends.server.schema.ObjectClassSyntax;
@@ -148,6 +149,12 @@
  // types.
  private AttributeType attributeTypesType;
  // The attribute type that will be used to hold the schema creation timestamp.
  private AttributeType createTimestampType;
  // The attribute type that will be used to hold the schema creator's name.
  private AttributeType creatorsNameType;
  // The attribute type that will be used to include the defined DIT content
  // rules.
  private AttributeType ditContentRulesType;
@@ -167,25 +174,44 @@
  // uses.
  private AttributeType matchingRuleUsesType;
  // The attribute that will be used to hold the schema modifier's name.
  private AttributeType modifiersNameType;
  // The attribute type that will be used to hold the schema modification
  // timestamp.
  private AttributeType modifyTimestampType;
  // The attribute type that will be used to include the defined object classes.
  private AttributeType objectClassesType;
  // The attribute type that will be used to include the defined name forms.
  private AttributeType nameFormsType;
  // The value containing DN of the user we'll say created the configuration.
  private AttributeValue creatorsName;
  // The value containing the DN of the last user to modify the configuration.
  private AttributeValue modifiersName;
  // The timestamp that will be used for the schema creation time.
  private AttributeValue createTimestamp;
  // The timestamp that will be used for the latest schema modification time.
  private AttributeValue modifyTimestamp;
  // Indicates whether the attributes of the schema entry should always be
  // treated as user attributes even if they are defined as operational.
  private boolean showAllAttributes;
  // The set of objectclasses that will be used in the schema entry.
  private HashMap<ObjectClass,String> schemaObjectClasses;
  // The DN of the configuration entry for this backend.
  private DN configEntryDN;
  // The set of base DNs for this backend.
  private DN[] baseDNs;
  // The set of objectclasses that will be used in the schema entry.
  private HashMap<ObjectClass,String> schemaObjectClasses;
  // The set of supported controls for this backend.
  private HashSet<String> supportedControls;
@@ -264,6 +290,29 @@
    nameFormsType = DirectoryServer.getAttributeType(ATTR_NAME_FORMS_LC, true);
    // Initialize the lastmod attributes.
    creatorsNameType =
         DirectoryServer.getAttributeType(OP_ATTR_CREATORS_NAME_LC, true);
    createTimestampType =
         DirectoryServer.getAttributeType(OP_ATTR_CREATE_TIMESTAMP_LC, true);
    modifiersNameType =
         DirectoryServer.getAttributeType(OP_ATTR_MODIFIERS_NAME_LC, true);
    modifyTimestampType =
         DirectoryServer.getAttributeType(OP_ATTR_MODIFY_TIMESTAMP_LC, true);
    creatorsName  = new AttributeValue(creatorsNameType, baseDNs[0].toString());
    modifiersName =
         new AttributeValue(modifiersNameType, baseDNs[0].toString());
    long createTime = DirectoryServer.getSchema().getOldestModificationTime();
    createTimestamp =
         GeneralizedTimeSyntax.createGeneralizedTimeValue(createTime);
    long modifyTime = DirectoryServer.getSchema().getYoungestModificationTime();
    modifyTimestamp =
         GeneralizedTimeSyntax.createGeneralizedTimeValue(modifyTime);
    // Get the set of user-defined attributes for the configuration entry.  Any
    // attributes that we don't recognize will be included directly in the
    // schema entry.
@@ -418,7 +467,11 @@
        attrType.hasName(ATTR_BACKEND_BASE_DN.toLowerCase()) ||
        attrType.hasName(ATTR_BACKEND_WRITABILITY_MODE.toLowerCase()) ||
        attrType.hasName(ATTR_SCHEMA_SHOW_ALL_ATTRIBUTES.toLowerCase()) ||
        attrType.hasName(ATTR_COMMON_NAME))
        attrType.hasName(ATTR_COMMON_NAME) ||
        attrType.hasName(OP_ATTR_CREATORS_NAME_LC) ||
        attrType.hasName(OP_ATTR_CREATE_TIMESTAMP_LC) ||
        attrType.hasName(OP_ATTR_MODIFIERS_NAME_LC) ||
        attrType.hasName(OP_ATTR_MODIFY_TIMESTAMP_LC))
    {
      return true;
    }
@@ -700,6 +753,36 @@
    }
    // Add the lastmod attributes.
    valueSet = new LinkedHashSet<AttributeValue>(1);
    valueSet.add(creatorsName);
    attrList = new ArrayList<Attribute>(1);
    attrList.add(new Attribute(creatorsNameType, OP_ATTR_CREATORS_NAME,
                               valueSet));
    operationalAttrs.put(creatorsNameType, attrList);
    valueSet = new LinkedHashSet<AttributeValue>(1);
    valueSet.add(createTimestamp);
    attrList = new ArrayList<Attribute>(1);
    attrList.add(new Attribute(createTimestampType, OP_ATTR_CREATE_TIMESTAMP,
                               valueSet));
    operationalAttrs.put(createTimestampType, attrList);
    valueSet = new LinkedHashSet<AttributeValue>(1);
    valueSet.add(modifiersName);
    attrList = new ArrayList<Attribute>(1);
    attrList.add(new Attribute(modifiersNameType, OP_ATTR_MODIFIERS_NAME,
                               valueSet));
    operationalAttrs.put(modifiersNameType, attrList);
    valueSet = new LinkedHashSet<AttributeValue>(1);
    valueSet.add(modifyTimestamp);
    attrList = new ArrayList<Attribute>(1);
    attrList.add(new Attribute(modifyTimestampType, OP_ATTR_MODIFY_TIMESTAMP,
                               valueSet));
    operationalAttrs.put(modifyTimestampType, attrList);
    // Add all the user-defined attributes.
    for (Attribute a : userDefinedAttributes)
    {
@@ -1279,6 +1362,16 @@
    {
      cleanUpTempSchemaFiles(tempSchemaFiles);
    }
    DN authzDN = modifyOperation.getAuthorizationDN();
    if (authzDN == null)
    {
      authzDN = DN.nullDN();
    }
    modifiersName = new AttributeValue(modifiersNameType, authzDN.toString());
    modifyTimestamp = GeneralizedTimeSyntax.createGeneralizedTimeValue(
                           System.currentTimeMillis());
  }
opendj-sdk/opends/src/server/org/opends/server/core/SchemaConfigManager.java
@@ -646,8 +646,10 @@
    // Construct the path to the directory that should contain the schema files
    // and make sure that it exists and is a directory.  Get a list of the files
    // in that directory sorted in alphabetic order.
    String schemaDirPath = getSchemaDirectoryPath();
    File schemaDir = new File(schemaDirPath);
    String schemaDirPath          = getSchemaDirectoryPath();
    File schemaDir                = new File(schemaDirPath);
    long oldestModificationTime   = -1L;
    long youngestModificationTime = -1L;
    String[] fileNames;
    try
@@ -673,6 +675,19 @@
        {
          fileList.add(f.getAbsolutePath());
        }
        long modificationTime = f.lastModified();
        if ((oldestModificationTime <= 0L) ||
            (modificationTime < oldestModificationTime))
        {
          oldestModificationTime = modificationTime;
        }
        if ((youngestModificationTime <= 0) ||
            (modificationTime > youngestModificationTime))
        {
          youngestModificationTime = modificationTime;
        }
      }
      fileNames = new String[fileList.size()];
@@ -696,6 +711,22 @@
    }
    // If the oldest and youngest modification timestamps didn't get set for
    // some reason, then set them to the current time.
    if (oldestModificationTime <= 0)
    {
      oldestModificationTime = System.currentTimeMillis();
    }
    if (youngestModificationTime <= 0)
    {
      youngestModificationTime = oldestModificationTime;
    }
    schema.setOldestModificationTime(oldestModificationTime);
    schema.setYoungestModificationTime(youngestModificationTime);
    // Iterate through the schema files and read them as an LDIF file containing
    // a single entry.  Then get the attributeTypes and objectClasses attributes
    // from that entry and parse them to initialize the server schema.
opendj-sdk/opends/src/server/org/opends/server/types/Schema.java
@@ -172,6 +172,14 @@
  // The set of pre-encoded objectclass representations.
  private LinkedHashSet<AttributeValue> objectClassSet;
  // The oldest modification timestamp for any schema configuration
  // file.
  private long oldestModificationTime;
  // The youngest modification timestamp for any schema configuration
  // file.
  private long youngestModificationTime;
  /**
@@ -214,6 +222,9 @@
    matchingRuleUseSet  = new LinkedHashSet<AttributeValue>();
    nameFormSet         = new LinkedHashSet<AttributeValue>();
    objectClassSet      = new LinkedHashSet<AttributeValue>();
    oldestModificationTime   = System.currentTimeMillis();
    youngestModificationTime = oldestModificationTime;
  }
@@ -2542,6 +2553,77 @@
  /**
   * Retrieves the modification timestamp for the file in the schema
   * configuration directory with the oldest last modified time.
   *
   * @return  The modification timestamp for the file in the schema
   *          configuration directory with the oldest last modified
   *          time.
   */
  public long getOldestModificationTime()
  {
    assert debugEnter(CLASS_NAME, "getOldestModificationTime");
    return oldestModificationTime;
  }
  /**
   * Sets the modification timestamp for the oldest file in the schema
   * configuration directory.
   *
   * @param  oldestModificationTime  The modification timestamp for
   *                                 the oldest file in the schema
   *                                 configuration directory.
   */
  public void setOldestModificationTime(long oldestModificationTime)
  {
    assert debugEnter(CLASS_NAME, "setOldestModificationTime",
                      String.valueOf(oldestModificationTime));
    this.oldestModificationTime = oldestModificationTime;
  }
  /**
   * Retrieves the modification timestamp for the file in the schema
   * configuration directory with the youngest last modified time.
   *
   * @return  The modification timestamp for the file in the schema
   *          configuration directory with the youngest last modified
   *          time.
   */
  public long getYoungestModificationTime()
  {
    assert debugEnter(CLASS_NAME, "getYoungestModificationTime");
    return youngestModificationTime;
  }
  /**
   * Sets the modification timestamp for the youngest file in the
   * schema configuration directory.
   *
   * @param  youngestModificationTime  The modification timestamp for
   *                                   the youngest file in the schema
   *                                   configuration directory.
   */
  public void setYoungestModificationTime(
                   long youngestModificationTime)
  {
    assert debugEnter(CLASS_NAME, "setYoungestModificationTime",
                      String.valueOf(youngestModificationTime));
    this.youngestModificationTime = youngestModificationTime;
  }
  /**
   * Recursively rebuilds all schema elements that are dependent upon
   * the provided element.  This must be invoked whenever an existing
   * schema element is modified in order to ensure that any elements
@@ -2817,6 +2899,8 @@
    dupSchema.matchingRuleUseSet.addAll(matchingRuleUseSet);
    dupSchema.nameFormSet.addAll(nameFormSet);
    dupSchema.objectClassSet.addAll(objectClassSet);
    dupSchema.oldestModificationTime   = oldestModificationTime;
    dupSchema.youngestModificationTime = youngestModificationTime;
    return dupSchema;
  }
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/SchemaBackendTestCase.java
@@ -3674,6 +3674,71 @@
  /**
   * Tests to ensure that the schema subentry includes the lastmod attributes
   * and that the modifiersName and modifyTimestamp attributes get updated when
   * the schema is modified.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testLastModAttributes()
         throws Exception
  {
    Entry schemaEntry = DirectoryServer.getEntry(DN.decode("cn=schema"));
    assertNotNull(schemaEntry);
    AttributeType cnType =
         DirectoryServer.getAttributeType("creatorsname", true);
    AttributeType ctType =
         DirectoryServer.getAttributeType("createtimestamp", true);
    AttributeType mnType =
         DirectoryServer.getAttributeType("modifiersname", true);
    AttributeType mtType =
         DirectoryServer.getAttributeType("modifytimestamp", true);
    assertTrue(schemaEntry.hasAttribute(cnType));
    assertTrue(schemaEntry.hasAttribute(ctType));
    assertTrue(schemaEntry.hasAttribute(mnType));
    assertTrue(schemaEntry.hasAttribute(mtType));
    AttributeValue oldMTValue =
         schemaEntry.getAttribute(mtType).get(0).getValues().iterator().next();
    String path = TestCaseUtils.createTempFile(
         "dn: cn=schema",
         "changetype: modify",
         "add: attributeTypes",
         "attributeTypes: ( testlastmodattributes-oid " +
              "NAME 'testLastModAttributes' " +
              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
              "X-ORGIN 'SchemaBackendTestCase' )");
    String[] args =
    {
      "-h", "127.0.0.1",
      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-D", "cn=Directory Manager",
      "-w", "password",
      "-f", path
    };
    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
    schemaEntry = DirectoryServer.getEntry(DN.decode("cn=schema"));
    assertNotNull(schemaEntry);
    assertTrue(schemaEntry.hasAttribute(cnType));
    assertTrue(schemaEntry.hasAttribute(ctType));
    assertTrue(schemaEntry.hasAttribute(mnType));
    assertTrue(schemaEntry.hasAttribute(mtType));
    AttributeValue newMTValue =
         schemaEntry.getAttribute(mtType).get(0).getValues().iterator().next();
    assertFalse(oldMTValue.equals(newMTValue));
  }
  /**
   * Tests the {@code exportLDIF} method with a valid configuration.
   *
   * @throws  Exception  If an unexpected problem occurs.