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

Nicolas Capponi
11.56.2014 dad6b68360a7aa7d0cbc43aa1310c0aad970bd00
opendj3-server-dev/src/server/org/opends/server/replication/server/changelog/je/ChangeNumberIndexer.java
@@ -39,7 +39,11 @@
import org.opends.server.replication.plugin.MultimasterReplication;
import org.opends.server.replication.protocol.UpdateMsg;
import org.opends.server.replication.server.ChangelogState;
import org.opends.server.replication.server.changelog.api.*;
import org.opends.server.replication.server.changelog.api.ChangeNumberIndexRecord;
import org.opends.server.replication.server.changelog.api.ChangelogDB;
import org.opends.server.replication.server.changelog.api.ChangelogException;
import org.opends.server.replication.server.changelog.api.DBCursor;
import org.opends.server.replication.server.changelog.api.ReplicationDomainDB;
import org.opends.server.types.DN;
import org.opends.server.types.DirectoryException;
import org.opends.server.util.StaticUtils;
@@ -690,7 +694,13 @@
      {
        StaticUtils.close(map.values());
      }
      newCursors.remove(baseDN);
      for (Iterator<Pair<DN, Integer>> it = newCursors.keySet().iterator(); it.hasNext();)
      {
        if (it.next().getFirst().equals(baseDN))
        {
          it.remove();
        }
      }
    }
  }
opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/replication/server/ExternalChangeLogTest.java
@@ -167,14 +167,14 @@
   * Launcher.
   */
  @Test(enabled=true)
  public void ECLReplicationServerPreTest() throws Exception
  public void PreTest() throws Exception
  {
    // No RSDomain created yet => RS only case => ECL is not a supported
    ECLIsNotASupportedSuffix();
  }
  @Test(enabled=true, dependsOnMethods = { "ECLReplicationServerPreTest"})
  public void ECLReplicationServerTest() throws Exception
  @Test(enabled=true, dependsOnMethods = { "PreTest"})
  public void PrimaryTest() throws Exception
  {
    replicationServer.getChangelogDB().setPurgeDelay(0);
    // let's enable ECl manually now that we tested that ECl is not available
@@ -194,23 +194,29 @@
    ECLCompatTestLimits(1,4,true);
  }
  @Test(enabled=false, dependsOnMethods = { "ECLReplicationServerTest"})
  public void ECLReplicationServerTest1() throws Exception
  @Test(enabled=false, dependsOnMethods = { "PrimaryTest"})
  public void TestWithTwoDomains() throws Exception
  {
    replicationServer.getChangelogDB().setPurgeDelay(0);
    // Test with a mix of domains, a mix of DSes
    ECLTwoDomains();
  }
  @Test(enabled=false, dependsOnMethods = { "ECLReplicationServerTest"})
  public void ECLReplicationServerTest2() throws Exception
  @Test(enabled=false, dependsOnMethods = { "PrimaryTest"})
  public void TestAfterChangelogTrim() throws Exception
  {
    // Test ECL after changelog trimming
    ECLAfterChangelogTrim();
  }
  @Test(enabled=true, dependsOnMethods = { "ECLReplicationServerTest"})
  public void ECLReplicationServerTest3() throws Exception
  @Test(enabled=true, dependsOnMethods = { "PrimaryTest"})
  public void TestAfterDomainIsRemoved() throws Exception
  {
    ECLAfterDomainIsRemoved();
  }
  @Test(enabled=true, dependsOnMethods = { "PrimaryTest"})
  public void TestWithAndWithoutControl() throws Exception
  {
    replicationServer.getChangelogDB().setPurgeDelay(0);
    // Write changes and read ECL from start
@@ -222,20 +228,20 @@
    ECLCompatWriteReadAllOps(5);
  }
  @Test(enabled=true, dependsOnMethods = { "ECLReplicationServerTest"})
  public void ECLReplicationServerTest4() throws Exception
  @Test(enabled = true, dependsOnMethods = { "TestWithAndWithoutControl" })
  public void TestWithIncludeAttributes() throws Exception
  {
    ECLIncludeAttributes();
  }
  @Test(enabled=true, dependsOnMethods = { "ECLReplicationServerTest"})
  public void ECLReplicationServerTest5() throws Exception
  @Test(enabled=true, dependsOnMethods = { "PrimaryTest"})
  public void TestChangeTimeHeartBeat() throws Exception
  {
    ChangeTimeHeartbeatTest();
  }
  @Test(enabled=true, dependsOnMethods = { "ECLReplicationServerTest"})
  public void ECLReplicationServerTest6() throws Exception
  @Test(enabled=true, dependsOnMethods = { "PrimaryTest"})
  public void TestOperationalAttributesNotVisibleOutsideRootDSE() throws Exception
  {
    // Test that ECL Operational, virtual attributes are not visible
    // outside rootDSE. Next test will test access in RootDSE.
@@ -243,8 +249,8 @@
    ECLOperationalAttributesFailTest();
  }
  @Test(enabled=false, dependsOnMethods = { "ECLReplicationServerTest"})
  public void ECLReplicationServerFullTest() throws Exception
  @Test(enabled=false, dependsOnMethods = { "PrimaryTest"})
  public void PrimaryFullTest() throws Exception
  {
    // ***********************************************
    // First set of test are in the cookie mode
@@ -254,22 +260,22 @@
    ECLOnPrivateBackend();
  }
  @Test(enabled=true, groups="slow", dependsOnMethods = { "ECLReplicationServerTest"})
  public void ECLReplicationServerFullTest1() throws Exception
  @Test(enabled=true, groups="slow", dependsOnMethods = { "PrimaryTest"})
  public void FullTestRemoteAPIWithEmptyECL() throws Exception
  {
    // Test remote API (ECL through replication protocol) with empty ECL
    ECLRemoteEmpty();
  }
  @Test(enabled=true, groups="slow", dependsOnMethods = { "ECLReplicationServerTest"})
  public void ECLReplicationServerFullTest2() throws Exception
  @Test(enabled=true, groups="slow", dependsOnMethods = { "PrimaryTest"})
  public void FullTestWithEmptyECL() throws Exception
  {
    // Test with empty changelog
    ECLEmpty();
  }
  @Test(enabled=false, groups="slow", dependsOnMethods = { "ECLReplicationServerTest"})
  public void ECLReplicationServerFullTest3() throws Exception
  @Test(enabled=false, groups="slow", dependsOnMethods = { "PrimaryTest"})
  public void FullTestPrimaryPlusOperationAttributesNotVisible() throws Exception
  {
    replicationServer.getChangelogDB().setPurgeDelay(0);
    // Test all types of ops.
@@ -285,29 +291,29 @@
    ECLCompatTestLimits(1, 4, true);
  }
  @Test(enabled=false, groups="slow", dependsOnMethods = { "ECLReplicationServerTest"})
  public void ECLReplicationServerFullTest4() throws Exception
  @Test(enabled=false, groups="slow", dependsOnMethods = { "PrimaryTest"})
  public void FullTestRemoteAPIWithNonEmptyECL() throws Exception
  {
    // Test remote API (ECL through replication protocol) with NON empty ECL
    ECLRemoteNonEmpty();
  }
  @Test(enabled=false, groups="slow", dependsOnMethods = { "ECLReplicationServerTest"})
  public void ECLReplicationServerFullTest7() throws Exception
  @Test(enabled=false, groups="slow", dependsOnMethods = { "PrimaryTest"})
  public void FullTestPersistentSearchWithChangesOnlyRequest() throws Exception
  {
    // Persistent search with changesOnly request
    ECLPsearch(true, false);
  }
  @Test(enabled=false, groups="slow", dependsOnMethods = { "ECLReplicationServerTest"})
  public void ECLReplicationServerFullTest8() throws Exception
  @Test(enabled=false, groups="slow", dependsOnMethods = { "PrimaryTest"})
  public void FullTestPersistentSearchWithInitValuesRequest() throws Exception
  {
    // Persistent search with init values request
    ECLPsearch(false, false);
  }
  @Test(enabled=false, groups="slow", dependsOnMethods = { "ECLReplicationServerTest"})
  public void ECLReplicationServerFullTest9() throws Exception
  @Test(enabled=false, groups="slow", dependsOnMethods = { "PrimaryTest"})
  public void FullTestSimultaneousPersistentSearches() throws Exception
  {
    // Simultaneous psearches
    ECLSimultaneousPsearches();
@@ -319,24 +325,16 @@
  // TODO:ECL Test the attributes list and values returned in ECL entries
  // TODO:ECL Test search -s base, -s one
  @Test(enabled=false, groups="slow", dependsOnMethods = { "ECLReplicationServerTest"})
  public void ECLReplicationServerFullTest11() throws Exception
  {
    // Test directly from the java object that the changeTimeHeartbeatState
    // stored are ok.
    ChangeTimeHeartbeatTest();
  }
  @Test(enabled=true, groups="slow", dependsOnMethods = { "ECLReplicationServerTest"})
  public void ECLReplicationServerFullTest12() throws Exception
  @Test(enabled=true, groups="slow", dependsOnMethods = { "PrimaryTest"})
  public void FullTestFilters() throws Exception
  {
    // Test the different forms of filter that are parsed in order to
    // optimize the request.
    ECLFilterTest();
  }
  @Test(enabled=true, groups="slow", dependsOnMethods = { "ECLReplicationServerTest"})
  public void ECLReplicationServerFullTest13() throws Exception
  @Test(enabled=true, groups="slow", dependsOnMethods = { "PrimaryTest"})
  public void FullTestDraftCompatModeWithEmptyECL() throws Exception
  {
    // ***********************************************
    // Second set of test are in the draft compat mode
@@ -345,14 +343,14 @@
    ECLCompatEmpty();
  }
  @Test(enabled=true, groups="slow", dependsOnMethods = { "ECLReplicationServerTest"})
  public void ECLReplicationServerFullTest14() throws Exception
  @Test(enabled=true, groups="slow", dependsOnMethods = { "PrimaryTest"})
  public void FullTestRequestFromInvalidChangeNumber() throws Exception
  {
    // Request from an invalid change number
    ECLCompatBadSeqnum();
  }
  @Test(enabled=false, groups="slow", dependsOnMethods = { "ECLReplicationServerTest"})
  @Test(enabled=false, groups="slow", dependsOnMethods = { "PrimaryTest"})
  public void ECLReplicationServerFullTest15() throws Exception
  {
    replicationServer.getChangelogDB().setPurgeDelay(0);
@@ -388,7 +386,7 @@
    ECLPsearch(true, true);
  }
  @Test(enabled=false, groups="slow", dependsOnMethods = { "ECLReplicationServerTest"})
  @Test(enabled=false, groups="slow", dependsOnMethods = { "PrimaryTest"})
  public void ECLReplicationServerFullTest16() throws Exception
  {
    // Persistent search in init + changes mode
@@ -398,22 +396,22 @@
    // TODO: test with optimization when code done.
    ECLFilterOnReplicationCSN(csn);
  }
  /**
   * Verifies that is not possible to read the changelog without the changelog-read privilege
   */
  @Test(enabled=true, dependsOnMethods = { "ECLReplicationServerTest"})
  @Test(enabled=true, dependsOnMethods = { "PrimaryTest"})
  public void ECLChangelogReadPrivilegeTest() throws Exception
  {
    AuthenticationInfo nonPrivilegedUser = new AuthenticationInfo();
    InternalClientConnection conn = new InternalClientConnection(nonPrivilegedUser);
    InternalSearchOperation ico = conn.processSearch("cn=changelog", SearchScope.WHOLE_SUBTREE, "(objectclass=*)");
    assertEquals(ico.getResultCode(), ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
    assertEquals(ico.getErrorMessage().toMessage(), NOTE_SEARCH_CHANGELOG_INSUFFICIENT_PRIVILEGES.get());
  }
  private void ECLIsNotASupportedSuffix() throws Exception
  {
    ECLCompatTestLimits(0,0, false);
@@ -931,8 +929,8 @@
  /** Test ECL content after replication changelogDB trimming */
  private void ECLAfterChangelogTrim() throws Exception
  {
    String tn = "ECLAfterChangelogTrim";
    debugInfo(tn, "Starting test");
    String testName = "ECLAfterChangelogTrim";
    debugInfo(testName, "Starting test");
    ReplicationBroker server01 = null;
    try
@@ -945,16 +943,16 @@
          100, replicationServerPort, brokerSessionTimeout);
      final CSN[] csns = generateCSNs(3, SERVER_ID_1);
      publishDeleteMsgInOTest(server01, csns[0], tn, 1);
      publishDeleteMsgInOTest(server01, csns[0], testName, 1);
      Thread.sleep(1000);
      // Test that last cookie has been updated
      String cookieNotEmpty = readLastCookie();
      debugInfo(tn, "Store cookie not empty=\"" + cookieNotEmpty + "\"");
      debugInfo(testName, "Store cookie not empty=\"" + cookieNotEmpty + "\"");
      publishDeleteMsgInOTest(server01, csns[1], tn, 2);
      publishDeleteMsgInOTest(server01, csns[2], tn, 3);
      publishDeleteMsgInOTest(server01, csns[1], testName, 2);
      publishDeleteMsgInOTest(server01, csns[2], testName, 3);
      // ---
      // 2. Now set up a very short purge delay on the replication changelogs
@@ -966,22 +964,22 @@
      // since replication changelog has been trimmed
      String cookie= "";
      InternalSearchOperation searchOp =
          searchOnCookieChangelog("(targetDN=*)", cookie, 0, tn, SUCCESS);
          searchOnCookieChangelog("(targetDN=*)", cookie, 0, testName, SUCCESS);
      // ---
      // 4. Assert that a request with the current last cookie returns nothing
      // since replication changelog has been trimmed
      cookie = readLastCookie();
      debugInfo(tn, "2. Search with last cookie=" + cookie + "\"");
      searchOp = searchOnCookieChangelog("(targetDN=*)", cookie, 0, tn, SUCCESS);
      debugInfo(testName, "2. Search with last cookie=" + cookie + "\"");
      searchOp = searchOnCookieChangelog("(targetDN=*)", cookie, 0, testName, SUCCESS);
      // ---
      // 5. Assert that a request with an "old" cookie - one that refers to
      //    changes that have been removed by the replication changelog trimming
      //    returns the appropriate error.
      debugInfo(tn, "d1 trimdate" + getDomainOldestState(TEST_ROOT_DN));
      debugInfo(tn, "d2 trimdate" + getDomainOldestState(TEST_ROOT_DN2));
      searchOp = searchOnCookieChangelog("(targetDN=*)", cookieNotEmpty, 0, tn, UNWILLING_TO_PERFORM);
      debugInfo(testName, "d1 trimdate" + getDomainOldestState(TEST_ROOT_DN));
      debugInfo(testName, "d2 trimdate" + getDomainOldestState(TEST_ROOT_DN2));
      searchOp = searchOnCookieChangelog("(targetDN=*)", cookieNotEmpty, 0, testName, UNWILLING_TO_PERFORM);
      assertTrue(searchOp.getErrorMessage().toString().startsWith(
          ERR_RESYNC_REQUIRED_TOO_OLD_DOMAIN_IN_PROVIDED_COOKIE.get(TEST_ROOT_DN_STRING).toString()),
          searchOp.getErrorMessage().toString());
@@ -992,7 +990,69 @@
      // And reset changelog purge delay for the other tests.
      replicationServer.getChangelogDB().setPurgeDelay(15 * 1000);
    }
    debugInfo(tn, "Ending test successfully");
    debugInfo(testName, "Ending test successfully");
  }
  /** Test ECL content after a domain has been removed. */
  private void ECLAfterDomainIsRemoved() throws Exception
  {
    String testName = "ECLAfterDomainIsRemoved";
    debugInfo(testName, "Starting test");
    ReplicationBroker server01 = null;
    try
    {
      // ---
      // 1. Populate the changelog and read the cookie
      // Creates server broker on o=test
      server01 = openReplicationSession(TEST_ROOT_DN, SERVER_ID_1, 100, replicationServerPort, brokerSessionTimeout);
      final CSN[] csns = generateCSNs(3, SERVER_ID_1);
      publishDeleteMsgInOTest(server01, csns[0], testName, 1);
      Thread.sleep(1000);
      // Test that last cookie has been updated
      String cookieNotEmpty = readLastCookie();
      debugInfo(testName, "Store cookie not empty=\"" + cookieNotEmpty + "\"");
      publishDeleteMsgInOTest(server01, csns[1], testName, 2);
      publishDeleteMsgInOTest(server01, csns[2], testName, 3);
      // ---
      // 2. Now remove the domain by sending a reset message
      ResetGenerationIdMsg msg = new ResetGenerationIdMsg(23657);
      server01.publish(msg);
      // ---
      // 3. Assert that a request with an empty cookie returns nothing
      // since replication changelog has been cleared
      String cookie= "";
      InternalSearchOperation searchOp = null;
      searchOnCookieChangelog("(targetDN=*)", cookie, 0, testName, SUCCESS);
      // ---
      // 4. Assert that a request with the current last cookie returns nothing
      // since replication changelog has been cleared
      cookie = readLastCookie();
      debugInfo(testName, "2. Search with last cookie=" + cookie + "\"");
      searchOp = searchOnCookieChangelog("(targetDN=*)", cookie, 0, testName, SUCCESS);
      // ---
      // 5. Assert that a request with an "old" cookie - one that refers to
      //    changes that have been removed by the replication changelog clearing
      //    returns the appropriate error.
      debugInfo(testName, "d1 trimdate" + getDomainOldestState(TEST_ROOT_DN));
      debugInfo(testName, "d2 trimdate" + getDomainOldestState(TEST_ROOT_DN2));
      searchOp = searchOnCookieChangelog("(targetDN=*)", cookieNotEmpty, 0, testName, UNWILLING_TO_PERFORM);
      assertThat(searchOp.getErrorMessage().toString()).contains("unknown replicated domain", TEST_ROOT_DN_STRING.toString());
    }
    finally
    {
      stop(server01);
    }
    debugInfo(testName, "Ending test successfully");
  }
  private void debugAndWriteEntries(LDIFWriter ldifWriter,