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"
So either some modifs are to be done on core side, or we may put the modifications in the operaton context and intercept the replay
at the pre-op stage and effectively replay the modifications at this time.
...to be discussed.
1 files added
5 files modified
| New file |
| | |
| | | /* |
| | | * 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); |
| | | } |
| | | |
| | | } |
| | |
| | | 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; |
| | |
| | | super((OperationContext) operation.getAttachment(SYNCHROCONTEXT), |
| | | operation.getRawEntryDN().stringValue()); |
| | | |
| | | encodedMods = modsToByte(operation.getModifications()); |
| | | |
| | | ModifyDnContext ctx = |
| | | (ModifyDnContext) operation.getAttachment(SYNCHROCONTEXT); |
| | | newSuperiorId = ctx.getNewParentId(); |
| | |
| | | } |
| | | |
| | | /** |
| | | * 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. |
| | |
| | | } |
| | | |
| | | /** |
| | | * 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. |
| | |
| | | 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()); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | @Override |
| | | public AbstractOperation createOperation( |
| | | InternalClientConnection connection, String newDn) |
| | | throws LDAPException, ASN1Exception |
| | | { |
| | | ModifyDNOperationBasis moddn = new ModifyDNOperationBasis(connection, |
| | | InternalClientConnection.nextOperationID(), |
| | |
| | | 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); |
| | |
| | | else |
| | | length += 1; |
| | | |
| | | length += encodedMods.length + 1; |
| | | |
| | | byte[] resultByteArray = encodeHeader(MSG_TYPE_MODIFYDN, length); |
| | | int pos = resultByteArray.length - length; |
| | | |
| | |
| | | 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; |
| | | } |
| | | |
| | |
| | | { |
| | | // 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; |
| | | } |
| | | |
| | | /** |
| | |
| | | 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; |
| | |
| | | /** |
| | | * 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. |
| | | * |
| | |
| | | } |
| | | |
| | | /** |
| | | * 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 |
| | |
| | | } |
| | | |
| | | /** |
| | | * 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 |
| | |
| | | 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) |
| | | { |
| | |
| | | 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. |
| | |
| | | |
| | | @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}, |
| | | }; |
| | | } |
| | | |
| | |
| | | * 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 |
| | |
| | | (short) 596, (short) 13); |
| | | ModifyDNMsg msg = new ModifyDNMsg(rawDN, cn, uid, |
| | | newParentUid, deleteOldRdn, |
| | | newSuperior, newRdn); |
| | | newSuperior, newRdn, mods); |
| | | |
| | | msg.setAssured(isAssured); |
| | | msg.setAssuredMode(assuredMode); |
| | |
| | | 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); |
| | | |
| | |
| | | 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()); |
| | |
| | | |
| | | @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 |
| | | { |
| | |
| | | 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); |
| | |
| | | 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); |