From 46fd9423ab622d7f9531aa1564846ec52fe09534 Mon Sep 17 00:00:00 2001
From: Ludovic Poitou <ludovic.poitou@forgerock.com>
Date: Wed, 24 Apr 2013 12:44:51 +0000
Subject: [PATCH] Replication Cleanup.

---
 opends/src/server/org/opends/server/replication/plugin/PersistentServerState.java |  353 +++++++++-------------------------------------------------
 1 files changed, 56 insertions(+), 297 deletions(-)

diff --git a/opends/src/server/org/opends/server/replication/plugin/PersistentServerState.java b/opends/src/server/org/opends/server/replication/plugin/PersistentServerState.java
index 729b122..1eb9573 100644
--- a/opends/src/server/org/opends/server/replication/plugin/PersistentServerState.java
+++ b/opends/src/server/org/opends/server/replication/plugin/PersistentServerState.java
@@ -23,7 +23,7 @@
  *
  *
  *      Copyright 2006-2010 Sun Microsystems, Inc.
- *      Portions copyright 2012 ForgeRock AS.
+ *      Portions copyright 2012-2013 ForgeRock AS.
  */
 package org.opends.server.replication.plugin;
 import org.opends.messages.Message;
@@ -35,15 +35,12 @@
 import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Iterator;
 
-import org.opends.server.core.DeleteOperationBasis;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.core.ModifyOperationBasis;
 import org.opends.server.protocols.internal.InternalClientConnection;
 import org.opends.server.protocols.internal.InternalSearchOperation;
 import org.opends.server.protocols.ldap.LDAPAttribute;
-import org.opends.server.protocols.ldap.LDAPFilter;
 import org.opends.server.protocols.ldap.LDAPModification;
 import org.opends.server.replication.common.ChangeNumber;
 import org.opends.server.replication.common.ServerState;
@@ -55,7 +52,6 @@
 import org.opends.server.types.DN;
 import org.opends.server.types.DereferencePolicy;
 import org.opends.server.types.DirectoryException;
-import org.opends.server.types.LDAPException;
 import org.opends.server.types.ModificationType;
 import org.opends.server.types.RawModification;
 import org.opends.server.types.ResultCode;
@@ -64,7 +60,7 @@
 import org.opends.server.types.SearchScope;
 
 /**
- * This class implements a ServerState that is stored on the backends
+ * This class implements a ServerState that is stored in the backend
  * used to store the synchronized data and that is therefore persistent
  * across server reboot.
  */
@@ -73,7 +69,6 @@
    private final DN baseDn;
    private final InternalClientConnection conn =
        InternalClientConnection.getRootConnection();
-   private final ByteString asn1BaseDn;
    private final int serverId;
 
    private final ServerState state;
@@ -83,16 +78,6 @@
     */
    protected static final String REPLICATION_STATE = "ds-sync-state";
 
-   /**
-    * The attribute name used to store the entryUUID.
-    */
-   private static final String ENTRY_UUID = "entryUUID";
-
-   /**
-    * The attribute name used to store the RUV elements.
-    */
-   private static final String REPLICATION_RUV_ELEMENT = "nsds50ruv";
-
   /**
    * create a new ServerState.
    * @param baseDn The baseDN for which the ServerState is created
@@ -103,12 +88,12 @@
     this.baseDn = baseDn;
     this.serverId = serverId;
     this.state = new ServerState();
-    this.asn1BaseDn = ByteString.valueOf(baseDn.toString());
     loadState();
   }
 
   /**
-   * Create a new PersistenServerState based on an already existing ServerState.
+   * Create a new PersistentServerState based on an already existing
+   * ServerState.
    *
    * @param baseDn    The baseDN for which the ServerState is created.
    * @param serverId  The serverId.
@@ -119,7 +104,6 @@
     this.baseDn = baseDn;
     this.serverId = serverId;
     this.state = state;
-    this.asn1BaseDn = ByteString.valueOf(baseDn.toString());
     loadState();
   }
 
@@ -170,16 +154,14 @@
    */
   public void loadState()
   {
-    SearchResultEntry stateEntry = null;
-
     // try to load the state from the base entry.
-    stateEntry = searchBaseEntry();
-
+    SearchResultEntry stateEntry = searchBaseEntry();
     if (stateEntry == null)
     {
-      // The base entry does not exist yet
-      // in the database or was deleted. Try to read the ServerState
-      // from the configuration instead.
+      /*
+      The base entry does not exist yet in the database or was deleted.
+      Try to read the ServerState from the configuration instead.
+      */
       stateEntry = searchConfigEntry();
     }
 
@@ -205,50 +187,47 @@
    */
   private SearchResultEntry searchBaseEntry()
   {
-    LDAPFilter filter;
-
     try
     {
-      filter = LDAPFilter.decode("objectclass=*");
-    } catch (LDAPException e)
-    {
-      // can not happen
-      return null;
-    }
-
-    /*
-     * Search the database entry that is used to periodically
-     * save the ServerState
-     */
-    LinkedHashSet<String> attributes = new LinkedHashSet<String>(1);
-    attributes.add(REPLICATION_STATE);
-    InternalSearchOperation search = conn.processSearch(asn1BaseDn,
-        SearchScope.BASE_OBJECT,
-        DereferencePolicy.DEREF_ALWAYS, 0, 0, false,
-        filter,attributes);
-    if (((search.getResultCode() != ResultCode.SUCCESS)) &&
-        ((search.getResultCode() != ResultCode.NO_SUCH_OBJECT)))
-    {
-      Message message = ERR_ERROR_SEARCHING_RUV.
-          get(search.getResultCode().getResultCodeName(), search.toString(),
-              search.getErrorMessage(), baseDn.toString());
-      logError(message);
-      return null;
-    }
-
-    SearchResultEntry stateEntry = null;
-    if (search.getResultCode() == ResultCode.SUCCESS)
-    {
+      SearchFilter filter =
+          SearchFilter.createFilterFromString("objectclass=*");
       /*
-       * Read the serverState from the REPLICATION_STATE attribute
+       * Search the database entry that is used to periodically
+       * save the ServerState
        */
-      LinkedList<SearchResultEntry> result = search.getSearchEntries();
-      if (!result.isEmpty())
+      LinkedHashSet<String> attributes = new LinkedHashSet<String>(1);
+      attributes.add(REPLICATION_STATE);
+      InternalSearchOperation search = conn.processSearch(baseDn,
+          SearchScope.BASE_OBJECT,
+          DereferencePolicy.NEVER_DEREF_ALIASES,
+          0, 0, false, filter, attributes);
+      if (((search.getResultCode() != ResultCode.SUCCESS)) &&
+          ((search.getResultCode() != ResultCode.NO_SUCH_OBJECT)))
       {
-        stateEntry = result.getFirst();
+        Message message = ERR_ERROR_SEARCHING_RUV.
+            get(search.getResultCode().getResultCodeName(), search.toString(),
+                search.getErrorMessage(), baseDn.toString());
+        logError(message);
+        return null;
       }
+
+      SearchResultEntry stateEntry = null;
+      if (search.getResultCode() == ResultCode.SUCCESS)
+      {
+        // Read the serverState from the REPLICATION_STATE attribute
+        LinkedList<SearchResultEntry> result = search.getSearchEntries();
+        if (!result.isEmpty())
+        {
+          stateEntry = result.getFirst();
+        }
+      }
+      return stateEntry;
     }
-    return stateEntry;
+    catch (DirectoryException e)
+    {
+      // cannot happen
+      return null;
+    }
   }
 
   /**
@@ -276,15 +255,12 @@
 
       if (op.getResultCode() == ResultCode.SUCCESS)
       {
-        /*
-         * Read the serverState from the REPLICATION_STATE attribute
-         */
+        // Read the serverState from the REPLICATION_STATE attribute
         LinkedList<SearchResultEntry> resultEntries =
           op.getSearchEntries();
         if (!resultEntries.isEmpty())
         {
-          SearchResultEntry resultEntry = resultEntries.getFirst();
-          return resultEntry;
+          return resultEntries.getFirst();
         }
       }
       return null;
@@ -455,31 +431,23 @@
         dbMaxCn = serverStateMaxCn;
         for (SearchResultEntry resEntry : op.getSearchEntries())
         {
-          List<Attribute> attrs = resEntry.getAttribute(histType);
-          Iterator<AttributeValue> iav = attrs.get(0).iterator();
-          try
+          for (AttributeValue attrValue :
+                    resEntry.getAttribute(histType).get(0))
           {
-            while (true)
-            {
-              AttributeValue attrVal = iav.next();
-              HistoricalAttributeValue histVal =
-                new HistoricalAttributeValue(attrVal.toString());
-              ChangeNumber cn = histVal.getCn();
+            HistoricalAttributeValue histVal =
+                new HistoricalAttributeValue(attrValue.toString());
+            ChangeNumber cn = histVal.getCn();
 
-              if ((cn != null) && (cn.getServerId() == serverId))
+            if ((cn != null) && (cn.getServerId() == serverId))
+            {
+              // compare the csn regarding the maxCn we know and
+              // store the biggest
+              if (ChangeNumber.compare(dbMaxCn, cn) < 0)
               {
-                // compare the csn regarding the maxCn we know and
-                // store the biggest
-                if (ChangeNumber.compare(dbMaxCn, cn) < 0)
-                {
-                  dbMaxCn = cn;
-                }
+                dbMaxCn = cn;
               }
             }
           }
-          catch(Exception e)
-          {
-          }
         }
 
         if (ChangeNumber.compare(dbMaxCn, serverStateMaxCn) > 0)
@@ -495,215 +463,6 @@
     }
   }
 
-/**
- * Check if a ReplicaUpdateVector entry is present
- * if so, translate the ruv into a serverState and
- * a generationId.
- * @return the generationId translated from the RUV
- * entry, 0 if no RUV is present
- */
-  public Long checkRUVCompat() {
-
-   Long genId = null;
-   SearchResultEntry ruvEntry = null;
-
-   try
-   {
-
-     // Search the RUV in the DB
-     ruvEntry = searchRUVEntry();
-
-     if (ruvEntry == null)
-       return null;
-
-     // Check if the serverState is already initialized
-
-     if( !isServerStateInitilized())
-     {
-       // Translate the ruv to serverState
-       // and GenerationId
-       genId = initializeStateWithRUVEntry(ruvEntry);
-     }
-   }
-   catch (Exception e)
-   {
-     Message message = NOTE_ERR_WHILE_TRYING_TO_DECODE_RUV_IN_STATE.get(
-         baseDn.toString());
-     logError(message);
-   }
-   // In any case, remove the RUV entry
-   // if it exists
-   DeleteOperationBasis del =  new DeleteOperationBasis(conn,
-       InternalClientConnection.nextOperationID(),
-       InternalClientConnection.nextMessageID(), null,
-       ByteString.valueOf(ruvEntry.getDN().toNormalizedString()));
-
-   // Run the internal operation
-   del.setInternalOperation(true);
-   del.setSynchronizationOperation(true);
-   del.setDontSynchronize(true);
-   del.run();
-
-   return genId;
-  }
-
-  /**
-   * Initialize the serverState and the GenerationId based on a RUV
-   * entry.
-   * @param ruvEntry the entry to translate into a serverState.
-   * @return the generationId translated from the RUV entry.
-   */
-  private Long initializeStateWithRUVEntry(SearchResultEntry ruvEntry) {
-
-    Long genId = null;
-    String value = null;
-    String csn = null;
-
-    AttributeType ruvElementType =
-      DirectoryServer.getAttributeType(REPLICATION_RUV_ELEMENT);
-
-    if (ruvElementType == null)
-      return null;
-
-    for (Attribute attr : ruvEntry.getAttribute(ruvElementType))
-    {
-      Iterator<AttributeValue> it = attr.iterator();
-      while (it.hasNext())
-      {
-        value = it.next().toString();
-        // Search for the GenerationId
-        if (value.startsWith("{replicageneration} "))
-        {
-          // Get only the timestamp present in the CSN
-          String replicaGen = value.substring(20, 28);
-          genId = Long.parseLong(replicaGen,16);
-        }
-        else
-        {
-          // Translate the other elements into serverState
-          if (value.startsWith("{replica "))
-          {
-            String[] bits = value.split(" ");
-
-            // Need to take into account when a purl is empty
-            if (bits.length > 3)
-            {
-              if (bits[2].contains("ldap"))
-              {
-                // the ldap url is present so the max csn is the 5th element
-                // Example :
-                // {replica 5 ldap://host:port} 494b6635000000050000 4aeab8f300
-                //  0000050000
-                csn = bits[4];
-              }
-              else
-              {
-                // no ldap url so the max csn is the 4th element
-                // Example :
-                // {replica 31842} 4a0d1ff700017c620000 4a926b6500007c620000
-                csn = bits[3];
-              }
-
-              String temp = csn.substring(0, 8);
-              Long timeStamp = Long.parseLong(temp, 16);
-
-              temp = csn.substring(8, 12);
-              Integer seqNum = Integer.parseInt(temp, 16);
-
-              temp = csn.substring(12, 16);
-              Integer replicaId = Integer.parseInt(temp, 16);
-
-              // No need to take into account the subSeqNum
-              ChangeNumber cn =
-                new ChangeNumber(timeStamp*1000, seqNum, replicaId);
-
-              this.update(cn);
-            }
-          }
-        }
-      }
-    }
-
-    return genId;
-}
-
-  /**
-   * Check if the server State is initialized by searching
-   * the attribute type REPLICATION_STATE in the root entry.
-   * @return true if the serverState is initialized, false
-   * otherwise
-   */
-  private boolean isServerStateInitilized() {
-    SearchResultEntry resultEntry = searchBaseEntry();
-
-    AttributeType synchronizationStateType =
-      DirectoryServer.getAttributeType(REPLICATION_STATE);
-    List<Attribute> attrs =
-      resultEntry.getAttribute(synchronizationStateType);
-
-    return (attrs != null);
-  }
-
-/**
- * Search the database entry that represent a serverState
- * using the RUV format (compatibility mode).
- * @return the corresponding RUV entry, null otherwise
- */
-  private SearchResultEntry searchRUVEntry() {
-    LDAPFilter filter;
-    SearchResultEntry ruvEntry = null;
-
-    // Search the RUV entry
-    try
-    {
-      filter = LDAPFilter.decode("objectclass=ldapSubEntry");
-    } catch (LDAPException e)
-    {
-      // can not happen
-      return null;
-    }
-
-    LinkedHashSet<String> attributes = new LinkedHashSet<String>(1);
-    attributes.add(ENTRY_UUID);
-    attributes.add(REPLICATION_RUV_ELEMENT);
-    InternalSearchOperation search = conn.processSearch(asn1BaseDn,
-        SearchScope.SUBORDINATE_SUBTREE,
-        DereferencePolicy.DEREF_ALWAYS, 0, 0, false,
-        filter,attributes);
-    if (((search.getResultCode() != ResultCode.SUCCESS)) &&
-        ((search.getResultCode() != ResultCode.NO_SUCH_OBJECT)))
-      return null;
-
-    if (search.getResultCode() == ResultCode.SUCCESS)
-    {
-      /*
-       * Search the ldapSubEntry with the entryUUID equals
-       * to "ffffffff-ffff-ffff-ffff-ffffffffffff"
-       */
-      LinkedList<SearchResultEntry> result = search.getSearchEntries();
-      if (!result.isEmpty())
-      {
-        for (SearchResultEntry ldapSubEntry : result)
-        {
-          List<Attribute> attrs =
-            ldapSubEntry.getAttribute(ENTRY_UUID.toLowerCase());
-          if (attrs != null)
-          {
-            Iterator<AttributeValue> iav = attrs.get(0).iterator();
-            AttributeValue attrVal = iav.next();
-            if (attrVal.toString().
-                equalsIgnoreCase("ffffffff-ffff-ffff-ffff-ffffffffffff"))
-            {
-              ruvEntry = ldapSubEntry;
-              break;
-            }
-          }
-        }
-      }
-    }
-    return ruvEntry;
-  }
-
   /**
    * Get the largest ChangeNumber seen for a given LDAP server ID.
    *

--
Gitblit v1.10.0