From 1c7c95f1a75a34ce6de070d6101e97a43e5c4942 Mon Sep 17 00:00:00 2001
From: gbellato <gbellato@localhost>
Date: Thu, 08 Nov 2007 15:45:34 +0000
Subject: [PATCH] Fix for 2577 : replication generationID is not correctly saved in schema backend files and is not returned when searching.

---
 opendj-sdk/opends/src/server/org/opends/server/core/SchemaConfigManager.java                           |   84 +++++++++++-----
 opendj-sdk/opends/src/server/org/opends/server/types/Schema.java                                       |   78 +++++----------
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/InitOnLineTest.java |   19 +++
 opendj-sdk/opends/src/server/org/opends/server/config/ConfigConstants.java                             |   11 --
 opendj-sdk/opends/src/server/org/opends/server/backends/SchemaBackend.java                             |   51 +++-------
 5 files changed, 115 insertions(+), 128 deletions(-)

diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/SchemaBackend.java b/opendj-sdk/opends/src/server/org/opends/server/backends/SchemaBackend.java
index b108606..76cf79c 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/SchemaBackend.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/SchemaBackend.java
@@ -45,6 +45,7 @@
 import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
 import java.util.concurrent.ConcurrentHashMap;
@@ -171,13 +172,6 @@
   // The attribute type that will be used to include the defined name forms.
   private AttributeType nameFormsType;
 
-  // The attribute type that will be used to save the synchronization state.
-  private AttributeType synchronizationStateType;
-
-  // The attribute type that will be used to save the synchronization
-  // generationId.
-  private AttributeType synchronizationGenerationIdType;
-
   // The value containing DN of the user we'll say created the configuration.
   private AttributeValue creatorsName;
 
@@ -272,12 +266,6 @@
     matchingRuleUsesType =
          DirectoryServer.getAttributeType(ATTR_MATCHING_RULE_USE_LC, true);
     nameFormsType = DirectoryServer.getAttributeType(ATTR_NAME_FORMS_LC, true);
-    synchronizationStateType =
-      DirectoryServer.getAttributeType(ATTR_SYNCHRONIZATION_STATE_LC, true);
-    synchronizationGenerationIdType =
-      DirectoryServer.getAttributeType(ATTR_SYNCHRONIZATION_GENERATIONID_LC,
-          true);
-
 
     // Initialize the lastmod attributes.
     creatorsNameType =
@@ -955,21 +943,15 @@
                                valueSet));
     operationalAttrs.put(modifyTimestampType, attrList);
 
-    //  Add the synchronization State attribute.
-    valueSet = DirectoryServer.getSchema().getSynchronizationState();
-    attr = new Attribute(synchronizationStateType,
-                         ATTR_SYNCHRONIZATION_STATE_LC, valueSet);
-    attrList = new ArrayList<Attribute>(1);
-    attrList.add(attr);
-    operationalAttrs.put(synchronizationStateType, attrList);
-
-    //  Add the synchronization GenerationId attribute.
-    valueSet = DirectoryServer.getSchema().getSynchronizationGenerationId();
-    attr = new Attribute(synchronizationGenerationIdType,
-                         ATTR_SYNCHRONIZATION_GENERATIONID_LC, valueSet);
-    attrList = new ArrayList<Attribute>(1);
-    attrList.add(attr);
-    operationalAttrs.put(synchronizationGenerationIdType, attrList);
+    //  Add the extra attributes.
+    Map<String, Attribute> attributes =
+      DirectoryServer.getSchema().getExtraAttributes();
+    for (Attribute attribute : attributes.values())
+    {
+      attrList = new ArrayList<Attribute>(1);
+      attrList.add(attribute);
+      operationalAttrs.put(attribute.getAttributeType(), attrList);
+    }
 
     // Add all the user-defined attributes.
     for (Attribute a : userDefinedAttributes)
@@ -1497,8 +1479,7 @@
           }
           else
           {
-            if (at.equals(synchronizationStateType))
-              newSchema.setSynchronizationState(a.getValues());
+            newSchema.addExtraAttribute(at.getNameOrOID(), a);
             modifiedSchemaFiles.add(FILE_USER_SCHEMA_ELEMENTS);
           }
       }
@@ -3441,14 +3422,12 @@
 
     if (schemaFile.equals(FILE_USER_SCHEMA_ELEMENTS))
     {
-      values = schema.getSynchronizationState();
-      if (values != null)
+      Map<String, Attribute> attributes = schema.getExtraAttributes();
+      for (Attribute attribute : attributes.values())
       {
         ArrayList<Attribute> attrList = new ArrayList<Attribute>(1);
-        attrList.add(new Attribute(synchronizationStateType,
-                                   synchronizationStateType.getPrimaryName(),
-                                   values));
-        schemaEntry.putAttribute(synchronizationStateType, attrList);
+        attrList.add(attribute);
+        schemaEntry.putAttribute(attribute.getAttributeType(), attrList);
       }
     }
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/config/ConfigConstants.java b/opendj-sdk/opends/src/server/org/opends/server/config/ConfigConstants.java
index 07ce3f0..246273e 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/config/ConfigConstants.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/config/ConfigConstants.java
@@ -1327,18 +1327,7 @@
    */
   public static final String ATTR_MATCHING_RULE_USE_LC = "matchingruleuse";
 
-  /**
-   * The name of the attribute that holds the synchronization state,
-   * formatted in lowercase.
-   */
-  public static final String ATTR_SYNCHRONIZATION_STATE_LC = "ds-sync-state";
 
-  /**
-   * The name of the attribute that holds the replication generationId,
-   * formatted in lowercase.
-   */
-  public static final String ATTR_SYNCHRONIZATION_GENERATIONID_LC =
-       "ds-sync-generation-id";
 
   /**
    * The default maximum request size that should be used if none is specified
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/SchemaConfigManager.java b/opendj-sdk/opends/src/server/org/opends/server/core/SchemaConfigManager.java
index 938d54e..00d6986 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/SchemaConfigManager.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/SchemaConfigManager.java
@@ -710,29 +710,16 @@
       }
     }
 
-
-    AttributeType synchronizationStateType =
-      schema.getAttributeType(ATTR_SYNCHRONIZATION_STATE_LC);
-    if (synchronizationStateType == null)
+    // Loop on all the attribute of the schema entry to
+    // find the extra attribute that shoule be loaded in the Schema.
+    for (Attribute attribute : entry.getAttributes())
     {
-      synchronizationStateType =
-        DirectoryServer.getDefaultAttributeType(ATTR_SYNCHRONIZATION_STATE_LC,
-            new MatchingRuleUseSyntax());
+      if (!isSchemaAttribute(attribute))
+      {
+        schema.addExtraAttribute(attribute.getName(), attribute);
+      }
     }
 
-    AttributeType synchronizationGenerationIdType =
-      schema.getAttributeType(ATTR_SYNCHRONIZATION_GENERATIONID_LC);
-    if (synchronizationGenerationIdType == null)
-    {
-      synchronizationGenerationIdType = DirectoryServer.getDefaultAttributeType
-          (ATTR_SYNCHRONIZATION_GENERATIONID_LC, new MatchingRuleUseSyntax());
-    }
-
-    List<Attribute> synchronizationState =
-      entry.getAttribute(synchronizationStateType);
-    if (synchronizationState != null && !(synchronizationState.isEmpty()))
-      schema.setSynchronizationState(synchronizationState.get(0).getValues());
-
     // Parse the attribute type definitions if there are any.
     if (attrList != null)
     {
@@ -744,7 +731,7 @@
           AttributeType attrType;
           try
           {
-            attrType = attrTypeSyntax.decodeAttributeType(v.getValue(),
+            attrType = AttributeTypeSyntax.decodeAttributeType(v.getValue(),
                                                           schema, false);
             attrType.setExtraProperty(SCHEMA_PROPERTY_FILENAME, (String) null);
             attrType.setSchemaFile(schemaFile);
@@ -837,7 +824,8 @@
           ObjectClass oc;
           try
           {
-            oc = ocSyntax.decodeObjectClass(v.getValue(), schema, false);
+            oc =
+              ObjectClassSyntax.decodeObjectClass(v.getValue(), schema, false);
             oc.setExtraProperty(SCHEMA_PROPERTY_FILENAME, (String) null);
             oc.setSchemaFile(schemaFile);
           }
@@ -931,7 +919,7 @@
           NameForm nf;
           try
           {
-            nf = nfSyntax.decodeNameForm(v.getValue(), schema, false);
+            nf = NameFormSyntax.decodeNameForm(v.getValue(), schema, false);
             nf.getExtraProperties().remove(SCHEMA_PROPERTY_FILENAME);
             nf.setSchemaFile(schemaFile);
           }
@@ -1023,7 +1011,8 @@
           DITContentRule dcr;
           try
           {
-            dcr = dcrSyntax.decodeDITContentRule(v.getValue(), schema, false);
+            dcr = DITContentRuleSyntax.decodeDITContentRule(
+                v.getValue(), schema, false);
             dcr.getExtraProperties().remove(SCHEMA_PROPERTY_FILENAME);
             dcr.setSchemaFile(schemaFile);
           }
@@ -1116,8 +1105,8 @@
           DITStructureRule dsr;
           try
           {
-            dsr = dsrSyntax.decodeDITStructureRule(v.getValue(), schema,
-                                                   false);
+            dsr = DITStructureRuleSyntax.decodeDITStructureRule(
+                v.getValue(), schema, false);
             dsr.getExtraProperties().remove(SCHEMA_PROPERTY_FILENAME);
             dsr.setSchemaFile(schemaFile);
           }
@@ -1210,8 +1199,8 @@
           MatchingRuleUse mru;
           try
           {
-            mru = mruSyntax.decodeMatchingRuleUse(v.getValue(), schema,
-                                                  false);
+            mru = MatchingRuleUseSyntax.decodeMatchingRuleUse(
+                            v.getValue(), schema, false);
             mru.getExtraProperties().remove(SCHEMA_PROPERTY_FILENAME);
             mru.setSchemaFile(schemaFile);
           }
@@ -1296,5 +1285,44 @@
 
     return mods;
   }
+
+
+
+  /**
+   * This method checks if a given attribute is an attribute that
+   * is used by the definition of the schema.
+   *
+   * @param attribute   The attribute to be checked.
+   * @return            true if the attribute is part of the schema definition,
+   *                    false if the attribute is not part of the schema
+   *                    definition.
+   */
+  private static boolean isSchemaAttribute(Attribute attribute)
+  {
+    String attributeOid = attribute.getAttributeType().getOID();
+    if (attributeOid.equals("2.5.21.1") ||
+        attributeOid.equals("2.5.21.2") ||
+        attributeOid.equals("2.5.21.4") ||
+        attributeOid.equals("2.5.21.5") ||
+        attributeOid.equals("2.5.21.6") ||
+        attributeOid.equals("2.5.21.7") ||
+        attributeOid.equals("2.5.21.8") ||
+        attributeOid.equals("2.5.4.3")  ||
+        attributeOid.equals("attributetypes-oid")      ||
+        attributeOid.equals("objectclasses-oid")       ||
+        attributeOid.equals("matchingRules-oid")       ||
+        attributeOid.equals("matchingRuleUse-oid")     ||
+        attributeOid.equals("NameFormDescription-oid") ||
+        attributeOid.equals("dITContentRules-oid")     ||
+        attributeOid.equals("dITStructureRules")
+        )
+    {
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
 }
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/Schema.java b/opendj-sdk/opends/src/server/org/opends/server/types/Schema.java
index 16692dd..dc390d4 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/types/Schema.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/Schema.java
@@ -35,9 +35,11 @@
 import java.io.FileWriter;
 import java.io.IOException;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.TreeSet;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -212,12 +214,13 @@
   // file.
   private long youngestModificationTime;
 
-  // The synchronization State.
-  private LinkedHashSet<AttributeValue> synchronizationState = null;
+  // A set of extra attributes that are not used directly by
+  // the schema but may be used by other component to store
+  // information in the schema.
+  // ex : Replication uses this to store its state and GenerationID.
 
-  // The synchronization generationId.
-  private LinkedHashSet<AttributeValue> synchronizationGenerationId
-    = null;
+  private Map<String, Attribute> extraAttributes =
+    new HashMap<String, Attribute>();
 
 
 
@@ -2931,15 +2934,10 @@
     dupSchema.objectClassSet.addAll(objectClassSet);
     dupSchema.oldestModificationTime   = oldestModificationTime;
     dupSchema.youngestModificationTime = youngestModificationTime;
-    if (synchronizationState != null)
+    if (extraAttributes != null)
     {
-      dupSchema.synchronizationState =
-        new LinkedHashSet<AttributeValue>(synchronizationState);
-    }
-    if (synchronizationGenerationId != null)
-    {
-      dupSchema.synchronizationGenerationId = new
-        LinkedHashSet<AttributeValue>(synchronizationGenerationId);
+      dupSchema.extraAttributes =
+        new HashMap<String, Attribute>(extraAttributes);
     }
 
     return dupSchema;
@@ -2947,49 +2945,29 @@
 
 
   /**
-   * Retrieves the Synchronization state for this schema.
+   * Get the extraAttributes stored in this schema.
    *
-   * @return  The Synchronization state for this schema.
+   * @return  The extraAttributes stored in this schema.
    */
-  public LinkedHashSet<AttributeValue> getSynchronizationState()
+  public Map<String, Attribute> getExtraAttributes()
   {
-    return synchronizationState;
+    return extraAttributes;
   }
 
+
   /**
-   * Sets the Synchronization generationId for this schema.
+   * Add a new extra Attribute for this schema.
    *
-   * @param  values  Synchronization generationId for this schema.
-   */
-  public void setSynchronizationGenerationId(
-              LinkedHashSet<AttributeValue> values)
-  {
-    synchronizationGenerationId = values;
-  }
-
-  /**
-   * Retrieves the Synchronization generationId for this schema.
+   * @param  name     The identifier of the extra Attribute.
    *
-   * @return  The Synchronization generationId for this schema.
+   * @param  attr     The extra attribute that must be added to
+   *                  this Schema.
    */
-  public LinkedHashSet<AttributeValue>
-    getSynchronizationGenerationId()
+  public void addExtraAttribute(String name, Attribute attr)
   {
-    return synchronizationGenerationId;
+    extraAttributes.put(name, attr);
   }
 
-  /**
-   * Sets the Synchronization state for this schema.
-   *
-   * @param  values  Synchronization state for this schema.
-   */
-  public void setSynchronizationState(
-              LinkedHashSet<AttributeValue> values)
-  {
-    synchronizationState = values;
-  }
-
-
 
   /**
    * Writes a single file containing all schema element definitions,
@@ -3557,16 +3535,10 @@
       substringMatchingRules = null;
     }
 
-    if (synchronizationGenerationId != null)
+    if (extraAttributes != null)
     {
-      synchronizationGenerationId.clear();
-      synchronizationGenerationId = null;
-    }
-
-    if (synchronizationState != null)
-    {
-      synchronizationState.clear();
-      synchronizationState = null;
+      extraAttributes.clear();
+      extraAttributes = null;
     }
 
     if (syntaxes != null)
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/InitOnLineTest.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/InitOnLineTest.java
index ca6a5a5..b10dd33 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/InitOnLineTest.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/InitOnLineTest.java
@@ -1453,8 +1453,27 @@
   protected void afterTest()
   {
 
+    // Check that the domain hsa completed the import/export task.
     if (replDomain != null)
     {
+      // race condition could cause the main thread to reach 
+      // this code before the task is fully completed.
+      // in those cases, loop for a while waiting for completion.
+      for (int i = 0; i< 10; i++)
+      {
+        if (replDomain.ieRunning())
+        {
+          try
+          {
+            Thread.sleep(500);
+          } catch (InterruptedException e)
+          { }
+        }
+        else
+        {
+          break;
+        }
+      }
        assertTrue(!replDomain.ieRunning(),
          "ReplicationDomain: Import/Export is not expected to be running");
     }

--
Gitblit v1.10.0