mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Jean-Noël Rouvignac
10.54.2015 28215a00c6a6c49ab982f51dee97d501ce954ad3
opendj-server-legacy/src/test/java/org/opends/server/replication/DependencyTest.java
@@ -29,9 +29,10 @@
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
import org.forgerock.opendj.config.server.ConfigException;
import org.forgerock.opendj.ldap.ByteString;
import org.opends.server.TestCaseUtils;
import org.opends.server.backends.MemoryBackend;
@@ -47,14 +48,16 @@
import org.opends.server.replication.server.ReplServerFakeConfiguration;
import org.opends.server.replication.server.ReplicationServer;
import org.opends.server.replication.service.ReplicationBroker;
import org.opends.server.types.AttributeType;
import org.opends.server.types.Attributes;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.Modification;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import static org.opends.server.TestCaseUtils.*;
import static org.opends.server.core.DirectoryServer.*;
import static org.opends.server.util.CollectionUtils.*;
import static org.testng.Assert.*;
/**
@@ -105,7 +108,7 @@
    int brokerId = 2;
    int serverId = 1;
    int replServerId = 81;
    int AddSequenceLength = 30;
    int addSequenceLength = 30;
    cleanDB();
@@ -121,62 +124,36 @@
       * - Configure replication server
       * - check that the last entry has been correctly added
       */
      Entry entry = TestCaseUtils.entryFromLdifString(
          "dn:" + TEST_ROOT_DN_STRING + "\n"
          + "objectClass: top\n"
          + "objectClass: organization\n"
          + "entryuuid: " + stringUID(1) + "\n");
      String entryldif =
        "dn:" + TEST_ROOT_DN_STRING + "\n"
         + "objectClass: top\n"
         + "objectClass: organization\n"
         + "entryuuid: " + stringUID(1) + "\n";
      Entry entry = TestCaseUtils.entryFromLdifString(entryldif);
      AttributeType uidType =
        DirectoryServer.getSchema().getAttributeType("entryuuid");
      int replServerPort = TestCaseUtils.findFreePort();
      ReplServerFakeConfiguration conf =
        new ReplServerFakeConfiguration(replServerPort, "dependencyTestAddModDelDependencyTestDb",
                                        replicationDbImplementation, 0, replServerId,
                                        0, AddSequenceLength*5+100, null);
      replServer = new ReplicationServer(conf);
      replServer = newReplicationServer(replServerId, addSequenceLength * 5 + 100, "dependencyTestAddModDelDependencyTestDb");
      ReplicationBroker broker = openReplicationSession(
          baseDN, brokerId, 1000, replServerPort, 1000, CLEAN_DB_GENERATION_ID);
          baseDN, brokerId, 1000, replServer.getReplicationPort(), 1000, CLEAN_DB_GENERATION_ID);
      Thread.sleep(2000);
      // send a sequence of add operation
      // send a sequence of add operation
      DN addDN = TEST_ROOT_DN;
      CSNGenerator gen = new CSNGenerator(brokerId, 0L);
      int sequence;
      for (sequence = 1; sequence<=AddSequenceLength; sequence ++)
      for (sequence = 1; sequence<=addSequenceLength; sequence ++)
      {
        entry.removeAttribute(uidType);
        entry.removeAttribute(getAttributeType("entryuuid"));
        entry.addAttribute(Attributes.create("entryuuid", stringUID(sequence+1)),
                           new LinkedList<ByteString>());
        addDN = DN.valueOf("dc=dependency" + sequence + "," + addDN);
        AddMsg addMsg =
          new AddMsg(gen.newCSN(), addDN, stringUID(sequence+1),
                     stringUID(sequence),
                     entry.getObjectClassAttribute(),
                     entry.getAttributes(), null );
        broker.publish(addMsg);
        ModifyMsg modifyMsg =
          new ModifyMsg(gen.newCSN(), addDN,
                        generatemods("description", "test"),
                        stringUID(sequence+1));
        broker.publish(modifyMsg);
        broker.publish(addMsg(addDN, entry, sequence + 1, sequence, gen));
        broker.publish(modifyMsg(addDN, sequence + 1, generatemods("description", "test"), gen));
      }
      // configure and start replication of TEST_ROOT_DN_STRING on the server
      SortedSet<String> replServers = new TreeSet<>();
      replServers.add("localhost:"+replServerPort);
      DomainFakeCfg domainConf = new DomainFakeCfg(baseDN, serverId, replServers);
      domainConf.setHeartbeatInterval(100000);
      domain = MultimasterReplication.createNewDomain(domainConf);
      domain.start();
      domain = startNewLDAPReplicationDomain(replServer, baseDN, serverId, 100000);
      // check that last entry in sequence got added.
      Entry lastEntry = getEntry(addDN, 30000, true);
@@ -186,12 +163,11 @@
      // Check that all the modify have been replayed
      // (all the entries should have a description).
      addDN = TEST_ROOT_DN;
      for (sequence = 1; sequence<=AddSequenceLength; sequence ++)
      for (sequence = 1; sequence<=addSequenceLength; sequence ++)
      {
        addDN = DN.valueOf("dc=dependency" + sequence + "," + addDN);
        boolean found = checkEntryHasAttribute(addDN, "description", "test", 10000, true);
        assertTrue(found, "The modification was not replayed on entry " + addDN);
        checkEntryHasAttributeValue(
            addDN, "description", "test", 10, "The modification was not replayed on entry " + addDN);
      }
      /*
@@ -206,14 +182,13 @@
       */
      domain.disable();
      Thread.sleep(2000);  // necesary because disable does not wait
      Thread.sleep(2000);  // necessary because disable does not wait
                           // for full termination of all threads. (issue 1571)
      DN deleteDN = addDN;
      while (sequence-->1)
      {
        DeleteMsg delMsg = new DeleteMsg(deleteDN, gen.newCSN(), stringUID(sequence + 1));
        broker.publish(delMsg);
        broker.publish(delMsg(deleteDN, sequence + 1, gen));
        deleteDN = deleteDN.parent();
      }
@@ -237,6 +212,27 @@
    }
  }
  private AddMsg addMsg(DN addDN, Entry entry, int uniqueId, int parentId, CSNGenerator gen)
  {
    return new AddMsg(gen.newCSN(), addDN, stringUID(uniqueId), stringUID(parentId),
        entry.getObjectClassAttribute(), entry.getAttributes(), null);
  }
  private ModifyMsg modifyMsg(DN dn, int entryUUID, List<Modification> mods, CSNGenerator gen)
  {
    return new ModifyMsg(gen.newCSN(), dn, mods, stringUID(entryUUID));
  }
  private DeleteMsg delMsg(DN delDN, int entryUUID, CSNGenerator gen)
  {
    return new DeleteMsg(delDN, gen.newCSN(), stringUID(entryUUID));
  }
  private ModifyDNMsg modDNMsg(DN dn, String newRDN, int entryUUID, int newSuperiorEntryUUID, CSNGenerator gen)
  {
    return new ModifyDNMsg(dn, gen.newCSN(), stringUID(entryUUID), stringUID(newSuperiorEntryUUID), true, null, newRDN);
  }
  /**
   * Check the dependency between moddn and delete operation
   * when an entry is renamed to a new dn and then deleted.
@@ -257,81 +253,48 @@
    try
    {
      // Create replication server, replication domain and broker.
      String entryldif = "dn:" + TEST_ROOT_DN_STRING + "\n"
      + "objectClass: top\n"
      + "objectClass: organization\n";
      Entry entry = TestCaseUtils.entryFromLdifString(entryldif);
      AttributeType uidType =
        DirectoryServer.getSchema().getAttributeType("entryuuid");
      Entry entry = TestCaseUtils.entryFromLdifString(
          "dn:" + TEST_ROOT_DN_STRING + "\n"
          + "objectClass: top\n"
          + "objectClass: organization\n");
      CSNGenerator gen = new CSNGenerator(brokerId, 0L);
      int renamedEntryUuid = 100;
      int replServerPort = TestCaseUtils.findFreePort();
      ReplServerFakeConfiguration conf =
        new ReplServerFakeConfiguration(replServerPort, "dependencyTestModdnDelDependencyTestDb",
                                        replicationDbImplementation, 0, replServerId,
                                        0, 200, null);
      replServer = new ReplicationServer(conf);
      replServer = newReplicationServer(replServerId, 200, "dependencyTestModdnDelDependencyTestDb");
      // configure and start replication of TEST_ROOT_DN_STRING on the server
      SortedSet<String> replServers = new TreeSet<>();
      replServers.add("localhost:"+replServerPort);
      DomainFakeCfg domainConf = new DomainFakeCfg(baseDN, serverId, replServers);
      domainConf.setHeartbeatInterval(100000);
      Thread.sleep(2000);
      domain = MultimasterReplication.createNewDomain(domainConf);
      domain.start();
      domain = startNewLDAPReplicationDomain(replServer, baseDN, serverId, 100000);
      ReplicationBroker broker = openReplicationSession(
          baseDN, brokerId, 1000, replServerPort, 1000, CLEAN_DB_GENERATION_ID);
          baseDN, brokerId, 1000, replServer.getReplicationPort(), 1000, CLEAN_DB_GENERATION_ID);
      // add an entry to play with.
      entry.removeAttribute(uidType);
      entry.removeAttribute(getAttributeType("entryuuid"));
      entry.addAttribute(Attributes.create("entryuuid",
                         stringUID(renamedEntryUuid)),
                         new LinkedList<ByteString>());
      DN addDN = DN.valueOf("dc=moddndel" + "," + TEST_ROOT_DN_STRING);
      AddMsg addMsg =
          new AddMsg(gen.newCSN(), addDN, stringUID(renamedEntryUuid),
                   stringUID(1),
                   entry.getObjectClassAttribute(),
                   entry.getAttributes(), null );
      broker.publish(addMsg);
      broker.publish(addMsg(addDN, entry, renamedEntryUuid, 1, gen));
      // check that the entry was correctly added
      boolean found = checkEntryHasAttribute(addDN, "entryuuid", stringUID(renamedEntryUuid), 30000, true);
      assertTrue(found, "The initial entry add failed");
      checkEntryHasAttributeValue(addDN, "entryuuid", stringUID(renamedEntryUuid), 30, "The initial entry add failed");
      // disable the domain to make sure that the messages are
      // all sent in a row.
      // disable the domain to make sure that the messages are all sent in a row.
      domain.disable();
      // rename and delete the entry.
      ModifyDNMsg moddnMsg =
          new ModifyDNMsg(addDN, gen.newCSN(),
                        stringUID(renamedEntryUuid),
                        stringUID(1), true, null, "dc=new_name");
      broker.publish(moddnMsg);
      DeleteMsg delMsg =
        new DeleteMsg(DN.valueOf("dc=new_name" + "," + TEST_ROOT_DN_STRING),
                      gen.newCSN(), stringUID(renamedEntryUuid));
      broker.publish(delMsg);
      broker.publish(modDNMsg(addDN, "dc=new_name", renamedEntryUuid, 1, gen));
      DN delDN = DN.valueOf("dc=new_name" + "," + TEST_ROOT_DN_STRING);
      broker.publish(delMsg(delDN, renamedEntryUuid, gen));
      // enable back the domain to trigger message replay.
      domain.enable();
      // check that entry does not exist anymore.
      Thread.sleep(10000);
      found = checkEntryHasAttribute(DN.valueOf("dc=new_name" + "," + TEST_ROOT_DN_STRING),
                                     "entryuuid",
                                     stringUID(renamedEntryUuid),
                                     30000, false);
      assertFalse(found, "The delete dependencies was not correctly enforced");
      checkEntryHasNoSuchAttributeValue(DN.valueOf("dc=new_name" + "," + TEST_ROOT_DN_STRING), "entryuuid",
          stringUID(renamedEntryUuid), 30, "The delete dependencies was not correctly enforced");
    }
    finally
    {
@@ -356,18 +319,15 @@
    TestCaseUtils.initializeTestBackend(false);
    // Create top entry with uuid
    String baseentryldif =
      "dn:" + TEST_ROOT_DN_STRING + "\n"
       + "objectClass: top\n"
       + "objectClass: organization\n"
       + "o: test\n"
       + "entryuuid: " + stringUID(1) + "\n";
    Entry topEntry = TestCaseUtils.entryFromLdifString(baseentryldif);
    Entry topEntry = TestCaseUtils.entryFromLdifString(
        "dn:" + TEST_ROOT_DN_STRING + "\n"
         + "objectClass: top\n"
         + "objectClass: organization\n"
         + "o: test\n"
         + "entryuuid: " + stringUID(1) + "\n");
    MemoryBackend memoryBackend =
      (MemoryBackend) DirectoryServer.getBackend(TEST_BACKEND_ID);
    MemoryBackend memoryBackend = (MemoryBackend) DirectoryServer.getBackend(TEST_BACKEND_ID);
    memoryBackend.addEntry(topEntry, null);
  }
@@ -387,94 +347,58 @@
    int brokerId = 2;
    int serverId = 1;
    int replServerId = 83;
    int AddSequenceLength = 30;
    int addSequenceLength = 30;
    cleanDB();
    try
    {
      String entryldif = "dn:" + TEST_ROOT_DN_STRING + "\n"
      + "objectClass: top\n"
      + "objectClass: organization\n";
      Entry entry = TestCaseUtils.entryFromLdifString(entryldif);
      AttributeType uidType =
        DirectoryServer.getSchema().getAttributeType("entryuuid");
      Entry entry = TestCaseUtils.entryFromLdifString(
          "dn:" + TEST_ROOT_DN_STRING + "\n"
          + "objectClass: top\n"
          + "objectClass: organization\n");
      int replServerPort = TestCaseUtils.findFreePort();
      ReplServerFakeConfiguration conf =
        new ReplServerFakeConfiguration(replServerPort, "dependencyTestAddDelAddDependencyTestDb", replicationDbImplementation,
                                        0, replServerId, 0, 5*AddSequenceLength+100, null);
      replServer = new ReplicationServer(conf);
      replServer = newReplicationServer(replServerId, 5 * addSequenceLength + 100, "dependencyTestAddDelAddDependencyTestDb");
      ReplicationBroker broker = openReplicationSession(
          baseDN, brokerId, 100, replServerPort, 1000, CLEAN_DB_GENERATION_ID);
          baseDN, brokerId, 100, replServer.getReplicationPort(), 1000, CLEAN_DB_GENERATION_ID);
      // send a sequence of add/del/add operations
      CSNGenerator gen = new CSNGenerator(brokerId, 0L);
      int sequence;
      for (sequence = 1; sequence<=AddSequenceLength; sequence ++)
      for (sequence = 1; sequence<=addSequenceLength; sequence ++)
      {
        // add the entry a first time
        entry.removeAttribute(uidType);
        entry.removeAttribute(getAttributeType("entryuuid"));
        entry.addAttribute(Attributes.create("entryuuid", stringUID(sequence+1)),
                           new LinkedList<ByteString>());
        DN addDN = DN.valueOf("dc=dependency" + sequence + "," + TEST_ROOT_DN_STRING);
        AddMsg addMsg =
          new AddMsg(gen.newCSN(), addDN, stringUID(sequence+1),
                     stringUID(1),
                     entry.getObjectClassAttribute(),
                     entry.getAttributes(), null );
        broker.publish(addMsg);
        // delete the entry
        DeleteMsg delMsg = new DeleteMsg(addDN, gen.newCSN(),
                                         stringUID(sequence+1));
        broker.publish(delMsg);
        broker.publish(addMsg(addDN, entry, sequence + 1, 1, gen));
        broker.publish(delMsg(addDN, sequence + 1, gen));
        // add again the entry with a new entryuuid.
        entry.removeAttribute(uidType);
        entry.removeAttribute(getAttributeType("entryuuid"));
        entry.addAttribute(Attributes.create("entryuuid", stringUID(sequence+1025)),
                           new LinkedList<ByteString>());
        addMsg =
          new AddMsg(gen.newCSN(), addDN, stringUID(sequence+1025),
                     stringUID(1),
                     entry.getObjectClassAttribute(),
                     entry.getAttributes(), null );
        broker.publish(addMsg);
        broker.publish(addMsg(addDN, entry, sequence + 1025, 1, gen));
      }
      // configure and start replication of TEST_ROOT_DN_STRING on the server
      SortedSet<String> replServers = new TreeSet<>();
      replServers.add("localhost:"+replServerPort);
      DomainFakeCfg domainConf = new DomainFakeCfg(baseDN, serverId, replServers);
      domain = MultimasterReplication.createNewDomain(domainConf);
      domain.start();
      domain = startNewLDAPReplicationDomain(replServer, baseDN, serverId, -1);
      // check that all entries have been deleted and added
      // again by checking that they do have the correct entryuuid
      for (sequence = 1; sequence<=AddSequenceLength; sequence ++)
      for (sequence = 1; sequence<=addSequenceLength; sequence ++)
      {
        String addDn = "dc=dependency" + sequence + "," + TEST_ROOT_DN_STRING;
        boolean found =
          checkEntryHasAttribute(DN.valueOf(addDn), "entryuuid",
                                 stringUID(sequence+1025),
                                 30000, true);
        if (!found)
        {
          fail("The second add was not replayed on entry " + addDn);
        }
        checkEntryHasAttributeValue(DN.valueOf(addDn), "entryuuid", stringUID(sequence + 1025), 30,
            "The second add was not replayed on entry " + addDn);
      }
      for (sequence = 1; sequence<=AddSequenceLength; sequence ++)
      for (sequence = 1; sequence<=addSequenceLength; sequence ++)
      {
        DN deleteDN = DN.valueOf("dc=dependency" + sequence + "," + TEST_ROOT_DN_STRING);
        DeleteMsg delMsg = new DeleteMsg(deleteDN,
                                         gen.newCSN(),
                                         stringUID(sequence + 1025));
        broker.publish(delMsg);
        broker.publish(delMsg(deleteDN, sequence + 1025, gen));
      }
      // check that the database was cleaned successfully
@@ -493,6 +417,28 @@
    }
  }
  private ReplicationServer newReplicationServer(int replServerId, int windowSize, String dirName) throws Exception
  {
    int replServerPort = TestCaseUtils.findFreePort();
    ReplServerFakeConfiguration conf = new ReplServerFakeConfiguration(
        replServerPort, dirName, replicationDbImplementation, 0, replServerId, 0, windowSize, null);
    return new ReplicationServer(conf);
  }
  private LDAPReplicationDomain startNewLDAPReplicationDomain(ReplicationServer replServer, DN baseDN, int serverId,
      int heartBeatInterval) throws ConfigException
  {
    SortedSet<String> replServers = newTreeSet("localhost:" + replServer.getReplicationPort());
    DomainFakeCfg domainConf = new DomainFakeCfg(baseDN, serverId, replServers);
    if (heartBeatInterval > 0)
    {
      domainConf.setHeartbeatInterval(heartBeatInterval);
    }
    LDAPReplicationDomain domain = MultimasterReplication.createNewDomain(domainConf);
    domain.start();
    return domain;
  }
  /**
   * Check that the dependency of moddn operation are working by
   * issuing a set of Add operation followed by a modrdn of the added entry.
@@ -506,29 +452,21 @@
    int brokerId = 2;
    int serverId = 1;
    int replServerId = 84;
    int AddSequenceLength = 30;
    int addSequenceLength = 30;
    cleanDB();
    try
    {
      String entryldif = "dn:" + TEST_ROOT_DN_STRING + "\n"
      + "objectClass: top\n"
      + "objectClass: organization\n";
      Entry entry = TestCaseUtils.entryFromLdifString(entryldif);
      AttributeType uidType =
        DirectoryServer.getSchema().getAttributeType("entryuuid");
      Entry entry = TestCaseUtils.entryFromLdifString(
          "dn:" + TEST_ROOT_DN_STRING + "\n"
          + "objectClass: top\n"
          + "objectClass: organization\n");
      int replServerPort = TestCaseUtils.findFreePort();
      ReplServerFakeConfiguration conf =
        new ReplServerFakeConfiguration(replServerPort, "dependencyTestAddModdnDependencyTestDb", replicationDbImplementation,
                                        0, replServerId, 0, 5*AddSequenceLength+100, null);
      replServer = new ReplicationServer(conf);
      replServer = newReplicationServer(replServerId, 5 * addSequenceLength + 100, "dependencyTestAddModdnDependencyTestDb");
      ReplicationBroker broker = openReplicationSession(
          baseDN, brokerId, 100, replServerPort, 1000, CLEAN_DB_GENERATION_ID);
          baseDN, brokerId, 100, replServer.getReplicationPort(), 1000, CLEAN_DB_GENERATION_ID);
      DN addDN = TEST_ROOT_DN;
@@ -536,36 +474,24 @@
      // send a sequence of add/modrdn operations
      int sequence;
      for (sequence = 1; sequence<=AddSequenceLength; sequence ++)
      for (sequence = 1; sequence<=addSequenceLength; sequence ++)
      {
        // add the entry
        entry.removeAttribute(uidType);
        entry.removeAttribute(getAttributeType("entryuuid"));
        entry.addAttribute(Attributes.create("entryuuid", stringUID(sequence+1)),
                           new LinkedList<ByteString>());
        addDN = DN.valueOf("dc=dependency" + sequence + "," + TEST_ROOT_DN_STRING);
        AddMsg addMsg =
          new AddMsg(gen.newCSN(), addDN, stringUID(sequence+1),
                     stringUID(1),
                     entry.getObjectClassAttribute(),
                     entry.getAttributes(), null );
        broker.publish(addMsg);
        broker.publish(addMsg(addDN, entry, sequence + 1, 1, gen));
        // rename the entry
        ModifyDNMsg moddnMsg =
          new ModifyDNMsg(addDN, gen.newCSN(), stringUID(sequence+1),
                          stringUID(1), true, null, "dc=new_dep" + sequence);
        broker.publish(moddnMsg);
        broker.publish(modDNMsg(addDN, "dc=new_dep" + sequence, sequence + 1, 1, gen));
      }
      // configure and start replication of TEST_ROOT_DN_STRING on the server
      SortedSet<String> replServers = new TreeSet<>();
      replServers.add("localhost:"+replServerPort);
      DomainFakeCfg domainConf = new DomainFakeCfg(baseDN, serverId, replServers);
      domain = MultimasterReplication.createNewDomain(domainConf);
      domain.start();
      domain = startNewLDAPReplicationDomain(replServer, baseDN, serverId, -1);
      // check that all entries have been renamed
      for (sequence = 1; sequence<=AddSequenceLength; sequence ++)
      for (sequence = 1; sequence<=addSequenceLength; sequence ++)
      {
        addDN = DN.valueOf("dc=new_dep" + sequence + "," + TEST_ROOT_DN_STRING);
        Entry baseEntry = getEntry(addDN, 30000, true);
@@ -574,11 +500,10 @@
      }
      // delete the entries to clean the database.
      for (sequence = 1; sequence<=AddSequenceLength; sequence ++)
      for (sequence = 1; sequence<=addSequenceLength; sequence ++)
      {
        addDN = DN.valueOf("dc=new_dep" + sequence + "," + TEST_ROOT_DN_STRING);
        DeleteMsg delMsg = new DeleteMsg(addDN, gen.newCSN(), stringUID(sequence + 1));
        broker.publish(delMsg);
        broker.publish(delMsg(addDN, sequence + 1, gen));
      }
    }
    finally
@@ -601,5 +526,4 @@
  {
    return String.format("11111111-1111-1111-1111-%012x", i);
  }
}