From ccd66a6d38f7d3a55a4fddd2945d8ab8920b007e Mon Sep 17 00:00:00 2001
From: Nicolas Capponi <nicolas.capponi@forgerock.com>
Date: Mon, 07 Nov 2016 15:05:30 +0000
Subject: [PATCH] OPENDJ-3417 Move management of backends and listeners from DirectoryServer to BackendConfigManager

---
 opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java                                     |  205 ++----------------
 opendj-server-legacy/src/main/java/org/opends/server/backends/RootDSEBackend.java                                  |    8 
 opendj-server-legacy/src/main/java/org/opends/server/backends/MonitorBackend.java                                  |    7 
 opendj-server-legacy/src/main/java/org/opends/server/core/SubentryManager.java                                     |    4 
 opendj-server-legacy/src/test/java/org/opends/server/backends/ChangelogBackendTestCase.java                        |    1 
 opendj-server-legacy/src/main/java/org/opends/server/backends/ChangelogBackend.java                                |    5 
 opendj-server-legacy/src/main/java/org/opends/server/backends/MemoryBackend.java                                   |    7 
 opendj-server-legacy/src/main/java/org/opends/server/extensions/DefaultEntryCache.java                             |    4 
 opendj-server-legacy/src/main/java/org/opends/server/backends/LDIFBackend.java                                     |    9 
 opendj-server-legacy/src/main/java/org/opends/server/backends/SchemaBackend.java                                   |    8 
 opendj-server-legacy/src/main/java/org/opends/server/backends/BackupBackend.java                                   |    8 
 opendj-server-legacy/src/test/java/org/opends/server/core/BackendConfigManagerTestCase.java                        |   14 
 opendj-server-legacy/src/main/java/org/opends/server/api/LocalBackendInitializationListener.java                   |    4 
 opendj-server-legacy/src/test/java/org/opends/server/TestCaseUtils.java                                            |   17 +
 opendj-server-legacy/src/test/java/org/opends/server/types/TestDN.java                                             |    2 
 opendj-server-legacy/src/main/java/org/opends/server/backends/task/TaskBackend.java                                |    4 
 opendj-server-legacy/src/main/java/org/opends/server/backends/ConfigurationBackend.java                            |    9 
 opendj-server-legacy/src/main/java/org/opends/server/core/BackendConfigManager.java                                |  249 ++++++++++++++++++++-
 opendj-server-legacy/src/main/java/org/opends/server/core/ServerContext.java                                       |    2 
 opendj-server-legacy/src/main/java/org/opends/server/backends/NullBackend.java                                     |    4 
 opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java |    2 
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/Task.java                                 |    3 
 opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/BackendImpl.java                           |    8 
 opendj-server-legacy/src/main/java/org/opends/server/core/GroupManager.java                                        |    4 
 opendj-server-legacy/src/main/java/org/opends/server/replication/plugin/LDAPReplicationDomain.java                 |    4 
 opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciListenerManager.java              |    4 
 opendj-server-legacy/src/main/java/org/opends/server/backends/TrustStoreBackend.java                               |    7 
 opendj-server-legacy/src/main/java/org/opends/server/crypto/CryptoManagerSync.java                                 |    4 
 28 files changed, 350 insertions(+), 257 deletions(-)

diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/Task.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/Task.java
index 38f0ab0..dbfcb29 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/Task.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/Task.java
@@ -240,7 +240,8 @@
     getInfo().stopPooling();
     if (getInfo().mustDeregisterConfig())
     {
-      DirectoryServer.deregisterBaseDN(DN.valueOf("cn=config"));
+      DirectoryServer.getInstance().getServerContext().getBackendConfigManager()
+        .deregisterBaseDN(DN.valueOf("cn=config"));
     }
     DirectoryServer.getInstance().initializeConfiguration(ConfigReader.configFile);
     getInfo().setMustDeregisterConfig(true);
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/api/BackendInitializationListener.java b/opendj-server-legacy/src/main/java/org/opends/server/api/LocalBackendInitializationListener.java
similarity index 96%
rename from opendj-server-legacy/src/main/java/org/opends/server/api/BackendInitializationListener.java
rename to opendj-server-legacy/src/main/java/org/opends/server/api/LocalBackendInitializationListener.java
index 26be45b..1ab4490 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/api/BackendInitializationListener.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/api/LocalBackendInitializationListener.java
@@ -21,14 +21,14 @@
 /**
  * This interface defines a set of methods that may be used by server
  * components to perform any processing that they might find necessary
- * whenever a backend is initialized and/or finalized.
+ * whenever a local backend is initialized and/or finalized.
  */
 @org.opends.server.types.PublicAPI(
      stability=org.opends.server.types.StabilityLevel.VOLATILE,
      mayInstantiate=false,
      mayExtend=true,
      mayInvoke=false)
-public interface BackendInitializationListener
+public interface LocalBackendInitializationListener
 {
   /**
    * Performs any processing that may be required whenever a backend
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciListenerManager.java b/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciListenerManager.java
index a913191..b12ff9b 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciListenerManager.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciListenerManager.java
@@ -34,7 +34,7 @@
 import org.forgerock.opendj.ldap.schema.AttributeType;
 import org.opends.server.api.AlertGenerator;
 import org.opends.server.api.LocalBackend;
-import org.opends.server.api.BackendInitializationListener;
+import org.opends.server.api.LocalBackendInitializationListener;
 import org.opends.server.api.plugin.InternalDirectoryServerPlugin;
 import org.opends.server.api.plugin.PluginResult;
 import org.opends.server.api.plugin.PluginResult.PostOperation;
@@ -64,7 +64,7 @@
  * finalized.
  */
 public class AciListenerManager implements
-    BackendInitializationListener, AlertGenerator
+    LocalBackendInitializationListener, AlertGenerator
 {
   private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
 
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/BackupBackend.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/BackupBackend.java
index d482425..bdb192e 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/BackupBackend.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/BackupBackend.java
@@ -104,6 +104,9 @@
   /** A cache of BackupDirectories. */
   private HashMap<File,CachedBackupDirectory> backupDirectories;
 
+  /** The server context. */
+  private ServerContext serverContext;
+
   /**
    * To avoid parsing and reparsing the contents of backup.info files, we
    * cache the BackupDirectory for each directory using this class.
@@ -172,6 +175,7 @@
   @Override
   public void configureBackend(BackupBackendCfg config, ServerContext serverContext) throws ConfigException
   {
+    this.serverContext = serverContext;
     // Make sure that a configuration entry was provided.  If not, then we will
     // not be able to complete initialization.
     if (config == null)
@@ -232,7 +236,7 @@
     // Register the backup base as a private suffix.
     try
     {
-      DirectoryServer.registerBaseDN(backupBaseDN, this, true);
+      serverContext.getBackendConfigManager().registerBaseDN(backupBaseDN, this, true);
     }
     catch (Exception e)
     {
@@ -251,7 +255,7 @@
 
     try
     {
-      DirectoryServer.deregisterBaseDN(backupBaseDN);
+      serverContext.getBackendConfigManager().deregisterBaseDN(backupBaseDN);
     }
     catch (Exception e)
     {
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/ChangelogBackend.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/ChangelogBackend.java
index 8d7aa45..95c62c0 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/ChangelogBackend.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/ChangelogBackend.java
@@ -257,7 +257,8 @@
 
     try
     {
-      DirectoryServer.registerBaseDN(CHANGELOG_BASE_DN, this, true);
+      DirectoryServer.getInstance().getServerContext().getBackendConfigManager()
+        .registerBaseDN(CHANGELOG_BASE_DN, this, true);
     }
     catch (final DirectoryException e)
     {
@@ -271,7 +272,7 @@
   {
     try
     {
-      DirectoryServer.deregisterBaseDN(CHANGELOG_BASE_DN);
+      DirectoryServer.getInstance().getServerContext().getBackendConfigManager().deregisterBaseDN(CHANGELOG_BASE_DN);
     }
     catch (final DirectoryException e)
     {
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/ConfigurationBackend.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/ConfigurationBackend.java
index 62866be..96ec891 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/ConfigurationBackend.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/ConfigurationBackend.java
@@ -50,7 +50,6 @@
 import org.opends.server.config.ConfigurationHandler;
 import org.opends.server.core.AddOperation;
 import org.opends.server.core.DeleteOperation;
-import org.opends.server.core.DirectoryServer;
 import org.opends.server.core.ModifyDNOperation;
 import org.opends.server.core.ModifyOperation;
 import org.opends.server.core.SearchOperation;
@@ -192,6 +191,9 @@
    */
   private final Object configLock = new Object();
 
+  /** The server context. */
+  private final ServerContext serverContext;
+
   /**
    * Creates and initializes a new instance of this backend.
    *
@@ -205,6 +207,7 @@
   public ConfigurationBackend(ServerContext serverContext, ConfigurationHandler configurationHandler)
       throws InitializationException
   {
+    this.serverContext = serverContext;
     this.configurationHandler = configurationHandler;
     this.configRootEntry = Converters.to(configurationHandler.getRootEntry());
     baseDNs = Collections.singleton(configRootEntry.getName());
@@ -227,7 +230,7 @@
   {
     try
     {
-      DirectoryServer.deregisterBaseDN(configRootEntry.getName());
+      serverContext.getBackendConfigManager().deregisterBaseDN(configRootEntry.getName());
     }
     catch (Exception e)
     {
@@ -247,7 +250,7 @@
     DN baseDN = configRootEntry.getName();
     try
     {
-      DirectoryServer.registerBaseDN(baseDN, this, true);
+      serverContext.getBackendConfigManager().registerBaseDN(baseDN, this, true);
     }
     catch (DirectoryException e)
     {
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/LDIFBackend.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/LDIFBackend.java
index 0283aa2..1b41013 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/LDIFBackend.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/LDIFBackend.java
@@ -107,6 +107,9 @@
   /** The path to the LDIF file containing the data for this backend. */
   private String ldifFilePath;
 
+  /** The server context. */
+  private ServerContext serverContext;
+
   /**
    * Creates a new backend with the provided information.  All backend
    * implementations must implement a default constructor that use
@@ -132,8 +135,7 @@
     {
       try
       {
-        DirectoryServer.registerBaseDN(dn, this,
-                                       currentConfig.isIsPrivateBackend());
+        serverContext.getBackendConfigManager().registerBaseDN(dn, this, currentConfig.isIsPrivateBackend());
       }
       catch (Exception e)
       {
@@ -337,7 +339,7 @@
       {
         try
         {
-          DirectoryServer.deregisterBaseDN(dn);
+          serverContext.getBackendConfigManager().deregisterBaseDN(dn);
         }
         catch (Exception e)
         {
@@ -1191,6 +1193,7 @@
   @Override
   public void configureBackend(LDIFBackendCfg config, ServerContext serverContext) throws ConfigException
   {
+    this.serverContext = serverContext;
     if (config != null)
     {
       currentConfig = config;
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/MemoryBackend.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/MemoryBackend.java
index 986d7e4..68b3fe0 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/MemoryBackend.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/MemoryBackend.java
@@ -105,6 +105,8 @@
   private Map<DN, HashSet<DN>> childDNs;
   /** The mapping between entry DNs and the corresponding entries. */
   private LinkedHashMap<DN,Entry> entryMap;
+  /** The server context. */
+  private ServerContext serverContext;
 
   /**
    * Creates a new backend with the provided information.  All backend
@@ -132,6 +134,7 @@
   @Override
   public void configureBackend(MemoryBackendCfg config, ServerContext serverContext) throws ConfigException
   {
+    this.serverContext = serverContext;
     if (config != null)
     {
       this.baseDNs = config.getBaseDN();
@@ -157,7 +160,7 @@
     {
       try
       {
-        DirectoryServer.registerBaseDN(dn, this, false);
+        serverContext.getBackendConfigManager().registerBaseDN(dn, this, false);
       }
       catch (Exception e)
       {
@@ -186,7 +189,7 @@
     {
       try
       {
-        DirectoryServer.deregisterBaseDN(dn);
+        serverContext.getBackendConfigManager().deregisterBaseDN(dn);
       }
       catch (Exception e)
       {
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/MonitorBackend.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/MonitorBackend.java
index 0bd63a3..9a45423 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/MonitorBackend.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/MonitorBackend.java
@@ -102,6 +102,8 @@
   private DN baseMonitorDN;
   /** The set of base DNs for this backend. */
   private Set<DN> baseDNs;
+  /** The server context. */
+  private ServerContext serverContext;
 
   /**
    * Creates a new backend with the provided information. All backend
@@ -167,6 +169,7 @@
       throws ConfigException
   {
     Reject.ifNull(config);
+    this.serverContext = serverContext;
 
     final MonitorBackendCfg cfg = config;
     final Entry configEntry = DirectoryServer.getConfigEntry(cfg.dn());
@@ -296,7 +299,7 @@
     currentConfig.removeMonitorChangeListener(this);
     try
     {
-      DirectoryServer.deregisterBaseDN(baseMonitorDN);
+      serverContext.getBackendConfigManager().deregisterBaseDN(baseMonitorDN);
     }
     catch (final Exception e)
     {
@@ -387,7 +390,7 @@
     // Register the monitor base as a private suffix.
     try
     {
-      DirectoryServer.registerBaseDN(baseMonitorDN, this, true);
+      serverContext.getBackendConfigManager().registerBaseDN(baseMonitorDN, this, true);
     }
     catch (final Exception e)
     {
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/NullBackend.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/NullBackend.java
index 23c1358..5b8f42a 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/NullBackend.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/NullBackend.java
@@ -136,7 +136,7 @@
     {
       try
       {
-        DirectoryServer.registerBaseDN(dn, this, false);
+        serverContext.getBackendConfigManager().registerBaseDN(dn, this, false);
       }
       catch (Exception e)
       {
@@ -177,7 +177,7 @@
     {
       try
       {
-        DirectoryServer.deregisterBaseDN(dn);
+        serverContext.getBackendConfigManager().deregisterBaseDN(dn);
       }
       catch (Exception e)
       {
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/RootDSEBackend.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/RootDSEBackend.java
index fff1f37..fc300ea 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/RootDSEBackend.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/RootDSEBackend.java
@@ -331,7 +331,7 @@
 
     // Add the "ds-private-naming-contexts" attribute.
     Attribute privateNamingContextAttr = createAttribute(
-        ATTR_PRIVATE_NAMING_CONTEXTS, serverContext.getBackendManager().getPrivateNamingContexts().keySet());
+        ATTR_PRIVATE_NAMING_CONTEXTS, serverContext.getBackendConfigManager().getPrivateNamingContexts().keySet());
     addAttribute(privateNamingContextAttr, dseUserAttrs, dseOperationalAttrs);
 
     // Add the "supportedControl" attribute.
@@ -419,7 +419,7 @@
     // TODO: this duplicates what is done in DirectoryServer (see DirectoryServer.getSupportedControls())
     // How should this be handled ?
     final Set<String> controls = new HashSet<>();
-    for (Backend<?> backend : serverContext.getBackendManager().getAllBackends())
+    for (Backend<?> backend : serverContext.getBackendConfigManager().getAllBackends())
     {
       controls.addAll(backend.getSupportedControls());
     }
@@ -429,7 +429,7 @@
   private Set<DN> getAllPublicNamingContexts()
   {
     Set<DN> namingContexts = new HashSet<>();
-    for (Backend<?> backend : serverContext.getBackendManager().getAllBackends())
+    for (Backend<?> backend : serverContext.getBackendConfigManager().getAllBackends())
     {
       namingContexts.addAll(backend.getBaseDNs());
     }
@@ -440,7 +440,7 @@
   {
     // TODO: this implementation is insufficient because it handles only the local backends
     // The non-local backends must be added for completeness
-    return new HashSet<DN>(serverContext.getBackendManager().getPublicNamingContexts().keySet());
+    return new HashSet<DN>(serverContext.getBackendConfigManager().getPublicNamingContexts().keySet());
   }
 
   private void addAll(Collection<Attribute> attributes,
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/SchemaBackend.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/SchemaBackend.java
index 18c183c..2f15fa5 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/SchemaBackend.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/SchemaBackend.java
@@ -214,7 +214,7 @@
     DirectoryServer.setSchemaDN(baseDNs.iterator().next());
     for (DN baseDN : baseDNs) {
       try {
-        DirectoryServer.registerBaseDN(baseDN, this, true);
+        serverContext.getBackendConfigManager().registerBaseDN(baseDN, this, true);
       } catch (Exception e) {
         logger.traceException(e);
 
@@ -237,7 +237,7 @@
     {
       try
       {
-        DirectoryServer.deregisterBaseDN(baseDN);
+        serverContext.getBackendConfigManager().deregisterBaseDN(baseDN);
       }
       catch (Exception e)
       {
@@ -1783,7 +1783,7 @@
       {
         try
         {
-          DirectoryServer.deregisterBaseDN(dn);
+          serverContext.getBackendConfigManager().deregisterBaseDN(dn);
           ccr.addMessage(INFO_SCHEMA_DEREGISTERED_BASE_DN.get(dn));
         }
         catch (Exception e)
@@ -1800,7 +1800,7 @@
       {
         try
         {
-          DirectoryServer.registerBaseDN(dn, this, true);
+          serverContext.getBackendConfigManager().registerBaseDN(dn, this, true);
           ccr.addMessage(INFO_SCHEMA_REGISTERED_BASE_DN.get(dn));
         }
         catch (Exception e)
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/TrustStoreBackend.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/TrustStoreBackend.java
index 0bb5e8b..579eb46 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/TrustStoreBackend.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/TrustStoreBackend.java
@@ -117,6 +117,8 @@
 
   /** The certificate manager for the trust store. */
   private CertificateManager certificateManager;
+  /** The server context. */
+  private ServerContext serverContext;
 
   /**
    * Creates a new backend.  All backend
@@ -138,6 +140,7 @@
   @Override
   public void configureBackend(TrustStoreBackendCfg config, ServerContext serverContext) throws ConfigException
   {
+    this.serverContext = serverContext;
     Reject.ifNull(config);
     configuration = config;
   }
@@ -204,7 +207,7 @@
     // Register the trust store base as a private suffix.
     try
     {
-      DirectoryServer.registerBaseDN(getBaseDN(), this, true);
+      serverContext.getBackendConfigManager().registerBaseDN(getBaseDN(), this, true);
     }
     catch (Exception e)
     {
@@ -302,7 +305,7 @@
 
     try
     {
-      DirectoryServer.deregisterBaseDN(getBaseDN());
+      serverContext.getBackendConfigManager().deregisterBaseDN(getBaseDN());
     }
     catch (Exception e)
     {
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/BackendImpl.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/BackendImpl.java
index ac37586..8a4d621 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/BackendImpl.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/BackendImpl.java
@@ -198,7 +198,7 @@
     {
       try
       {
-        DirectoryServer.registerBaseDN(dn, this, false);
+        serverContext.getBackendConfigManager().registerBaseDN(dn, this, false);
       }
       catch (Exception e)
       {
@@ -224,7 +224,7 @@
     {
       try
       {
-        DirectoryServer.deregisterBaseDN(dn);
+        serverContext.getBackendConfigManager().deregisterBaseDN(dn);
       }
       catch (Exception e)
       {
@@ -862,7 +862,7 @@
       if (!newBaseDNs.contains(baseDN))
       {
         // The base DN was deleted.
-        DirectoryServer.deregisterBaseDN(baseDN);
+        serverContext.getBackendConfigManager().deregisterBaseDN(baseDN);
         EntryContainer ec = rootContainer.unregisterEntryContainer(baseDN);
         ec.close();
         ec.delete(txn);
@@ -881,7 +881,7 @@
           // The base DN was added.
           EntryContainer ec = rootContainer.openEntryContainer(baseDN, txn, AccessMode.READ_WRITE);
           rootContainer.registerEntryContainer(baseDN, ec);
-          DirectoryServer.registerBaseDN(baseDN, this, false);
+          serverContext.getBackendConfigManager().registerBaseDN(baseDN, this, false);
         }
         catch (Exception e)
         {
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/task/TaskBackend.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/task/TaskBackend.java
index 17a7b55..f000dbf 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/task/TaskBackend.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/task/TaskBackend.java
@@ -227,7 +227,7 @@
     // Register the task base as a private suffix.
     try
     {
-      DirectoryServer.registerBaseDN(taskRootDN, this, true);
+      serverContext.getBackendConfigManager().registerBaseDN(taskRootDN, this, true);
     }
     catch (Exception e)
     {
@@ -267,7 +267,7 @@
 
     try
     {
-      DirectoryServer.deregisterBaseDN(taskRootDN);
+      serverContext.getBackendConfigManager().deregisterBaseDN(taskRootDN);
     }
     catch (Exception e)
     {
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/BackendConfigManager.java b/opendj-server-legacy/src/main/java/org/opends/server/core/BackendConfigManager.java
index ff77bc5..d39be75 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/BackendConfigManager.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/core/BackendConfigManager.java
@@ -20,11 +20,9 @@
 import static org.forgerock.util.Reject.ifNull;
 import static org.opends.messages.ConfigMessages.*;
 import static org.opends.messages.CoreMessages.*;
-import static org.opends.server.api.LocalBackend.asLocalBackend;
 import static org.opends.server.core.DirectoryServer.*;
 import static org.opends.server.util.StaticUtils.*;
 
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -35,6 +33,10 @@
 import java.util.Set;
 import java.util.TreeMap;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
 
 import org.forgerock.i18n.LocalizableMessage;
 import org.forgerock.i18n.slf4j.LocalizedLogger;
@@ -51,9 +53,10 @@
 import org.forgerock.opendj.server.config.server.RootCfg;
 import org.opends.server.api.LocalBackend;
 import org.opends.server.api.Backend;
-import org.opends.server.api.BackendInitializationListener;
+import org.opends.server.api.LocalBackendInitializationListener;
 import org.opends.server.backends.ConfigurationBackend;
 import org.opends.server.config.ConfigConstants;
+import org.opends.server.monitors.LocalBackendMonitor;
 import org.opends.server.types.DirectoryException;
 import org.opends.server.types.Entry;
 import org.opends.server.types.InitializationException;
@@ -72,11 +75,23 @@
 {
   private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
 
+  /** The mapping beetwen backends IDs and local backend implementations. */
+  private final Map<String, LocalBackend<?>> localBackends = new ConcurrentHashMap<>();
+
   /** The mapping between configuration entry DNs and their corresponding backend implementations. */
-  private final ConcurrentHashMap<DN, Backend<? extends BackendCfg>> registeredBackends = new ConcurrentHashMap<>();
+  private final Map<DN, Backend<? extends BackendCfg>> registeredBackends = new ConcurrentHashMap<>();
+
+  /** The set of local backend initialization listeners. */
+  private final Set<LocalBackendInitializationListener> initializationListeners = new CopyOnWriteArraySet<>();
+
   private final ServerContext serverContext;
   private final BaseDnRegistry localBackendsRegistry;
 
+  /** Lock to protect reads of the backend maps. */
+  private final ReadLock readLock;
+  /** Lock to protect updates of the backends maps. */
+  private final WriteLock writeLock;
+
   /**
    * Creates a new instance of this backend config manager.
    *
@@ -87,6 +102,9 @@
   {
     this.serverContext = serverContext;
     this.localBackendsRegistry = new BaseDnRegistry();
+    ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+    readLock = lock.readLock();
+    writeLock = lock.writeLock();
   }
 
   /**
@@ -165,7 +183,7 @@
       {
         continue;
       }
-      if (DirectoryServer.hasBackend(backendID))
+      if (hasLocalBackend(backendID))
       {
         // Skip this backend if it is already initialized and registered as available.
         continue;
@@ -236,9 +254,30 @@
 
   private void setLocalBackendWritabilityMode(Backend<?> backend, BackendCfg backendCfg)
   {
-    LocalBackend<?> localBackend = asLocalBackend(backend);
-    LocalBackendCfg localCfg = (LocalBackendCfg) backendCfg;
-    localBackend.setWritabilityMode(toWritabilityMode(localCfg.getWritabilityMode()));
+    if (backend instanceof LocalBackend)
+    {
+      LocalBackend<?> localBackend = (LocalBackend<?>) backend;
+      LocalBackendCfg localCfg = (LocalBackendCfg) backendCfg;
+      localBackend.setWritabilityMode(toWritabilityMode(localCfg.getWritabilityMode()));
+    }
+  }
+
+  /**
+   * Returns the provided backend instance as a LocalBackend.
+   *
+   * @param backend
+   *            A backend
+   * @return a local backend
+   * @throws IllegalArgumentException
+   *            If the provided backend is not a LocalBackend
+   */
+  public static LocalBackend<?> asLocalBackend(Backend<?> backend)
+  {
+    if (backend instanceof LocalBackend)
+    {
+      return (LocalBackend<?>) backend;
+    }
+    throw new IllegalArgumentException("Backend " + backend.getBackendID() + " is not a local backend");
   }
 
   /**
@@ -300,13 +339,23 @@
   }
 
   /**
-   * Returns the collection of all backends.
+   * Returns the set of all backends.
    *
    * @return all backends
    */
-  public Collection<Backend<?>> getAllBackends()
+  public Set<Backend<?>> getAllBackends()
   {
-    return new ArrayList<Backend<?>>(registeredBackends.values());
+    return new HashSet<Backend<?>>(registeredBackends.values());
+  }
+
+  /**
+   * Returns the set of local backends.
+   *
+   * @return the local backends
+   */
+  public Set<LocalBackend<?>> getLocalBackends()
+  {
+    return new HashSet<LocalBackend<?>>(localBackends.values());
   }
 
   /**
@@ -338,7 +387,32 @@
   }
 
   /**
-   * Retrieves the set of subordinate backends that of the backend that corresponds to provided base DN.
+   * Retrieves a local backend provided its identifier.
+   *
+   * @param backendId
+   *          Identifier of the backend
+   * @return the local backend, or {@code null} if there is no local backend registered with the
+   *            specified id.
+   */
+  public LocalBackend<?> getLocalBackend(String backendId)
+  {
+    return localBackends.get(backendId);
+  }
+
+  /**
+   * Indicates whether the local backend with the provided id exists.
+   *
+   * @param backendID
+   *          The backend ID for which to make the determination.
+   * @return {@code true} if a backend with the specified backend ID exists, {@code false} otherwise
+   */
+  public boolean hasLocalBackend(String backendID)
+  {
+    return localBackends.containsKey(backendID);
+  }
+
+  /**
+   * Retrieves the set of subordinate backends of the backend that corresponds to provided base DN.
    *
    * @param baseDN
    *          The base DN for which to retrieve the subordinates backends.
@@ -435,6 +509,61 @@
   }
 
   /**
+   * Registers a local backend.
+   *
+   * @param backend
+   *          The backend to register with the server.
+   *          Neither the backend nor its backend ID may be null.
+   * @throws DirectoryException
+   *           If the backend ID for the provided backend conflicts with the backend ID of an
+   *           existing backend.
+   */
+  public void registerLocalBackend(LocalBackend<?> backend) throws DirectoryException
+  {
+    ifNull(backend);
+    String backendID = backend.getBackendID();
+    ifNull(backendID);
+    writeLock.lock();
+    try
+    {
+      if (localBackends.containsKey(backendID))
+      {
+        LocalizableMessage message = ERR_REGISTER_BACKEND_ALREADY_EXISTS.get(backendID);
+        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
+      }
+      localBackends.put(backendID, backend);
+
+      for (String oid : backend.getSupportedControls())
+      {
+        registerSupportedControl(oid);
+      }
+
+      for (String oid : backend.getSupportedFeatures())
+      {
+        registerSupportedFeature(oid);
+      }
+
+      LocalBackendMonitor monitor = new LocalBackendMonitor(backend);
+      monitor.initializeMonitorProvider(null);
+      backend.setBackendMonitor(monitor);
+      registerMonitorProvider(monitor);
+    }
+    finally {
+      writeLock.unlock();
+    }
+  }
+
+  /**
+   * Registers a local backend initialization listener.
+   *
+   * @param  listener  The listener to register.
+   */
+  public void registerBackendInitializationListener(LocalBackendInitializationListener listener)
+  {
+    initializationListeners.add(listener);
+  }
+
+  /**
    * Deregisters the provided base DN.
    *
    * @param baseDN
@@ -451,6 +580,42 @@
     }
   }
 
+  /**
+   * Deregisters a local backend initialization listener.
+   *
+   * @param  listener  The listener to deregister.
+   */
+  public void deregisterBackendInitializationListener(LocalBackendInitializationListener listener)
+  {
+    initializationListeners.remove(listener);
+  }
+
+  /**
+   * Deregisters a local backend.
+   *
+   * @param backend
+   *          The backend to deregister with the server. It must not be {@code null}.
+   */
+  public void deregisterLocalBackend(LocalBackend<?> backend)
+  {
+    ifNull(backend);
+    writeLock.lock();
+    try
+    {
+      localBackends.remove(backend.getBackendID());
+      LocalBackendMonitor monitor = backend.getBackendMonitor();
+      if (monitor != null)
+      {
+        deregisterMonitorProvider(monitor);
+        monitor.finalizeMonitorProvider();
+        backend.setBackendMonitor(null);
+      }
+    }
+    finally {
+      writeLock.unlock();
+    }
+  }
+
   @Override
   public boolean isConfigurationChangeAcceptable(
        BackendCfg configEntry,
@@ -672,14 +837,14 @@
     if (backend instanceof LocalBackend<?>)
     {
       LocalBackend<?> localBackend = (LocalBackend<?>) backend;
-      for (BackendInitializationListener listener : getBackendInitializationListeners())
+      for (LocalBackendInitializationListener listener : initializationListeners)
       {
         listener.performBackendPreInitializationProcessing(localBackend);
       }
 
       try
       {
-        DirectoryServer.registerBackend(localBackend);
+        registerLocalBackend(localBackend);
       }
       catch (Exception e)
       {
@@ -695,7 +860,7 @@
         return false;
       }
 
-      for (BackendInitializationListener listener : getBackendInitializationListeners())
+      for (LocalBackendInitializationListener listener : initializationListeners)
       {
         listener.performBackendPostInitializationProcessing(localBackend);
       }
@@ -718,7 +883,7 @@
     // See if the entry contains an attribute that specifies the backend ID.  If
     // it does not, then skip it.
     String backendID = configEntry.getBackendId();
-    if (DirectoryServer.hasBackend(backendID))
+    if (hasLocalBackend(backendID))
     {
       unacceptableReason.add(WARN_CONFIG_BACKEND_DUPLICATE_BACKEND_ID.get(backendDN, backendID));
       return false;
@@ -809,7 +974,7 @@
     // See if the entry contains an attribute that specifies the backend ID.  If
     // it does not, then skip it.
     String backendID = cfg.getBackendId();
-    if (DirectoryServer.hasBackend(backendID))
+    if (hasLocalBackend(backendID))
     {
       LocalizableMessage message = WARN_CONFIG_BACKEND_DUPLICATE_BACKEND_ID.get(backendDN, backendID);
       logger.warn(message);
@@ -976,7 +1141,7 @@
     if (backend instanceof LocalBackend<?>)
     {
       LocalBackend<?> localBackend = (LocalBackend<?>) backend;
-      for (BackendInitializationListener listener : getBackendInitializationListeners())
+      for (LocalBackendInitializationListener listener : initializationListeners)
       {
         listener.performBackendPreFinalizationProcessing(localBackend);
       }
@@ -984,7 +1149,7 @@
       registeredBackends.remove(backendDN);
       DirectoryServer.deregisterBackend(localBackend);
 
-      for (BackendInitializationListener listener : getBackendInitializationListeners())
+      for (LocalBackendInitializationListener listener : initializationListeners)
       {
         listener.performBackendPostFinalizationProcessing(localBackend);
       }
@@ -994,6 +1159,52 @@
     }
   }
 
+  /** Shutdown all local backends. */
+  public void shutdownLocalBackends()
+  {
+    for (LocalBackend<?> backend : localBackends.values())
+    {
+      try
+      {
+        for (LocalBackendInitializationListener listener : initializationListeners)
+        {
+          listener.performBackendPreFinalizationProcessing(backend);
+        }
+
+        backend.finalizeBackend();
+
+        for (LocalBackendInitializationListener listener : initializationListeners)
+        {
+          listener.performBackendPostFinalizationProcessing(backend);
+        }
+
+        // Remove the shared lock for this backend.
+        try
+        {
+          String lockFile = LockFileManager.getBackendLockFileName(backend);
+          StringBuilder failureReason = new StringBuilder();
+          if (!LockFileManager.releaseLock(lockFile, failureReason))
+          {
+            logger.warn(WARN_SHUTDOWN_CANNOT_RELEASE_SHARED_BACKEND_LOCK, backend.getBackendID(), failureReason);
+            // FIXME -- Do we need to send an admin alert?
+          }
+        }
+        catch (Exception e2)
+        {
+          logger.traceException(e2);
+
+          logger.warn(WARN_SHUTDOWN_CANNOT_RELEASE_SHARED_BACKEND_LOCK, backend.getBackendID(),
+              stackTraceToSingleLineString(e2));
+          // FIXME -- Do we need to send an admin alert?
+        }
+      }
+      catch (Exception e)
+      {
+        logger.traceException(e);
+      }
+    }
+  }
+
   /**
    * Registry for maintaining the set of registered base DN's, associated local backends
    * and naming context information.
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java b/opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java
index 517e566..44b0d21 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java
@@ -17,7 +17,6 @@
 package org.opends.server.core;
 
 import static com.forgerock.opendj.cli.CommonArguments.*;
-
 import static org.forgerock.util.Reject.*;
 import static org.opends.messages.CoreMessages.*;
 import static org.opends.messages.ToolMessages.*;
@@ -36,7 +35,6 @@
 import java.lang.management.ManagementFactory;
 import java.net.InetAddress;
 import java.text.DecimalFormat;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
@@ -49,7 +47,6 @@
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
-import java.util.TreeMap;
 import java.util.TreeSet;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
@@ -87,7 +84,6 @@
 import org.opends.server.api.AlertHandler;
 import org.opends.server.api.AuthenticationPolicy;
 import org.opends.server.api.LocalBackend;
-import org.opends.server.api.BackendInitializationListener;
 import org.opends.server.api.BackupTaskListener;
 import org.opends.server.api.CertificateMapper;
 import org.opends.server.api.ClientConnection;
@@ -121,6 +117,7 @@
 import org.opends.server.config.JMXMBean;
 import org.opends.server.controls.PasswordPolicyErrorType;
 import org.opends.server.controls.PasswordPolicyResponseControl;
+import org.opends.server.core.BackendConfigManager.BackendAndName;
 import org.opends.server.crypto.CryptoManagerImpl;
 import org.opends.server.crypto.CryptoManagerSync;
 import org.opends.server.extensions.DiskSpaceMonitor;
@@ -135,7 +132,6 @@
 import org.opends.server.loggers.RotationPolicy;
 import org.opends.server.loggers.TextErrorLogPublisher;
 import org.opends.server.loggers.TextWriter;
-import org.opends.server.monitors.BackendMonitor;
 import org.opends.server.monitors.ConnectionHandlerMonitor;
 import org.opends.server.protocols.internal.InternalClientConnection;
 import org.opends.server.protocols.internal.InternalConnectionHandler;
@@ -417,8 +413,6 @@
   private List<ServerShutdownListener> shutdownListeners;
   /** The set of synchronization providers that have been registered with the Directory Server. */
   private List<SynchronizationProvider<SynchronizationProviderCfg>> synchronizationProviders;
-  /** The set of backend initialization listeners registered with the Directory Server. */
-  private Set<BackendInitializationListener> backendInitializationListeners;
 
   /** The set of root DNs registered with the Directory Server. */
   private Set<DN> rootDNs;
@@ -580,9 +574,6 @@
   /** The synchronization provider configuration manager for the Directory Server. */
   private SynchronizationProviderConfigManager synchronizationProviderConfigManager;
 
-  /** The set of backends registered with the server. */
-  private TreeMap<String, LocalBackend<?>> backends;
-
   /** The set of supported controls registered with the Directory Server. */
   private final TreeSet<String> supportedControls = newTreeSet(
       OID_LDAP_ASSERTION,
@@ -1061,7 +1052,7 @@
     }
 
     @Override
-    public BackendConfigManager getBackendManager()
+    public BackendConfigManager getBackendConfigManager()
     {
       return directoryServer.backendConfigManager;
     }
@@ -1215,8 +1206,6 @@
       directoryServer.defaultPasswordPolicyDN = null;
       directoryServer.defaultPasswordPolicy = null;
       directoryServer.monitorProviders = new ConcurrentHashMap<>();
-      directoryServer.backends = new TreeMap<>();
-      directoryServer.backendInitializationListeners = new CopyOnWriteArraySet<>();
       directoryServer.initializationCompletedListeners = new CopyOnWriteArrayList<>();
       directoryServer.shutdownListeners = new CopyOnWriteArrayList<>();
       directoryServer.synchronizationProviders = new CopyOnWriteArrayList<>();
@@ -1497,6 +1486,8 @@
 
       new AlertHandlerConfigManager(serverContext).initializeAlertHandlers();
 
+      backendConfigManager = new BackendConfigManager(serverContext);
+
       // Initialize the default entry cache. We have to have one before
       // <CODE>initializeRootAndAdminDataBackends()</CODE> method kicks in further down.
       entryCacheConfigManager = new EntryCacheConfigManager(serverContext);
@@ -1745,48 +1736,33 @@
   }
 
   /**
-   * Retrieves the set of backend initialization listeners that have been
-   * registered with the Directory Server.  The contents of the returned set
-   * must not be altered.
-   *
-   * @return  The set of backend initialization listeners that have been
-   *          registered with the Directory Server.
-   */
-  public static Set<BackendInitializationListener>
-                     getBackendInitializationListeners()
-  {
-    return directoryServer.backendInitializationListeners;
-  }
-
-  /**
-   * Registers the provided backend initialization listener with the Directory
+   * Registers the provided local backend initialization listener with the Directory
    * Server.
    *
-   * @param  listener  The backend initialization listener to register with the
+   * @param  listener  The local backend initialization listener to register with the
    *                   Directory Server.
    */
   public static void registerBackendInitializationListener(
-                          BackendInitializationListener listener)
+                          LocalBackendInitializationListener listener)
   {
-    directoryServer.backendInitializationListeners.add(listener);
+    directoryServer.backendConfigManager.registerBackendInitializationListener(listener);
   }
 
   /**
-   * Deregisters the provided backend initialization listener with the Directory
+   * Deregisters the provided local backend initialization listener with the Directory
    * Server.
    *
    * @param  listener  The backend initialization listener to deregister with
    *                   the Directory Server.
    */
   public static void deregisterBackendInitializationListener(
-                          BackendInitializationListener listener)
+                          LocalBackendInitializationListener listener)
   {
-    directoryServer.backendInitializationListeners.remove(listener);
+    directoryServer.backendConfigManager.deregisterBackendInitializationListener(listener);
   }
 
   private void initializeRootAndAdminDataBackends() throws ConfigException, InitializationException
   {
-    backendConfigManager = new BackendConfigManager(serverContext);
     backendConfigManager.initializeBackendConfig(Arrays.asList("adminRoot", "ads-truststore"));
 
     RootDSEBackendCfg rootDSECfg;
@@ -3391,15 +3367,15 @@
   }
 
   /**
-   * Retrieves the set of backends that have been registered with the Directory
-   * Server, as a mapping between the backend ID and the corresponding backend.
+   * Retrieves the set of local backends that have been registered with the Directory
+   * Server.
    *
-   * @return  The set of backends that have been registered with the Directory
+   * @return  The set of local backends that have been registered with the Directory
    *          Server.
    */
   public static Collection<LocalBackend<?>> getBackends()
   {
-    return new ArrayList<>(directoryServer.backends.values());
+    return directoryServer.backendConfigManager.getLocalBackends();
   }
 
   /**
@@ -3412,7 +3388,7 @@
    */
   public static LocalBackend<?> getBackend(String backendID)
   {
-    return directoryServer.backends.get(backendID);
+    return directoryServer.backendConfigManager.getLocalBackend(backendID);
   }
 
   /**
@@ -3426,7 +3402,7 @@
    */
   public static boolean hasBackend(String backendID)
   {
-    return directoryServer.backends.containsKey(backendID);
+    return directoryServer.backendConfigManager.hasLocalBackend(backendID);
   }
 
   /**
@@ -3443,38 +3419,7 @@
    */
   public static void registerBackend(LocalBackend<?> backend) throws DirectoryException
   {
-    ifNull(backend);
-
-    String backendID = backend.getBackendID();
-    ifNull(backendID);
-
-    synchronized (directoryServer)
-    {
-      TreeMap<String, LocalBackend<?>> newBackends = new TreeMap<>(directoryServer.backends);
-      if (newBackends.containsKey(backendID))
-      {
-        LocalizableMessage message = ERR_REGISTER_BACKEND_ALREADY_EXISTS.get(backendID);
-        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
-      }
-
-      newBackends.put(backendID, backend);
-      directoryServer.backends = newBackends;
-
-      for (String oid : backend.getSupportedControls())
-      {
-        registerSupportedControl(oid);
-      }
-
-      for (String oid : backend.getSupportedFeatures())
-      {
-        registerSupportedFeature(oid);
-      }
-
-      BackendMonitor monitor = new BackendMonitor(backend);
-      monitor.initializeMonitorProvider(null);
-      backend.setBackendMonitor(monitor);
-      registerMonitorProvider(monitor);
-    }
+    directoryServer.backendConfigManager.registerLocalBackend(backend);
   }
 
   /**
@@ -3487,23 +3432,7 @@
    */
   public static void deregisterBackend(LocalBackend<?> backend)
   {
-    ifNull(backend);
-
-    synchronized (directoryServer)
-    {
-      TreeMap<String, LocalBackend<?>> newBackends = new TreeMap<>(directoryServer.backends);
-      newBackends.remove(backend.getBackendID());
-
-      directoryServer.backends = newBackends;
-
-      BackendMonitor monitor = backend.getBackendMonitor();
-      if (monitor != null)
-      {
-        deregisterMonitorProvider(monitor);
-        monitor.finalizeMonitorProvider();
-        backend.setBackendMonitor(null);
-      }
-    }
+    directoryServer.backendConfigManager.deregisterLocalBackend(backend);
   }
 
   /**
@@ -3537,50 +3466,8 @@
     {
       return directoryServer.rootDSEBackend;
     }
-    return directoryServer.backendConfigManager.getLocalBackend(entryDN).getBackend();
-  }
-
-  /**
-   * Registers the provided base DN with the server.
-   *
-   * @param  baseDN     The base DN to register with the server.  It must not be
-   *                    {@code null}.
-   * @param  backend    The backend responsible for the provided base DN.  It
-   *                    must not be {@code null}.
-   * @param  isPrivate  Indicates whether the base DN should be considered a
-   *                    private base DN.  If the provided base DN is a naming
-   *                    context, then this controls whether it is public or
-   *                    private.
-   *
-   * @throws  DirectoryException  If a problem occurs while attempting to
-   *                              register the provided base DN.
-   */
-  public static void registerBaseDN(DN baseDN, LocalBackend<?> backend, boolean isPrivate)
-         throws DirectoryException
-  {
-    ifNull(baseDN, backend);
-    synchronized (directoryServer)
-    {
-      directoryServer.backendConfigManager.registerBaseDN(baseDN, backend, isPrivate);
-    }
-  }
-
-  /**
-   * Deregisters the provided base DN with the server.
-   *
-   * @param  baseDN     The base DN to deregister with the server.  It must not
-   *                    be {@code null}.
-   *
-   * @throws  DirectoryException  If a problem occurs while attempting to
-   *                              deregister the provided base DN.
-   */
-  public static void deregisterBaseDN(DN baseDN)
-         throws DirectoryException
-  {
-    ifNull(baseDN);
-    synchronized(directoryServer) {
-      directoryServer.backendConfigManager.deregisterBaseDN(baseDN);
-    }
+    BackendAndName backend = directoryServer.backendConfigManager.getLocalBackend(entryDN);
+    return backend != null ? backend.getBackend() : null;
   }
 
   /**
@@ -5020,7 +4907,7 @@
       }
     }
 
-    shutdownBackends();
+    directoryServer.backendConfigManager.shutdownLocalBackends();
 
     if (directoryServer.configurationHandler != null) {
       directoryServer.configurationHandler.finalize();
@@ -5075,47 +4962,7 @@
   /** Shutdown directory server backends. */
   public static void shutdownBackends()
   {
-    for (LocalBackend<?> backend : directoryServer.backends.values())
-    {
-      try
-      {
-        for (BackendInitializationListener listener : getBackendInitializationListeners())
-        {
-          listener.performBackendPreFinalizationProcessing(backend);
-        }
-
-        for (BackendInitializationListener listener : directoryServer.backendInitializationListeners)
-        {
-          listener.performBackendPostFinalizationProcessing(backend);
-        }
-
-        backend.finalizeBackend();
-
-        // Remove the shared lock for this backend.
-        try
-        {
-          String lockFile = LockFileManager.getBackendLockFileName(backend);
-          StringBuilder failureReason = new StringBuilder();
-          if (! LockFileManager.releaseLock(lockFile, failureReason))
-          {
-            logger.warn(WARN_SHUTDOWN_CANNOT_RELEASE_SHARED_BACKEND_LOCK, backend.getBackendID(), failureReason);
-            // FIXME -- Do we need to send an admin alert?
-          }
-        }
-        catch (Exception e2)
-        {
-          logger.traceException(e2);
-
-          logger.warn(WARN_SHUTDOWN_CANNOT_RELEASE_SHARED_BACKEND_LOCK,
-              backend.getBackendID(), stackTraceToSingleLineString(e2));
-          // FIXME -- Do we need to send an admin alert?
-        }
-      }
-      catch (Exception e)
-      {
-        logger.traceException(e);
-      }
-    }
+    directoryServer.backendConfigManager.shutdownLocalBackends();
   }
 
   /**
@@ -5143,12 +4990,6 @@
     shutdownHook             = null;
     workQueue                = null;
 
-    if (backends != null)
-    {
-      backends.clear();
-      backends = null;
-    }
-
     if (schemaHandler != null)
     {
       schemaHandler.destroy();
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/GroupManager.java b/opendj-server-legacy/src/main/java/org/opends/server/core/GroupManager.java
index dcb7024..e1281da 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/GroupManager.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/core/GroupManager.java
@@ -50,7 +50,7 @@
 import org.forgerock.opendj.server.config.server.GroupImplementationCfg;
 import org.forgerock.opendj.server.config.server.RootCfg;
 import org.opends.server.api.LocalBackend;
-import org.opends.server.api.BackendInitializationListener;
+import org.opends.server.api.LocalBackendInitializationListener;
 import org.opends.server.api.DITCacheMap;
 import org.opends.server.api.Group;
 import org.opends.server.api.plugin.InternalDirectoryServerPlugin;
@@ -95,7 +95,7 @@
        implements ConfigurationChangeListener<GroupImplementationCfg>,
                   ConfigurationAddListener<GroupImplementationCfg>,
                   ConfigurationDeleteListener<GroupImplementationCfg>,
-                  BackendInitializationListener
+                  LocalBackendInitializationListener
 {
   private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
 
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/ServerContext.java b/opendj-server-legacy/src/main/java/org/opends/server/core/ServerContext.java
index 71f55d7..cfbf971 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/ServerContext.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/core/ServerContext.java
@@ -141,5 +141,5 @@
    *
    * @return backend manager
    */
-  BackendConfigManager getBackendManager();
+  BackendConfigManager getBackendConfigManager();
 }
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/SubentryManager.java b/opendj-server-legacy/src/main/java/org/opends/server/core/SubentryManager.java
index c93b1cb..a613ac3 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/SubentryManager.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/core/SubentryManager.java
@@ -34,7 +34,7 @@
 import org.forgerock.opendj.ldap.ResultCode;
 import org.forgerock.opendj.ldap.SearchScope;
 import org.opends.server.api.LocalBackend;
-import org.opends.server.api.BackendInitializationListener;
+import org.opends.server.api.LocalBackendInitializationListener;
 import org.opends.server.api.ClientConnection;
 import org.opends.server.api.DITCacheMap;
 import org.opends.server.api.SubentryChangeListener;
@@ -86,7 +86,7 @@
  * in all cases, then we will need an alternate strategy.
  */
 public class SubentryManager extends InternalDirectoryServerPlugin
-        implements BackendInitializationListener
+        implements LocalBackendInitializationListener
 {
   private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
 
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/crypto/CryptoManagerSync.java b/opendj-server-legacy/src/main/java/org/opends/server/crypto/CryptoManagerSync.java
index 10b53b8..0807e77 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/crypto/CryptoManagerSync.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/crypto/CryptoManagerSync.java
@@ -43,7 +43,7 @@
 import org.forgerock.opendj.ldap.schema.ObjectClass;
 import org.opends.admin.ads.ADSContext;
 import org.opends.server.api.LocalBackend;
-import org.opends.server.api.BackendInitializationListener;
+import org.opends.server.api.LocalBackendInitializationListener;
 import org.opends.server.api.plugin.InternalDirectoryServerPlugin;
 import org.opends.server.api.plugin.PluginResult.PostResponse;
 import org.opends.server.config.ConfigConstants;
@@ -73,7 +73,7 @@
  * from the admin data branch to the crypto manager secret-key cache.
  */
 public class CryptoManagerSync extends InternalDirectoryServerPlugin
-     implements BackendInitializationListener
+     implements LocalBackendInitializationListener
 {
   /** The debug log tracer for this object. */
   private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/extensions/DefaultEntryCache.java b/opendj-server-legacy/src/main/java/org/opends/server/extensions/DefaultEntryCache.java
index 6d4d504..981baf4 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/extensions/DefaultEntryCache.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/extensions/DefaultEntryCache.java
@@ -26,7 +26,7 @@
 import org.forgerock.opendj.config.server.ConfigurationChangeListener;
 import org.forgerock.opendj.server.config.server.EntryCacheCfg;
 import org.opends.server.api.LocalBackend;
-import org.opends.server.api.BackendInitializationListener;
+import org.opends.server.api.LocalBackendInitializationListener;
 import org.opends.server.api.EntryCache;
 import org.opends.server.api.MonitorData;
 import org.opends.server.core.DirectoryServer;
@@ -45,7 +45,7 @@
 public class DefaultEntryCache
        extends EntryCache<EntryCacheCfg>
        implements ConfigurationChangeListener<EntryCacheCfg>,
-       BackendInitializationListener
+       LocalBackendInitializationListener
 {
   private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
 
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/replication/plugin/LDAPReplicationDomain.java b/opendj-server-legacy/src/main/java/org/opends/server/replication/plugin/LDAPReplicationDomain.java
index 5906016..33286eb 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/replication/plugin/LDAPReplicationDomain.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/replication/plugin/LDAPReplicationDomain.java
@@ -80,7 +80,7 @@
 import org.opends.server.api.AlertGenerator;
 import org.opends.server.api.LocalBackend;
 import org.opends.server.api.LocalBackend.BackendOperation;
-import org.opends.server.api.BackendInitializationListener;
+import org.opends.server.api.LocalBackendInitializationListener;
 import org.opends.server.api.DirectoryThread;
 import org.opends.server.api.MonitorData;
 import org.opends.server.api.ServerShutdownListener;
@@ -174,7 +174,7 @@
  */
 public final class LDAPReplicationDomain extends ReplicationDomain
        implements ConfigurationChangeListener<ReplicationDomainCfg>,
-                  AlertGenerator, BackendInitializationListener, ServerShutdownListener
+                  AlertGenerator, LocalBackendInitializationListener, ServerShutdownListener
 {
   /**
    * Set of attributes that will return all the user attributes and the
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java b/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
index eafd036..9a859e7 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
@@ -762,7 +762,7 @@
 
   private static BackendConfigManager getBackendManager()
   {
-    return DirectoryServer.getInstance().getServerContext().getBackendManager();
+    return DirectoryServer.getInstance().getServerContext().getBackendConfigManager();
   }
 
   /**
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/TestCaseUtils.java b/opendj-server-legacy/src/test/java/org/opends/server/TestCaseUtils.java
index ff9f1dd..a2da17d 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/TestCaseUtils.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/TestCaseUtils.java
@@ -90,6 +90,7 @@
 import org.opends.server.core.AddOperation;
 import org.opends.server.core.DeleteOperation;
 import org.opends.server.core.DirectoryServer;
+import org.opends.server.core.ServerContext;
 import org.opends.server.loggers.AccessLogPublisher;
 import org.opends.server.loggers.AccessLogger;
 import org.opends.server.loggers.DebugLogger;
@@ -812,6 +813,17 @@
     DirectoryServer.getInstance().getServerContext().getSchemaHandler().updateSchema(schemaBeforeStartingFakeServer);
   }
 
+  /** Returns the server context. */
+  public static ServerContext getServerContext()
+  {
+    ServerContext serverContext = DirectoryServer.getInstance().getServerContext();
+    if (serverContext == null)
+    {
+      throw new RuntimeException("Server context is null");
+    }
+    return serverContext;
+  }
+
   /**
    * Shut down the server. This should only be called at the end of the test
    * suite and not by any unit tests.
@@ -877,14 +889,15 @@
     // is re-enabled, a new backend object is in fact created and old reference
     // 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(backendID);
+    MemoryBackend memoryBackend = (MemoryBackend) getServerContext().getBackendConfigManager()
+        .getLocalBackend(backendID);
 
     if (memoryBackend == null)
     {
       memoryBackend = new MemoryBackend();
       memoryBackend.setBackendID(backendID);
       memoryBackend.setBaseDNs(baseDN);
+      memoryBackend.configureBackend(null, getServerContext());
       memoryBackend.openBackend();
       DirectoryServer.registerBackend(memoryBackend);
     }
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/backends/ChangelogBackendTestCase.java b/opendj-server-legacy/src/test/java/org/opends/server/backends/ChangelogBackendTestCase.java
index 587bab6..6076f6a 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/backends/ChangelogBackendTestCase.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/backends/ChangelogBackendTestCase.java
@@ -1534,6 +1534,7 @@
       memoryBackend = new MemoryBackend();
       memoryBackend.setBackendID(backendId);
       memoryBackend.setBaseDNs(baseDN);
+      memoryBackend.configureBackend(null, getServerContext());
       memoryBackend.openBackend();
       DirectoryServer.registerBackend(memoryBackend);
     }
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/core/BackendConfigManagerTestCase.java b/opendj-server-legacy/src/test/java/org/opends/server/core/BackendConfigManagerTestCase.java
index 0dae2c1..212d29e 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/core/BackendConfigManagerTestCase.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/core/BackendConfigManagerTestCase.java
@@ -88,7 +88,8 @@
   @Test(expectedExceptions = { DirectoryException.class })
   public void testDeregisterNonExistentBaseDN() throws Exception
   {
-    DirectoryServer.deregisterBaseDN(DN.valueOf("o=unregistered"));
+    DirectoryServer.getInstance().getServerContext().getBackendConfigManager()
+      .deregisterBaseDN(DN.valueOf("o=unregistered"));
   }
 
 
@@ -179,19 +180,19 @@
     Entry backendEntry = createBackendEntry(backendID, false, baseDN);
 
     processAdd(backendEntry);
-    assertNull(DirectoryServer.getBackend(backendID));
+    assertNull(getLocalBackend(backendID));
     assertFalse(DirectoryServer.isNamingContext(baseDN));
 
     // Modify the backend to enable it.
     enableBackend(backendEntry, true);
 
-    LocalBackend<?> backend = DirectoryServer.getBackend(backendID);
+    LocalBackend<?> backend = getLocalBackend(backendID);
     assertBackend(baseDN, backend);
     createEntry(baseDN, backend);
 
     // Modify the backend to disable it.
     enableBackend(backendEntry, false);
-    assertNull(DirectoryServer.getBackend(backendID));
+    assertNull(getLocalBackend(backendID));
     assertFalse(DirectoryServer.entryExists(baseDN));
     assertFalse(DirectoryServer.isNamingContext(baseDN));
 
@@ -201,6 +202,11 @@
     assertEquals(deleteOperation.getResultCode(), ResultCode.SUCCESS);
   }
 
+  private LocalBackend<?> getLocalBackend(String backendID)
+  {
+    return getServerContext().getBackendConfigManager().getLocalBackend(backendID);
+  }
+
 
 
   /**
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/types/TestDN.java b/opendj-server-legacy/src/test/java/org/opends/server/types/TestDN.java
index 8153115..a105724 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/types/TestDN.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/types/TestDN.java
@@ -40,7 +40,7 @@
   public Object[][] getNamingContexts() {
     ArrayList<DN> contextList = new ArrayList<>();
     contextList.addAll(DirectoryServer.getPublicNamingContexts().keySet());
-    contextList.addAll(DirectoryServer.getInstance().getServerContext().getBackendManager().
+    contextList.addAll(DirectoryServer.getInstance().getServerContext().getBackendConfigManager().
         getPrivateNamingContexts().keySet());
 
     Object[][] contextArray = new Object[contextList.size()][1];

--
Gitblit v1.10.0