From b68d5cc1a6352dddd67adf06b18c3690c683debe 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 responsability of backends management to BackendConfigManager
---
opendj-server-legacy/src/main/java/org/opends/server/backends/RootDSEBackend.java | 266 ++++++++++------------------------------------------
1 files changed, 52 insertions(+), 214 deletions(-)
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 d66ec65..fff1f37 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
@@ -30,6 +30,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -51,8 +52,8 @@
import org.forgerock.opendj.ldap.schema.ObjectClass;
import org.forgerock.opendj.server.config.server.RootDSEBackendCfg;
import org.forgerock.util.Reject;
-import org.forgerock.util.Utils;
import org.opends.server.api.LocalBackend;
+import org.opends.server.api.Backend;
import org.opends.server.api.ClientConnection;
import org.opends.server.core.AddOperation;
import org.opends.server.core.DeleteOperation;
@@ -126,11 +127,8 @@
private DN rootDSEDN;
/** The set of base DNs for this backend. */
private Set<DN> baseDNs;
- /**
- * The set of subordinate base DNs and their associated backends that will be
- * used for non-base searches.
- */
- private ConcurrentHashMap<DN, LocalBackend<?>> subordinateBaseDNs;
+
+ private ServerContext serverContext;
/**
* Creates a new backend with the provided information. All backend
@@ -148,6 +146,7 @@
public void configureBackend(RootDSEBackendCfg config, ServerContext serverContext) throws ConfigException
{
Reject.ifNull(config);
+ this.serverContext = serverContext;
currentConfig = config;
configEntryDN = config.dn();
}
@@ -173,43 +172,6 @@
rootDSEDN = DN.rootDN();
baseDNs = Collections.singleton(rootDSEDN);
- // Create the set of subordinate base DNs. If this is specified in the
- // configuration, then use that set. Otherwise, use the set of non-private
- // backends defined in the server.
- try
- {
- Set<DN> subDNs = currentConfig.getSubordinateBaseDN();
- if (subDNs.isEmpty())
- {
- // This is fine -- we'll just use the set of user-defined suffixes.
- subordinateBaseDNs = null;
- }
- else
- {
- subordinateBaseDNs = new ConcurrentHashMap<>();
- for (DN baseDN : subDNs)
- {
- LocalBackend<?> backend = DirectoryServer.getBackend(baseDN);
- if (backend != null)
- {
- subordinateBaseDNs.put(baseDN, backend);
- }
- else
- {
- logger.warn(WARN_ROOTDSE_NO_BACKEND_FOR_SUBORDINATE_BASE, baseDN);
- }
- }
- }
- }
- catch (Exception e)
- {
- logger.traceException(e);
-
- LocalizableMessage message = WARN_ROOTDSE_SUBORDINATE_BASE_EXCEPTION.get(
- stackTraceToSingleLineString(e));
- throw new InitializationException(message, e);
- }
-
// Determine whether all root DSE attributes should be treated as user
// attributes.
showAllAttributes = currentConfig.isShowAllAttributes();
@@ -314,21 +276,7 @@
{
return -1;
}
-
- long count = 1;
- for (Map.Entry<DN, LocalBackend<?>> entry : getSubordinateBaseDNs().entrySet())
- {
- DN subBase = entry.getKey();
- LocalBackend<?> b = entry.getValue();
- Entry subBaseEntry = b.getEntry(subBase);
- if (subBaseEntry != null)
- {
- count++;
- count += b.getNumberOfEntriesInBaseDN(subBase);
- }
- }
-
- return count;
+ return 1;
}
@Override
@@ -339,20 +287,7 @@
{
return -1;
}
-
- long count = 0;
-
- for (Map.Entry<DN, LocalBackend<?>> entry : getSubordinateBaseDNs().entrySet())
- {
- DN subBase = entry.getKey();
- Entry subBaseEntry = entry.getValue().getEntry(subBase);
- if (subBaseEntry != null)
- {
- count ++;
- }
- }
-
- return count;
+ return 0;
}
@Override
@@ -363,27 +298,6 @@
{
return getRootDSE();
}
-
- // This method should never be used to get anything other than the root DSE.
- // If we got here, then that appears to be the case, so log a message.
- logger.warn(WARN_ROOTDSE_GET_ENTRY_NONROOT, entryDN);
-
- // Go ahead and check the subordinate backends to see if we can find the
- // entry there. Note that in order to avoid potential loop conditions, this
- // will only work if the set of subordinate bases has been explicitly
- // specified.
- if (subordinateBaseDNs != null)
- {
- for (LocalBackend<?> b : subordinateBaseDNs.values())
- {
- if (b.handlesEntry(entryDN))
- {
- return b.getEntry(entryDN);
- }
- }
- }
-
- // If we've gotten here, then we couldn't find the entry so return null.
return null;
}
@@ -410,30 +324,27 @@
Map<AttributeType, List<Attribute>> dseUserAttrs = new HashMap<>();
Map<AttributeType, List<Attribute>> dseOperationalAttrs = new HashMap<>();
- Map<DN, LocalBackend<?>> publicNamingContexts = showSubordinatesNamingContexts ?
- DirectoryServer.getAllPublicNamingContexts() :
- DirectoryServer.getPublicNamingContexts();
- Attribute publicNamingContextAttr = createAttribute(ATTR_NAMING_CONTEXTS, publicNamingContexts.keySet());
+ Set<DN> publicNamingContexts = showSubordinatesNamingContexts ?
+ getAllPublicNamingContexts() : getTopLevelPublicNamingContexts();
+ Attribute publicNamingContextAttr = createAttribute(ATTR_NAMING_CONTEXTS, publicNamingContexts);
addAttribute(publicNamingContextAttr, dseUserAttrs, dseOperationalAttrs);
// Add the "ds-private-naming-contexts" attribute.
Attribute privateNamingContextAttr = createAttribute(
- ATTR_PRIVATE_NAMING_CONTEXTS, DirectoryServer.getPrivateNamingContexts().keySet());
+ ATTR_PRIVATE_NAMING_CONTEXTS, serverContext.getBackendManager().getPrivateNamingContexts().keySet());
addAttribute(privateNamingContextAttr, dseUserAttrs, dseOperationalAttrs);
// Add the "supportedControl" attribute.
- Attribute supportedControlAttr = createAttribute(ATTR_SUPPORTED_CONTROL,
- DirectoryServer.getSupportedControls());
+ Attribute supportedControlAttr = createAttribute(ATTR_SUPPORTED_CONTROL, getAllControls());
addAttribute(supportedControlAttr, dseUserAttrs, dseOperationalAttrs);
// Add the "supportedExtension" attribute.
- Attribute supportedExtensionAttr = createAttribute(
- ATTR_SUPPORTED_EXTENSION, DirectoryServer.getSupportedExtensions());
+ Attribute supportedExtensionAttr = createAttribute(ATTR_SUPPORTED_EXTENSION,
+ DirectoryServer.getSupportedExtensions());
addAttribute(supportedExtensionAttr, dseUserAttrs, dseOperationalAttrs);
// Add the "supportedFeature" attribute.
- Attribute supportedFeatureAttr = createAttribute(ATTR_SUPPORTED_FEATURE,
- DirectoryServer.getSupportedFeatures());
+ Attribute supportedFeatureAttr = createAttribute(ATTR_SUPPORTED_FEATURE, DirectoryServer.getSupportedFeatures());
addAttribute(supportedFeatureAttr, dseUserAttrs, dseOperationalAttrs);
// Add the "supportedSASLMechanisms" attribute.
@@ -503,6 +414,35 @@
return e;
}
+ private Set<String> getAllControls()
+ {
+ // 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())
+ {
+ controls.addAll(backend.getSupportedControls());
+ }
+ return controls;
+ }
+
+ private Set<DN> getAllPublicNamingContexts()
+ {
+ Set<DN> namingContexts = new HashSet<>();
+ for (Backend<?> backend : serverContext.getBackendManager().getAllBackends())
+ {
+ namingContexts.addAll(backend.getBaseDNs());
+ }
+ return namingContexts;
+ }
+
+ private Set<DN> getTopLevelPublicNamingContexts()
+ {
+ // 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());
+ }
+
private void addAll(Collection<Attribute> attributes,
Map<AttributeType, List<Attribute>> userAttrs, Map<AttributeType, List<Attribute>> operationalAttrs)
{
@@ -567,22 +507,6 @@
{
return true;
}
-
- // If it was not the null DN, then iterate through the associated
- // subordinate backends to make the determination.
- for (Map.Entry<DN, LocalBackend<?>> entry : getSubordinateBaseDNs().entrySet())
- {
- DN baseDN = entry.getKey();
- if (entryDN.isSubordinateOrEqualTo(baseDN))
- {
- LocalBackend<?> b = entry.getValue();
- if (b.entryExists(entryDN))
- {
- return true;
- }
- }
- }
-
return false;
}
@@ -639,72 +563,13 @@
break;
case SINGLE_LEVEL:
- for (Map.Entry<DN, LocalBackend<?>> entry : getSubordinateBaseDNs().entrySet())
- {
- searchOperation.checkIfCanceled(false);
-
- DN subBase = entry.getKey();
- LocalBackend<?> b = entry.getValue();
- Entry subBaseEntry = b.getEntry(subBase);
- if (subBaseEntry != null && filter.matchesEntry(subBaseEntry))
- {
- searchOperation.returnEntry(subBaseEntry, null);
- }
- }
- break;
-
case WHOLE_SUBTREE:
case SUBORDINATES:
- try
- {
- for (Map.Entry<DN, LocalBackend<?>> entry : getSubordinateBaseDNs().entrySet())
- {
- searchOperation.checkIfCanceled(false);
-
- DN subBase = entry.getKey();
- LocalBackend<?> b = entry.getValue();
-
- searchOperation.setBaseDN(subBase);
- try
- {
- b.search(searchOperation);
- }
- catch (DirectoryException de)
- {
- // If it's a "no such object" exception, then the base entry for
- // the backend doesn't exist. This isn't an error, so ignore it.
- // We'll propogate all other errors, though.
- if (de.getResultCode() != ResultCode.NO_SUCH_OBJECT)
- {
- throw de;
- }
- }
- }
- }
- catch (DirectoryException de)
- {
- logger.traceException(de);
-
- throw de;
- }
- catch (Exception e)
- {
- logger.traceException(e);
-
- LocalizableMessage message = ERR_ROOTDSE_UNEXPECTED_SEARCH_FAILURE.
- get(searchOperation.getConnectionID(),
- searchOperation.getOperationID(),
- stackTraceToSingleLineString(e));
- throw new DirectoryException(
- DirectoryServer.getServerErrorResultCode(), message,
- e);
- }
- finally
- {
- searchOperation.setBaseDN(rootDSEDN);
- }
- break;
-
+ throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
+ ERR_ROOTDSE_NOT_SUPPORTED_SCOPE.get(
+ searchOperation.getConnectionID(),
+ searchOperation.getOperationID(),
+ searchOperation.getScope()));
default:
LocalizableMessage message = ERR_ROOTDSE_INVALID_SEARCH_SCOPE.
get(searchOperation.getConnectionID(),
@@ -714,21 +579,6 @@
}
}
- /**
- * Returns the subordinate base DNs of the root DSE.
- *
- * @return the subordinate base DNs of the root DSE
- */
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public Map<DN, LocalBackend<?>> getSubordinateBaseDNs()
- {
- if (subordinateBaseDNs != null)
- {
- return subordinateBaseDNs;
- }
- return DirectoryServer.getPublicNamingContexts();
- }
-
@Override
public Set<String> getSupportedControls()
{
@@ -842,7 +692,7 @@
{
for (DN baseDN : subDNs)
{
- LocalBackend<?> backend = DirectoryServer.getBackend(baseDN);
+ LocalBackend<?> backend = DirectoryServer.getLocalBackend(baseDN);
if (backend == null)
{
unacceptableReasons.add(WARN_ROOTDSE_NO_BACKEND_FOR_SUBORDINATE_BASE.get(baseDN));
@@ -869,7 +719,7 @@
final ConfigChangeResult ccr = new ConfigChangeResult();
// Check to see if we should apply a new set of base DNs.
- ConcurrentHashMap<DN, LocalBackend<?>> subBases;
+ ConcurrentHashMap<DN, Backend<?>> subBases;
try
{
Set<DN> subDNs = cfg.getSubordinateBaseDN();
@@ -883,7 +733,7 @@
subBases = new ConcurrentHashMap<>();
for (DN baseDN : subDNs)
{
- LocalBackend<?> backend = DirectoryServer.getBackend(baseDN);
+ LocalBackend<?> backend = DirectoryServer.getLocalBackend(baseDN);
if (backend == null)
{
// This is not fine. We can't use a suffix that doesn't exist.
@@ -928,18 +778,6 @@
if (ccr.getResultCode() == ResultCode.SUCCESS)
{
- subordinateBaseDNs = subBases;
-
- if (subordinateBaseDNs == null)
- {
- ccr.addMessage(INFO_ROOTDSE_USING_SUFFIXES_AS_BASE_DNS.get());
- }
- else
- {
- String basesStr = "{ " + Utils.joinAsString(", ", subordinateBaseDNs.keySet()) + " }";
- ccr.addMessage(INFO_ROOTDSE_USING_NEW_SUBORDINATE_BASE_DNS.get(basesStr));
- }
-
if (showAllAttributes != newShowAll)
{
showAllAttributes = newShowAll;
--
Gitblit v1.10.0