From 86b0f736fd2bec0d9a57f637205c189f0da176ca Mon Sep 17 00:00:00 2001
From: ludovicp <ludovicp@localhost>
Date: Fri, 28 May 2010 14:04:26 +0000
Subject: [PATCH] Fix issue #2934. RootDSEWorkflowTopology now takes into account the ds-cfg-subordinate-base-dn.

---
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/TestCaseUtils.java                       |   40 ++++++++++++-
 opendj-sdk/opends/src/server/org/opends/server/backends/RootDSEBackend.java                                     |   42 +++++++++++++
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/NetworkGroupTest.java |   86 ++++++++++++++++++++++++++++
 opendj-sdk/opends/src/server/org/opends/server/core/RootDseWorkflowTopology.java                                |    9 ++-
 4 files changed, 169 insertions(+), 8 deletions(-)

diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/RootDSEBackend.java b/opendj-sdk/opends/src/server/org/opends/server/backends/RootDSEBackend.java
index 8481001..cf82ccf 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/RootDSEBackend.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/RootDSEBackend.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2006-2009 Sun Microsystems, Inc.
+ *      Copyright 2006-2010 Sun Microsystems, Inc.
  */
 package org.opends.server.backends;
 
@@ -797,6 +797,46 @@
 
 
   /**
+   * Determines the workflow nodes which handle subordinate naming contexts.
+   * A workflow node is handling a subordinate naming context if the workflow
+   * base DN is in the list of the RootDSE subordinate naming contexts.
+   *
+   * @param   nodes
+   *          The list from which we search the workflow nodes which
+   *          are handling subordinate naming contexts
+   *
+   * @return  The list of workflow nodes that are handling subordinate
+   *          naming contexts
+   */
+  public Iterable<WorkflowTopologyNode> getSubordinateNamingContexts(
+      Iterable<WorkflowTopologyNode> nodes)
+  {
+    // If the list of subordinate naming contexts is null
+    // then return the whole list of workflow nodes.
+    if (subordinateBaseDNs == null)
+    {
+      return nodes;
+    }
+
+    // The returned list of subordinate naming contexts
+    List<WorkflowTopologyNode> subNC = new ArrayList<WorkflowTopologyNode>();
+
+    // Determine which workflow node is handling a subordinate naming context.
+    for (WorkflowTopologyNode node : nodes)
+    {
+      DN dn = node.getBaseDN();
+      if (subordinateBaseDNs.containsKey(dn))
+      {
+        subNC.add(node);
+      }
+    }
+
+    return subNC;
+  }
+
+
+
+  /**
    * }
    * Creates an attribute for the root DSE with the following criteria.
    *
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/RootDseWorkflowTopology.java b/opendj-sdk/opends/src/server/org/opends/server/core/RootDseWorkflowTopology.java
index b00fcb7..1ce5aed 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/RootDseWorkflowTopology.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/RootDseWorkflowTopology.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2008-2009 Sun Microsystems, Inc.
+ *      Copyright 2008-2010 Sun Microsystems, Inc.
  */
 package org.opends.server.core;
 
@@ -125,8 +125,11 @@
     searchOp.setScope(newScope);
     DN originalBaseDN = searchOp.getBaseDN();
 
-    for (WorkflowTopologyNode namingContext:
-         namingContexts.getPublicNamingContexts())
+    Iterable<WorkflowTopologyNode> ncToSearch =
+      DirectoryServer.getRootDSEBackend().getSubordinateNamingContexts(
+          namingContexts.getPublicNamingContexts());
+
+    for (WorkflowTopologyNode namingContext: ncToSearch)
     {
       // We have to change the operation request base DN to match the
       // subordinate workflow base DN. Otherwise the workflow will
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/TestCaseUtils.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/TestCaseUtils.java
index b09417f..ed41bf4 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/TestCaseUtils.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/TestCaseUtils.java
@@ -789,9 +789,32 @@
          throws IOException, InitializationException, ConfigException,
                 DirectoryException
   {
+    initializeMemoryBackend(
+        TEST_BACKEND_ID, TEST_ROOT_DN_STRING, createBaseEntry);
+  }
+
+  /**
+   * Initializes a memory-based backend that may be used to perform operations
+   * while testing the server.  This will ensure that the memory backend is
+   * created in the server if it does not yet exist, and that it is empty.
+   *
+   * @param  backendID        the ID of the backend to create
+   * @param  namingContext    the naming context to create in the backend
+   * @param  createBaseEntry  Indicate whether to automatically create the base
+   *                          entry and add it to the backend.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  public static void initializeMemoryBackend(
+      String backendID,
+      String namingContext,
+      boolean createBaseEntry
+      ) throws IOException, InitializationException, ConfigException,
+                DirectoryException
+  {
     startServer();
 
-    DN baseDN = DN.decode(TEST_ROOT_DN_STRING);
+    DN baseDN = DN.decode(namingContext);
 
     // Retrieve backend. Warning: it is important to perform this each time,
     // because a test may have disabled then enabled the backend (i.e a test
@@ -800,12 +823,12 @@
     // to memory backend must be invalidated. So to prevent this problem, we
     // retrieve the memory backend reference each time before cleaning it.
     MemoryBackend memoryBackend =
-        (MemoryBackend)DirectoryServer.getBackend(TEST_BACKEND_ID);
+        (MemoryBackend)DirectoryServer.getBackend(backendID);
 
     if (memoryBackend == null)
     {
       memoryBackend = new MemoryBackend();
-      memoryBackend.setBackendID(TEST_BACKEND_ID);
+      memoryBackend.setBackendID(backendID);
       memoryBackend.setBaseDNs(new DN[] {baseDN});
       memoryBackend.initializeBackend();
       DirectoryServer.registerBackend(memoryBackend);
@@ -821,6 +844,17 @@
   }
 
   /**
+   * Clears a memory-based backend.
+   */
+  public static void clearMemoryBackend(String backendID) throws Exception
+  {
+    MemoryBackend memoryBackend =
+      (MemoryBackend) DirectoryServer.getBackend(backendID);
+    if (memoryBackend != null)
+      memoryBackend.clearMemoryBackend();
+  }
+
+  /**
    * Clears all the entries from the JE backend determined by the
    * be id passed into the method.
 
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/NetworkGroupTest.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/NetworkGroupTest.java
index 5940283..eb6573c 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/NetworkGroupTest.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/NetworkGroupTest.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2006-2009 Sun Microsystems, Inc.
+ *      Copyright 2006-2010 Sun Microsystems, Inc.
  */
 package org.opends.server.core.networkgroups;
 
@@ -1134,6 +1134,90 @@
 
 
   /**
+   * This test checks that the network group takes into account the
+   * subordinate naming context defined in the RootDSEBackend.
+   */
+  @Test
+  public void testRootDseSubordinateNamingContext()
+         throws Exception
+  {
+    // Backends for the test
+    String backend1   = "o=test-rootDSE-subordinate-naming-context-1";
+    String backend2   = "o=test-rootDSE-subordinate-naming-context-2";
+    String backendID1 = "test-rootDSE-subordinate-naming-context-1";
+    String backendID2 = "test-rootDSE-subordinate-naming-context-2";
+
+    // Clean all the backends.
+    TestCaseUtils.clearDataBackends();
+
+    // Create a client connection for the test.
+    InternalClientConnection connection =
+      InternalClientConnection.getRootConnection();
+
+    // At this point, the list of subordinate naming context is not defined
+    // yet (null): any public backend should be visible. Create a backend
+    // with a base entry and check that the test naming context is visible.
+    TestCaseUtils.initializeMemoryBackend(backendID1, backend1, true);
+    searchPublicNamingContexts(connection, true,  1);
+
+    // Create another test backend and check that the new backend is visible
+    TestCaseUtils.initializeMemoryBackend(backendID2, backend2, true);
+    searchPublicNamingContexts(connection, true,  2);
+
+    // Now put in the list of subordinate naming context the backend1
+    // naming context. This white list will prevent the backend2 to be
+    // visible.
+    TestCaseUtils.dsconfig(
+        "set-root-dse-backend-prop",
+        "--set", "subordinate-base-dn:" + backend1);
+    searchPublicNamingContexts(connection, true, 1);
+
+    // === Cleaning
+
+    // Reset the subordinate naming context list.
+    // Both naming context should be visible again.
+    TestCaseUtils.dsconfig(
+        "set-root-dse-backend-prop",
+        "--reset", "subordinate-base-dn");
+    searchPublicNamingContexts(connection, true, 2);
+    
+    // Clean the test backends. There is no more naming context.
+    TestCaseUtils.clearMemoryBackend(backendID1);
+    TestCaseUtils.clearMemoryBackend(backendID2);
+    searchPublicNamingContexts(connection, false, 0);
+  }
+
+
+  /**
+   * Searches the list of naming contexts.
+   *
+   * @param connection    the connection to use for the search request
+   * @param shouldExist   indicates whether at least one NC should be found
+   * @param expectedNamingContexts  the number of expected naming contexts
+   */
+  private void searchPublicNamingContexts(
+      InternalClientConnection connection,
+      boolean shouldExist,
+      int expectedNamingContexts
+      ) throws Exception
+  {
+    SearchOperation search = connection.processSearch(
+        DN.decode(""),
+        SearchScope.SINGLE_LEVEL,
+        LDAPFilter.decode("(objectClass=*)").toSearchFilter());
+
+    // Check the number of found naming context
+    ResultCode expectedRC =
+      (shouldExist ? ResultCode.SUCCESS : ResultCode.NO_SUCH_OBJECT);
+    assertEquals(search.getResultCode(), expectedRC);
+    if (shouldExist)
+    {
+      assertEquals(search.getEntriesSent(), expectedNamingContexts);
+    }
+  }
+
+
+  /**
    * Searches an entry on a given connection.
    *
    * @param connection    the connection to use for the search request

--
Gitblit v1.10.0