From b86b7b939d4fb1f3aa3a390d20352e7a16d86ef7 Mon Sep 17 00:00:00 2001
From: mrossign <mrossign@localhost>
Date: Fri, 31 Oct 2008 16:15:12 +0000
Subject: [PATCH] Partial fix for #3525: Attribute modifications are not replicated for modDN operations Warning: ModifyDNMsg PDU is updated and modifications are exchanged through the replication network. However at replay time, the moddn operation is re-created with the modifications, but they cannot be replayed at this time: The comment of the addModification() method for ModifyDNOperation states that "This should only be called by pre-operation plugins"
---
opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ModifyMsg.java | 55 -------
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/protocol/SynchronizationMsgTest.java | 64 +++++++-
opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ReplServerStartMsg.java | 2
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/protocol/ProtocolCompatibilityTest.java | 55 ++++++-
opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ModifyCommonMsg.java | 137 +++++++++++++++++++
opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ModifyDNMsg.java | 90 ++++++++++++
6 files changed, 321 insertions(+), 82 deletions(-)
diff --git a/opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ModifyCommonMsg.java b/opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ModifyCommonMsg.java
new file mode 100644
index 0000000..5d1839a
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ModifyCommonMsg.java
@@ -0,0 +1,137 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Copyright 2008 Sun Microsystems, Inc.
+ */
+package org.opends.server.replication.protocol;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.opends.server.protocols.asn1.ASN1Element;
+import org.opends.server.protocols.ldap.LDAPAttribute;
+import org.opends.server.protocols.ldap.LDAPModification;
+import org.opends.server.replication.common.ChangeNumber;
+import org.opends.server.replication.plugin.Historical;
+import org.opends.server.types.Attribute;
+import org.opends.server.types.AttributeType;
+import org.opends.server.types.AttributeUsage;
+import org.opends.server.types.Modification;
+
+/**
+ * This class holds every common code for the modify messages (mod, moddn).
+ */
+public abstract class ModifyCommonMsg extends UpdateMsg {
+
+ /**
+ * The modifications kept encoded in the message.
+ */
+ protected byte[] encodedMods = new byte[0];
+
+ /**
+ * Creates a new ModifyCommonMsg.
+ */
+ public ModifyCommonMsg()
+ {
+ super();
+ }
+
+ /**
+ * Creates a new ModifyCommonMsg with the given informations.
+ *
+ * @param ctx The replication Context of the operation for which the
+ * update message must be created,.
+ * @param dn The DN of the entry on which the change
+ * that caused the creation of this object happened
+ */
+ public ModifyCommonMsg(OperationContext ctx, String dn)
+ {
+ super(ctx, dn);
+ }
+
+ /**
+ * Creates a new ModifyCommonMsg with the given informations.
+ *
+ * @param cn The ChangeNumber of the operation for which the
+ * UpdateMessage is created.
+ * @param entryUUID The Unique identifier of the entry that is updated
+ * by the operation for which the UpdateMessage is created.
+ * @param dn The DN of the entry on which the change
+ * that caused the creation of this object happened
+ */
+ public ModifyCommonMsg(ChangeNumber cn, String entryUUID, String dn)
+ {
+ super(cn, entryUUID, dn);
+ }
+
+ /**
+ * Set the Modification associated to the UpdateMsg to the provided value.
+ *
+ * @param mods The new Modification associated to this ModifyMsg.
+ */
+ public void setMods(List<Modification> mods)
+ {
+ encodedMods = modsToByte(mods);
+ }
+
+ /**
+ * Encode an ArrayList of Modification into a byte[] suitable
+ * for storage in a database or send on the network.
+ *
+ * @param mods the ArrayList of Modification to be encoded.
+ * @return The encoded modifications.
+ */
+ protected byte[] modsToByte(List<Modification> mods)
+ {
+ if ((mods == null) || (mods.size() == 0))
+ return new byte[0];
+
+ ArrayList<ASN1Element> modsASN1;
+
+ modsASN1 = new ArrayList<ASN1Element>(mods.size());
+ for (Modification mod : mods)
+ {
+ Attribute attr = mod.getAttribute();
+ AttributeType type = attr.getAttributeType();
+ if (type != null )
+ {
+ if (AttributeUsage.DSA_OPERATION.equals(type.getUsage()))
+ {
+ // Attributes with a dsaOperation usage should not be synchronized.
+ // skip them.
+ continue;
+ }
+ }
+
+ if (!Historical.isHistoricalAttribute(attr))
+ {
+ LDAPModification ldapmod = new LDAPModification(
+ mod.getModificationType(), new LDAPAttribute(mod.getAttribute()));
+ modsASN1.add(ldapmod.encode());
+ }
+ }
+
+ return ASN1Element.encodeValue(modsASN1);
+ }
+
+}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ModifyDNMsg.java b/opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ModifyDNMsg.java
index 1a3cd39..c146b2a 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ModifyDNMsg.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ModifyDNMsg.java
@@ -29,22 +29,29 @@
import static org.opends.server.replication.protocol.OperationContext.*;
import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
import java.util.zip.DataFormatException;
import org.opends.server.core.ModifyDNOperationBasis;
+import org.opends.server.protocols.asn1.ASN1Element;
+import org.opends.server.protocols.asn1.ASN1Exception;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.internal.InternalClientConnection;
+import org.opends.server.protocols.ldap.LDAPModification;
import org.opends.server.replication.common.ChangeNumber;
import org.opends.server.types.AbstractOperation;
import org.opends.server.types.DN;
import org.opends.server.types.DirectoryException;
+import org.opends.server.types.LDAPException;
+import org.opends.server.types.Modification;
import org.opends.server.types.RDN;
import org.opends.server.types.operation.PostOperationModifyDNOperation;
/**
* Message used to send Modify DN information.
*/
-public class ModifyDNMsg extends UpdateMsg
+public class ModifyDNMsg extends ModifyCommonMsg
{
private String newRDN;
private String newSuperior;
@@ -61,6 +68,8 @@
super((OperationContext) operation.getAttachment(SYNCHROCONTEXT),
operation.getRawEntryDN().stringValue());
+ encodedMods = modsToByte(operation.getModifications());
+
ModifyDnContext ctx =
(ModifyDnContext) operation.getAttachment(SYNCHROCONTEXT);
newSuperiorId = ctx.getNewParentId();
@@ -74,17 +83,19 @@
}
/**
- * construct a new Modify DN message.
+ * Construct a new Modify DN message (no mods).
+ * Note: Keep this constructor version to support already written tests, not
+ * using mods.
*
* @param dn The dn to use for building the message.
* @param changeNumber The changeNumberto use for building the message.
- * @param uid The unique id to use for building the message.
+ * @param uid The unique id to use for building the message.
* @param newParentUid The new parent unique id to use for building
* the message.
* @param deleteOldRdn boolean indicating if old rdn must be deleted to use
* for building the message.
- * @param newSuperior The new Superior entry to use for building the message.
- * @param newRDN The new Rdn to use for building the message.
+ * @param newSuperior The new Superior entry to use for building the message.
+ * @param newRDN The new Rdn to use for building the message.
*/
public ModifyDNMsg(String dn, ChangeNumber changeNumber, String uid,
String newParentUid, boolean deleteOldRdn,
@@ -100,6 +111,29 @@
}
/**
+ * Construct a new Modify DN message (with mods).
+ *
+ * @param dn The dn to use for building the message.
+ * @param changeNumber The changeNumberto use for building the message.
+ * @param uid The unique id to use for building the message.
+ * @param newParentUid The new parent unique id to use for building
+ * the message.
+ * @param deleteOldRdn boolean indicating if old rdn must be deleted to use
+ * for building the message.
+ * @param newSuperior The new Superior entry to use for building the message.
+ * @param newRDN The new Rdn to use for building the message.
+ * @param mods The mod of the operation.
+ */
+ public ModifyDNMsg(String dn, ChangeNumber changeNumber, String uid,
+ String newParentUid, boolean deleteOldRdn,
+ String newSuperior, String newRDN, List<Modification> mods)
+ {
+ this(dn, changeNumber, uid, newParentUid, deleteOldRdn, newSuperior,
+ newRDN);
+ this.encodedMods = modsToByte(mods);
+ }
+
+ /**
* Creates a new ModifyDN message from a byte[].
*
* @param in The byte[] from which the operation must be read.
@@ -145,6 +179,33 @@
deleteOldRdn = false;
else
deleteOldRdn = true;
+ pos++;
+
+ // For easiness (no additional method), simply compare PDU type to
+ // know if we have to read the mods of V2
+ if (in[0] == MSG_TYPE_MODIFYDN)
+ {
+ /* Read the mods : all the remaining bytes but the terminating 0 */
+ length = in.length - pos - 1;
+ if (length > 0) // Otherwise, there is only the trailing 0 byte which we
+ // do not need to read
+ {
+ encodedMods = new byte[length];
+ try
+ {
+ System.arraycopy(in, pos, encodedMods, 0, length);
+ } catch (IndexOutOfBoundsException e)
+ {
+ throw new DataFormatException(e.getMessage());
+ } catch (ArrayStoreException e)
+ {
+ throw new DataFormatException(e.getMessage());
+ } catch (NullPointerException e)
+ {
+ throw new DataFormatException(e.getMessage());
+ }
+ }
+ }
}
/**
@@ -153,6 +214,7 @@
@Override
public AbstractOperation createOperation(
InternalClientConnection connection, String newDn)
+ throws LDAPException, ASN1Exception
{
ModifyDNOperationBasis moddn = new ModifyDNOperationBasis(connection,
InternalClientConnection.nextOperationID(),
@@ -160,6 +222,11 @@
new ASN1OctetString(newDn), new ASN1OctetString(newRDN),
deleteOldRdn,
(newSuperior == null ? null : new ASN1OctetString(newSuperior)));
+
+ ArrayList<ASN1Element> mods = ASN1Element.decodeElements(encodedMods);
+ for (ASN1Element elem : mods)
+ moddn.addModification(LDAPModification.decode(elem).toModification());
+
ModifyDnContext ctx = new ModifyDnContext(getChangeNumber(), getUniqueId(),
newSuperiorId);
moddn.setAttachment(SYNCHROCONTEXT, ctx);
@@ -194,6 +261,8 @@
else
length += 1;
+ length += encodedMods.length + 1;
+
byte[] resultByteArray = encodeHeader(MSG_TYPE_MODIFYDN, length);
int pos = resultByteArray.length - length;
@@ -222,6 +291,15 @@
else
resultByteArray[pos++] = 0;
+ /* add the mods */
+ if (encodedMods.length > 0)
+ {
+ pos = resultByteArray.length - (encodedMods.length + 1);
+ addByteArray(encodedMods, resultByteArray, pos);
+ }
+ else
+ resultByteArray[pos++] = 0;
+
return resultByteArray;
}
@@ -438,7 +516,7 @@
{
// The MODDN message size are mainly dependent on the
// size of the DN. let's assume that they average on 100 bytes
- return 100;
+ return encodedMods.length + 100;
}
/**
diff --git a/opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ModifyMsg.java b/opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ModifyMsg.java
index 5416659..9f6676f 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ModifyMsg.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ModifyMsg.java
@@ -31,16 +31,11 @@
import org.opends.server.core.ModifyOperationBasis;
import org.opends.server.protocols.asn1.ASN1Exception;
import org.opends.server.protocols.asn1.ASN1OctetString;
-import org.opends.server.protocols.ldap.LDAPAttribute;
import org.opends.server.protocols.ldap.LDAPModification;
import org.opends.server.protocols.asn1.ASN1Element;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.replication.common.ChangeNumber;
-import org.opends.server.replication.plugin.Historical;
import org.opends.server.types.AbstractOperation;
-import org.opends.server.types.Attribute;
-import org.opends.server.types.AttributeType;
-import org.opends.server.types.AttributeUsage;
import org.opends.server.types.DN;
import org.opends.server.types.LDAPException;
import org.opends.server.types.Modification;
@@ -56,10 +51,8 @@
/**
* Message used to send Modify information.
*/
-public class ModifyMsg extends UpdateMsg
+public class ModifyMsg extends ModifyCommonMsg
{
- private byte[] encodedMods = null;
-
/**
* Creates a new Modify message from a ModifyOperation.
*
@@ -170,42 +163,6 @@
}
/**
- * Encode an ArrayList of Modification into a byte[] suitable
- * for storage in a database or send on the network.
- *
- * @param mods the ArrayList of Modification to be encoded.
- */
- private byte[] modsToByte(List<Modification> mods)
- {
- ArrayList<ASN1Element> modsASN1;
-
- modsASN1 = new ArrayList<ASN1Element>(mods.size());
- for (Modification mod : mods)
- {
- Attribute attr = mod.getAttribute();
- AttributeType type = attr.getAttributeType();
- if (type != null )
- {
- if (AttributeUsage.DSA_OPERATION.equals(type.getUsage()))
- {
- // Attributes with a dsaOperation usage should not be synchronized.
- // skip them.
- continue;
- }
- }
-
- if (!Historical.isHistoricalAttribute(attr))
- {
- LDAPModification ldapmod = new LDAPModification(
- mod.getModificationType(), new LDAPAttribute(mod.getAttribute()));
- modsASN1.add(ldapmod.encode());
- }
- }
-
- return ASN1Element.encodeValue(modsASN1);
- }
-
- /**
* {@inheritDoc}
*/
@Override
@@ -235,16 +192,6 @@
}
/**
- * Set the Modification associated to the UpdateMsg to the provided value.
- *
- * @param mods The new Modification associated to this ModifyMsg.
- */
- public void setMods(List<Modification> mods)
- {
- encodedMods = modsToByte(mods);
- }
-
- /**
* {@inheritDoc}
*/
@Override
diff --git a/opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ReplServerStartMsg.java b/opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ReplServerStartMsg.java
index 47a33e5..5bed97d 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ReplServerStartMsg.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ReplServerStartMsg.java
@@ -156,7 +156,7 @@
sslEncryption = Boolean.valueOf(new String(in, pos, length, "UTF-8"));
pos += length +1;
- // For easiness (no additional method), simpy compare PDU type to
+ // For easiness (no additional method), simply compare PDU type to
// know if we have to read new parameters of V2
if (in[0] == MSG_TYPE_REPL_SERVER_START)
{
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/protocol/ProtocolCompatibilityTest.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/protocol/ProtocolCompatibilityTest.java
index 45d87cf..519824d 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/protocol/ProtocolCompatibilityTest.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/protocol/ProtocolCompatibilityTest.java
@@ -55,6 +55,7 @@
import static org.opends.server.replication.protocol.OperationContext.SYNCHROCONTEXT;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
/**
* Test the conversions between the various protocol versions.
@@ -505,12 +506,44 @@
@DataProvider(name = "createModifyDnData")
public Object[][] createModifyDnData() {
+
+ AttributeType type = DirectoryServer.getAttributeType("description");
+
+ Attribute attr1 = Attributes.create("description", "new value");
+ Modification mod1 = new Modification(ModificationType.REPLACE, attr1);
+ List<Modification> mods1 = new ArrayList<Modification>();
+ mods1.add(mod1);
+
+ Attribute attr2 = Attributes.empty("description");
+ Modification mod2 = new Modification(ModificationType.DELETE, attr2);
+ List<Modification> mods2 = new ArrayList<Modification>();
+ mods2.add(mod1);
+ mods2.add(mod2);
+
+ AttributeBuilder builder = new AttributeBuilder(type);
+ List<Modification> mods3 = new ArrayList<Modification>();
+ builder.add("string");
+ builder.add("value");
+ builder.add("again");
+ Attribute attr3 = builder.toAttribute();
+ Modification mod3 = new Modification(ModificationType.ADD, attr3);
+ mods3.add(mod3);
+
+ List<Modification> mods4 = new ArrayList<Modification>();
+ for (int i = 0; i < 10; i++)
+ {
+ Attribute attr = Attributes.create("description", "string"
+ + String.valueOf(i));
+ Modification mod = new Modification(ModificationType.ADD, attr);
+ mods4.add(mod);
+ }
+
return new Object[][] {
- {"dc=test,dc=com", "dc=new", "11111111-1111-1111-1111-111111111111", "22222222-2222-2222-2222-222222222222", false, "dc=change", false, AssuredMode.SAFE_DATA_MODE, (byte)0},
- {"dc=test,dc=com", "dc=new", "33333333-3333-3333-3333-333333333333", "44444444-4444-4444-4444-444444444444", true, "dc=change", true, AssuredMode.SAFE_READ_MODE, (byte)1},
- {"dc=test,dc=com", "dc=new", "55555555-5555-5555-5555-555555555555", "66666666-6666-6666-6666-666666666666", false, null, true, AssuredMode.SAFE_READ_MODE, (byte)3},
+ {"dc=test,dc=com", "dc=new", "11111111-1111-1111-1111-111111111111", "22222222-2222-2222-2222-222222222222", false, "dc=change", mods1, false, AssuredMode.SAFE_DATA_MODE, (byte)0},
+ {"dc=test,dc=com", "dc=new", "33333333-3333-3333-3333-333333333333", "44444444-4444-4444-4444-444444444444", true, "dc=change", mods2, true, AssuredMode.SAFE_READ_MODE, (byte)1},
+ {"dc=test,dc=com", "dc=new", "55555555-5555-5555-5555-555555555555", "66666666-6666-6666-6666-666666666666", false, null, mods3, true, AssuredMode.SAFE_READ_MODE, (byte)3},
{"dc=delete,dc=an,dc=entry,dc=with,dc=a,dc=long dn",
- "dc=new", "77777777-7777-7777-7777-777777777777", "88888888-8888-8888-8888-888888888888",true, null, true, AssuredMode.SAFE_DATA_MODE, (byte)99},
+ "dc=new", "77777777-7777-7777-7777-777777777777", "88888888-8888-8888-8888-888888888888",true, null, mods4, true, AssuredMode.SAFE_DATA_MODE, (byte)99},
};
}
@@ -519,10 +552,10 @@
* using protocol V1 and V2 are working.
*/
@Test(dataProvider = "createModifyDnData")
- public void modifyDnTest(String rawDN, String newRdn, String uid, String newParentUid,
+ public void modifyDnMsgTest(String rawDN, String newRdn, String uid, String newParentUid,
boolean deleteOldRdn, String newSuperior,
- boolean isAssured, AssuredMode assuredMode,
- byte safeDataLevel)
+ List<Modification> mods, boolean isAssured,
+ AssuredMode assuredMode, byte safeDataLevel)
throws Exception
{
// Create V2 message
@@ -530,7 +563,7 @@
(short) 596, (short) 13);
ModifyDNMsg msg = new ModifyDNMsg(rawDN, cn, uid,
newParentUid, deleteOldRdn,
- newSuperior, newRdn);
+ newSuperior, newRdn, mods);
msg.setAssured(isAssured);
msg.setAssuredMode(assuredMode);
@@ -558,7 +591,7 @@
assertEquals(newMsg.getNewSuperiorId(), msg.getNewSuperiorId());
assertEquals(newMsg.deleteOldRdn(), msg.deleteOldRdn());
- // Create a modDn operation from each message to compare mods (kept encoded in messages)
+ // Create a modDn operation from each message to compare fields)
Operation op = msg.createOperation(connection);
Operation generatedOperation = newMsg.createOperation(connection);
@@ -570,15 +603,17 @@
assertEquals(modDnOpBasis.getRawEntryDN(), genModDnOpBasis.getRawEntryDN());
assertEquals( modDnOpBasis.getAttachment(SYNCHROCONTEXT),
genModDnOpBasis.getAttachment(SYNCHROCONTEXT));
- assertEquals(modDnOpBasis.getModifications(), genModDnOpBasis.getModifications());
// Check default value for only V2 fields
assertEquals(newMsg.getAssuredMode(), AssuredMode.SAFE_DATA_MODE);
assertEquals(newMsg.getSafeDataLevel(), (byte)-1);
+ assertEquals(modDnOpBasis.getModifications(), mods);
+ assertTrue(genModDnOpBasis.getModifications() == null);
// Set again only V2 fields
newMsg.setAssuredMode(assuredMode);
newMsg.setSafeDataLevel(safeDataLevel);
+ newMsg.setMods(mods);
// Serialize in V2 msg
ModifyDNMsg v2Msg = (ModifyDNMsg)ReplicationMsg.generateMsg(newMsg.getBytes());
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/protocol/SynchronizationMsgTest.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/protocol/SynchronizationMsgTest.java
index 1946193..04d1417 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/protocol/SynchronizationMsgTest.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/protocol/SynchronizationMsgTest.java
@@ -318,21 +318,54 @@
@DataProvider(name = "createModifyDnData")
public Object[][] createModifyDnData() {
+
+ AttributeType type = DirectoryServer.getAttributeType("description");
+
+ Attribute attr1 = Attributes.create("description", "new value");
+ Modification mod1 = new Modification(ModificationType.REPLACE, attr1);
+ List<Modification> mods1 = new ArrayList<Modification>();
+ mods1.add(mod1);
+
+ Attribute attr2 = Attributes.empty("description");
+ Modification mod2 = new Modification(ModificationType.DELETE, attr2);
+ List<Modification> mods2 = new ArrayList<Modification>();
+ mods2.add(mod1);
+ mods2.add(mod2);
+
+ AttributeBuilder builder = new AttributeBuilder(type);
+ List<Modification> mods3 = new ArrayList<Modification>();
+ builder.add("string");
+ builder.add("value");
+ builder.add("again");
+ Attribute attr3 = builder.toAttribute();
+ Modification mod3 = new Modification(ModificationType.ADD, attr3);
+ mods3.add(mod3);
+
+ List<Modification> mods4 = new ArrayList<Modification>();
+ for (int i = 0; i < 10; i++)
+ {
+ Attribute attr = Attributes.create("description", "string"
+ + String.valueOf(i));
+ Modification mod = new Modification(ModificationType.ADD, attr);
+ mods4.add(mod);
+ }
+
return new Object[][] {
- {"dc=test,dc=com", "dc=new", false, "dc=change", false, AssuredMode.SAFE_DATA_MODE, (byte)0},
- {"dc=test,dc=com", "dc=new", true, "dc=change", true, AssuredMode.SAFE_READ_MODE, (byte)1},
+ {"dc=test,dc=com", "dc=new", false, "dc=change", mods1, false, AssuredMode.SAFE_DATA_MODE, (byte)0},
+ {"dc=test,dc=com", "dc=new", true, "dc=change", mods2, true, AssuredMode.SAFE_READ_MODE, (byte)1},
// testNG does not like null argument so use "" for the newSuperior
// instead of null
- {"dc=test,dc=com", "dc=new", false, "", true, AssuredMode.SAFE_READ_MODE, (byte)3},
+ {"dc=test,dc=com", "dc=new", false, "", mods3, true, AssuredMode.SAFE_READ_MODE, (byte)3},
{"dc=delete,dc=an,dc=entry,dc=with,dc=a,dc=long dn",
- "dc=new",true, "", true, AssuredMode.SAFE_DATA_MODE, (byte)99},
+ "dc=new", true, "", mods4, true, AssuredMode.SAFE_DATA_MODE, (byte)99},
};
}
@Test(dataProvider = "createModifyDnData")
- public void modifyDnTest(String rawDN, String newRdn,
+ public void modifyDnMsgTest(String rawDN, String newRdn,
boolean deleteOldRdn, String newSuperior,
- boolean isAssured, AssuredMode assuredMode,
+ List<Modification> mods, boolean isAssured,
+ AssuredMode assuredMode,
byte safeDataLevel)
throws Exception
{
@@ -349,6 +382,8 @@
new ModifyDnContext(cn, "uniqueid", "newparentId"));
LocalBackendModifyDNOperation localOp =
new LocalBackendModifyDNOperation(op);
+ for (Modification mod : mods)
+ localOp.addModification(mod);
ModifyDNMsg msg = new ModifyDNMsg(localOp);
msg.setAssured(isAssured);
@@ -363,14 +398,21 @@
assertEquals(generatedMsg.getAssuredMode(), assuredMode);
assertEquals(generatedMsg.getSafeDataLevel(), safeDataLevel);
+ Operation oriOp = msg.createOperation(connection);
Operation generatedOperation = generatedMsg.createOperation(connection);
- ModifyDNOperationBasis mod2 = (ModifyDNOperationBasis) generatedOperation;
+
+ assertEquals(oriOp.getClass(), ModifyDNOperationBasis.class);
+ assertEquals(generatedOperation.getClass(), ModifyDNOperationBasis.class);
+
+ ModifyDNOperationBasis moddn1 = (ModifyDNOperationBasis) oriOp;
+ ModifyDNOperationBasis moddn2 = (ModifyDNOperationBasis) generatedOperation;
assertEquals(msg.getChangeNumber(), generatedMsg.getChangeNumber());
- assertEquals(op.getRawEntryDN(), mod2.getRawEntryDN());
- assertEquals(op.getRawNewRDN(), mod2.getRawNewRDN());
- assertEquals(op.deleteOldRDN(), mod2.deleteOldRDN());
- assertEquals(op.getRawNewSuperior(), mod2.getRawNewSuperior());
+ assertEquals(moddn1.getRawEntryDN(), moddn2.getRawEntryDN());
+ assertEquals(moddn1.getRawNewRDN(), moddn2.getRawNewRDN());
+ assertEquals(moddn1.deleteOldRDN(), moddn2.deleteOldRDN());
+ assertEquals(moddn1.getRawNewSuperior(), moddn2.getRawNewSuperior());
+ assertEquals(moddn1.getModifications(), moddn2.getModifications());
// Create an update message from this op
ModifyDNMsg updateMsg = (ModifyDNMsg) UpdateMsg.generateMsg(localOp);
--
Gitblit v1.10.0