From b5acb25ee2ad9bf8b166b9de1a34e6aab6ea23b7 Mon Sep 17 00:00:00 2001
From: gbellato <gbellato@localhost>
Date: Fri, 01 Sep 2006 12:04:47 +0000
Subject: [PATCH] issue 604 : solve the naming conflict that might happen when several masters are used there are 3 main parts in this commit : - attach the replication context in an OperationContext - if operation replay fails then fix the problem  - in the pre-op checks for conflict and cause failure if necessary most of the time there should be no conflict and the operation should be processed normally

---
 opends/src/server/org/opends/server/synchronization/ModifyDNMsg.java |  184 +++++++++++++++++++--------------------------
 1 files changed, 78 insertions(+), 106 deletions(-)

diff --git a/opends/src/server/org/opends/server/synchronization/ModifyDNMsg.java b/opends/src/server/org/opends/server/synchronization/ModifyDNMsg.java
index c0e016a..eb4a162 100644
--- a/opends/src/server/org/opends/server/synchronization/ModifyDNMsg.java
+++ b/opends/src/server/org/opends/server/synchronization/ModifyDNMsg.java
@@ -26,7 +26,7 @@
  */
 package org.opends.server.synchronization;
 
-import static org.opends.server.synchronization.SynchMessages.SYNCHRONIZATION;
+import static org.opends.server.synchronization.OperationContext.*;
 
 import java.io.UnsupportedEncodingException;
 import java.util.zip.DataFormatException;
@@ -41,10 +41,10 @@
  */
 public class ModifyDNMsg extends UpdateMessage
 {
-  private String dn;
   private String newRDN;
   private String newSuperior;
   private boolean deleteOldRdn;
+  private String newSuperiorId;
   private static final long serialVersionUID = -4905520652801395185L;
 
   /**
@@ -54,106 +54,83 @@
    */
   public ModifyDNMsg(ModifyDNOperation op)
   {
-    dn = op.getRawEntryDN().stringValue();
+    super((OperationContext) op.getAttachment(SYNCHROCONTEXT),
+        op.getRawEntryDN().stringValue());
+
+    ModifyDnContext ctx = (ModifyDnContext) op.getAttachment(SYNCHROCONTEXT);
+    newSuperiorId = ctx.getNewParentId();
+
     deleteOldRdn = op.deleteOldRDN();
     if (op.getRawNewSuperior() != null)
       newSuperior = op.getRawNewSuperior().stringValue();
     else
       newSuperior = null;
     newRDN = op.getRawNewRDN().stringValue();
-    changeNumber = (ChangeNumber) op.getAttachment(SYNCHRONIZATION);
   }
 
   /**
-   * Creates a new Add message from a byte[].
+   * Creates a new ModifyDN message from a byte[].
    *
    * @param in The byte[] from which the operation must be read.
-   * @throws DataFormatException The input byte[] is not a valid AddMsg
+   * @throws DataFormatException The input byte[] is not a valid AddMsg.
+   * @throws UnsupportedEncodingException If UTF8 is not supported.
    */
-  public ModifyDNMsg(byte[] in) throws DataFormatException
+  public ModifyDNMsg(byte[] in) throws DataFormatException,
+                                       UnsupportedEncodingException
   {
-    /* first byte is the type */
-    if (in[0] != MSG_TYPE_MODIFYDN_REQUEST)
-      throw new DataFormatException("byte[] is not a valid add msg");
-    int pos = 1;
+    super(in);
 
-    /* read the dn
+    int pos = decodeHeader(MSG_TYPE_MODIFYDN_REQUEST, in);
+
+    /* read the newRDN
      * first calculate the length then construct the string
      */
-    int length = 0;
-    int offset = pos;
-    while (in[pos++] != 0)
-    {
-      if (pos > in.length)
-        throw new DataFormatException("byte[] is not a valid add msg");
-      length++;
-    }
-    try
-    {
-      dn = new String(in, offset, length, "UTF-8");
+    int length = getNextLength(in, pos);
+    newRDN = new String(in, pos, length, "UTF-8");
+    pos += length + 1;
 
-      /* read the changeNumber
-       * it is always 24 characters long
-       */
-      String changenumberStr = new  String(in, pos, 24, "UTF-8");
-      changeNumber = new ChangeNumber(changenumberStr);
-      pos +=24;
+    /* read the newSuperior
+     * first calculate the length then construct the string
+     */
+    length = getNextLength(in, pos);
+    if (length != 0)
+      newSuperior = new String(in, pos, length, "UTF-8");
+    else
+      newSuperior = null;
+    pos += length + 1;
 
-      /* read the newRDN
-       * first calculate the length then construct the string
-       */
-      length = 0;
-      offset = pos;
-      while (in[pos++] != 0)
-      {
-        if (pos > in.length)
-          throw new DataFormatException("byte[] is not a valid add msg");
-        length++;
-      }
-      newRDN = new String(in, offset, length, "UTF-8");
+    /* read the new parent Id
+     */
+    length = getNextLength(in, pos);
+    if (length != 0)
+      newSuperiorId = new String(in, pos, length, "UTF-8");
+    else
+      newSuperiorId = null;
+    pos += length + 1;
 
-      /* read the newSuperior
-       * first calculate the length then construct the string
-       */
-      length = 0;
-      offset = pos;
-      while (in[pos++] != 0)
-      {
-        if (pos > in.length)
-          throw new DataFormatException("byte[] is not a valid add msg");
-        length++;
-      }
-      if (length != 0)
-        newSuperior = new String(in, offset, length, "UTF-8");
-      else
-        newSuperior = null;
-
-      /* get the deleteoldrdn flag */
-      if (in[pos] == 0)
-        deleteOldRdn = false;
-      else
-        deleteOldRdn = true;
-    } catch (UnsupportedEncodingException e)
-    {
-      throw new DataFormatException("UTF-8 is not supported by this jvm.");
-    }
+    /* get the deleteoldrdn flag */
+    if (in[pos] == 0)
+      deleteOldRdn = false;
+    else
+      deleteOldRdn = true;
   }
 
   /**
-   * Create an operation from this ModifyDN message.
-   * @param connection the connection to use when creating the operation
-   * @return the created operation
+   * {@inheritDoc}
    */
   @Override
-  public Operation createOperation(InternalClientConnection connection)
+  public Operation createOperation(InternalClientConnection connection,
+      String newDn)
   {
     ModifyDNOperation moddn =  new ModifyDNOperation(connection,
                InternalClientConnection.nextOperationID(),
                InternalClientConnection.nextMessageID(), null,
-               new ASN1OctetString(dn), new ASN1OctetString(newRDN),
+               new ASN1OctetString(newDn), new ASN1OctetString(newRDN),
                deleteOldRdn,
                (newSuperior == null ? null : new ASN1OctetString(newSuperior)));
-    moddn.setAttachment(SYNCHRONIZATION, getChangeNumber());
+    ModifyDnContext ctx = new ModifyDnContext(getChangeNumber(), getUniqueId(),
+                                              newSuperiorId);
+    moddn.setAttachment(SYNCHROCONTEXT, ctx);
     return moddn;
   }
 
@@ -167,16 +144,12 @@
   {
     try
     {
-      byte[] byteDn = dn.getBytes("UTF-8");
       byte[] byteNewRdn = newRDN.getBytes("UTF-8");
       byte[] byteNewSuperior = null;
+      byte[] byteNewSuperiorId = null;
 
-      /* The Modify DN message is stored in the form :
-       * <operation type><dn><changenumber><newrdn><newsuperior><deleteoldrdn>
-       * the length of result byte array is therefore :
-       *   1 + dn length+1 + 24 + newrdn length+1 + newsuperior length+1 +1
-       */
-      int length = 1 + byteDn.length + 1 + 24 + byteNewRdn.length + 1 + 1;
+      // calculate the length necessary to encode the parameters
+      int length = byteNewRdn.length + 1 + 1;
       if (newSuperior != null)
       {
         byteNewSuperior = newSuperior.getBytes("UTF-8");
@@ -185,42 +158,32 @@
       else
         length += 1;
 
-      byte[] resultByteArray = new byte[length];
-      int pos = 1;
-
-      /* put the type of the operation */
-      resultByteArray[0] = MSG_TYPE_MODIFYDN_REQUEST;
-
-      /* put the DN and a terminating 0 */
-      for (int i = 0; i< byteDn.length; i++,pos++)
+      if (newSuperiorId != null)
       {
-        resultByteArray[pos] = byteDn[i];
+        byteNewSuperiorId = newSuperiorId.getBytes("UTF-8");
+        length += byteNewSuperiorId.length + 1;
       }
-      resultByteArray[pos++] = 0;
+      else
+        length += 1;
 
-      /* put the ChangeNumber */
-      byte[] changeNumberByte =
-                      this.getChangeNumber().toString().getBytes("UTF-8");
-      for (int i=0; i<24; i++,pos++)
-      {
-        resultByteArray[pos] = changeNumberByte[i];
-      }
+      byte[] resultByteArray = encodeHeader(MSG_TYPE_MODIFYDN_REQUEST, length);
+      int pos = resultByteArray.length - length;
 
       /* put the new RDN and a terminating 0 */
-      for (int i = 0; i< byteNewRdn.length; i++,pos++)
-      {
-        resultByteArray[pos] = byteNewRdn[i];
-      }
-      resultByteArray[pos++] = 0;
+      pos = addByteArray(byteNewRdn, resultByteArray, pos);
 
       /* put the newsuperior and a terminating 0 */
       if (newSuperior != null)
       {
-        for (int i = 0; i< byteNewSuperior.length; i++,pos++)
-        {
-          resultByteArray[pos] = byteNewSuperior[i];
-        }
+        pos = addByteArray(byteNewSuperior, resultByteArray, pos);
+      }
+      else
         resultByteArray[pos++] = 0;
+
+      /* put the newsuperiorId and a terminating 0 */
+      if (newSuperiorId != null)
+      {
+        pos = addByteArray(byteNewSuperiorId, resultByteArray, pos);
       }
       else
         resultByteArray[pos++] = 0;
@@ -245,7 +208,16 @@
   @Override
   public String toString()
   {
-    return ("Modify DN " + dn + " " + newRDN + " " + newSuperior + " " +
+    return ("Modify DN " + getDn() + " " + newRDN + " " + newSuperior + " " +
             getChangeNumber());
   }
+
+  /**
+   * Set the new superior.
+   * @param string the new superior.
+   */
+  public void setNewSuperior(String string)
+  {
+    newSuperior = string;
+  }
 }

--
Gitblit v1.10.0