opendj-server-legacy/src/main/java/org/opends/admin/ads/ADSContextHelper.java
@@ -41,8 +41,8 @@ import org.forgerock.opendj.ldif.ConnectionEntryReader; import org.forgerock.opendj.server.config.client.LDIFBackendCfgClient; import org.forgerock.opendj.server.config.client.RootCfgClient; import org.forgerock.opendj.server.config.meta.BackendCfgDefn; import org.forgerock.opendj.server.config.meta.LDIFBackendCfgDefn; import org.forgerock.opendj.server.config.meta.LocalBackendCfgDefn.WritabilityMode; import org.opends.admin.ads.ADSContext.ServerProperty; import org.opends.admin.ads.ADSContextException.ErrorType; import org.opends.admin.ads.util.ConnectionWrapper; @@ -100,7 +100,7 @@ backend.setEnabled(true); backend.setLDIFFile(ADSContext.getAdminLDIFFile()); backend.setBackendId(backendName); backend.setWritabilityMode(BackendCfgDefn.WritabilityMode.ENABLED); backend.setWritabilityMode(WritabilityMode.ENABLED); backend.setIsPrivateBackend(true); } SortedSet<DN> suffixes = backend.getBaseDN(); opendj-server-legacy/src/main/java/org/opends/quicksetup/installer/InstallerHelper.java
@@ -54,11 +54,12 @@ import org.forgerock.opendj.ldap.DN; import org.forgerock.opendj.server.config.client.BackendCfgClient; import org.forgerock.opendj.server.config.client.CryptoManagerCfgClient; import org.forgerock.opendj.server.config.client.LocalBackendCfgClient; import org.forgerock.opendj.server.config.client.ReplicationDomainCfgClient; import org.forgerock.opendj.server.config.client.ReplicationServerCfgClient; import org.forgerock.opendj.server.config.client.ReplicationSynchronizationProviderCfgClient; import org.forgerock.opendj.server.config.client.RootCfgClient; import org.forgerock.opendj.server.config.meta.BackendCfgDefn; import org.forgerock.opendj.server.config.meta.LocalBackendCfgDefn.WritabilityMode; import org.forgerock.opendj.server.config.meta.ReplicationDomainCfgDefn; import org.forgerock.opendj.server.config.meta.ReplicationServerCfgDefn; import org.forgerock.opendj.server.config.meta.ReplicationSynchronizationProviderCfgDefn; @@ -341,11 +342,11 @@ try { RootCfgClient root = conn.getRootConfiguration(); BackendCfgClient backend = root.createBackend(backendType, backendName, null); LocalBackendCfgClient backend = (LocalBackendCfgClient) root.createBackend(backendType, backendName, null); backend.setEnabled(true); backend.setBaseDN(baseDNs); backend.setBackendId(backendName); backend.setWritabilityMode(BackendCfgDefn.WritabilityMode.ENABLED); backend.setWritabilityMode(WritabilityMode.ENABLED); backend.commit(); } catch (Throwable t) opendj-server-legacy/src/main/java/org/opends/server/api/Backend.java
@@ -121,25 +121,11 @@ public abstract Set<DN> getBaseDNs(); /** * Retrieves the parent backend for this backend. * Retrieves the password storage schemes defined for this backend. * * @return The parent backend for this backend, or {@code null} if * there is none. * @return the set of supported password storage schemes */ public abstract LocalBackend<?> getParentBackend(); /** * Retrieve the password storage schemes defined for this backend. */ public abstract Set<PasswordStorageScheme<?>> getPasswordStorageSchemes(); /** * Retrieves the set of subordinate backends for this backend. * * @return The set of subordinate backends for this backend, or an * empty array if none exist. */ public abstract Backend<?>[] getSubordinateBackends(); public abstract Set<PasswordStorageScheme<?>> getSupportedPasswordStorageSchemes(); /** * Retrieves the OIDs of the controls that may be supported by this @@ -219,26 +205,6 @@ } /** * Adds the provided backend to the set of subordinate backends for * this backend. * * @param subordinateBackend The backend to add to the set of * subordinate backends for this * backend. */ public abstract void addSubordinateBackend(Backend<?> subordinateBackend); /** * Removes the provided backend from the set of subordinate backends * for this backend. * * @param subordinateBackend The backend to remove from the set of * subordinate backends for this * backend. */ public abstract void removeSubordinateBackend(Backend<?> subordinateBackend); /** * Specifies the unique identifier for this backend. * * @param backendID The unique identifier for this backend. @@ -258,11 +224,4 @@ this.backendMonitor = backendMonitor; } /** * Specifies the parent backend for this backend. * * @param parentBackend The parent backend for this backend. */ public abstract void setParentBackend(Backend<?> parentBackend); } opendj-server-legacy/src/main/java/org/opends/server/api/BackendInitializationListener.java
@@ -12,7 +12,7 @@ * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2008 Sun Microsystems, Inc. * Portions Copyright 2015 ForgeRock AS. * Portions Copyright 2015-2016 ForgeRock AS. */ package org.opends.server.api; opendj-server-legacy/src/main/java/org/opends/server/api/LocalBackend.java
@@ -95,6 +95,15 @@ /** The set of persistent searches registered with this backend. */ private final ConcurrentLinkedQueue<PersistentSearch> persistentSearches = new ConcurrentLinkedQueue<>(); /** * 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) @@ -712,7 +721,8 @@ return persistentSearches; } public Set<PasswordStorageScheme<?>> getPasswordStorageSchemes() { @Override public Set<PasswordStorageScheme<?>> getSupportedPasswordStorageSchemes() { return new HashSet<PasswordStorageScheme<?>>(DirectoryServer.getPasswordStorageSchemes()); } @@ -725,25 +735,47 @@ */ public abstract long getEntryCount(); @Override /** * Retrieves the parent backend for this backend. * * @return The parent backend for this backend, or {@code null} if * there is none. */ public final LocalBackend<?> getParentBackend() { return parentBackend; } @Override /** * Specifies the parent backend for this backend. * * @param parentBackend The parent backend for this backend. */ public final synchronized void setParentBackend(Backend<?> parentBackend) { this.parentBackend = (LocalBackend<?>) parentBackend; } @Override /** * Retrieves the set of subordinate backends for this backend. * * @return The set of subordinate backends for this backend, or an * empty array if none exist. */ public final LocalBackend<?>[] getSubordinateBackends() { return subordinateBackends; } @Override /** * Adds the provided backend to the set of subordinate backends for * this backend. * * @param subordinateBackend The backend to add to the set of * subordinate backends for this * backend. */ public final synchronized void addSubordinateBackend(Backend<?> subordinateBackend) { LinkedHashSet<LocalBackend<?>> backendSet = new LinkedHashSet<>(); @@ -755,7 +787,14 @@ } } @Override /** * Removes the provided backend from the set of subordinate backends * for this backend. * * @param subordinateBackend The backend to remove from the set of * subordinate backends for this * backend. */ public final synchronized void removeSubordinateBackend(Backend<?> subordinateBackend) { ArrayList<LocalBackend<?>> backendList = new ArrayList<>(subordinateBackends.length); opendj-server-legacy/src/main/java/org/opends/server/backends/ChangelogBackend.java
@@ -241,7 +241,7 @@ @Deprecated public static ChangelogBackend getInstance() { return (ChangelogBackend) DirectoryServer.getBackend(CHANGELOG_BASE_DN); return (ChangelogBackend) DirectoryServer.getLocalBackend(CHANGELOG_BASE_DN); } @Override opendj-server-legacy/src/main/java/org/opends/server/backends/ConfigurationBackend.java
@@ -40,8 +40,9 @@ import org.forgerock.opendj.ldap.DN; import org.forgerock.opendj.ldap.ResultCode; import org.forgerock.opendj.ldap.schema.AttributeType; import org.forgerock.opendj.server.config.meta.BackendCfgDefn.WritabilityMode; import org.forgerock.opendj.server.config.meta.LocalBackendCfgDefn.WritabilityMode; import org.forgerock.opendj.server.config.server.BackendCfg; import org.forgerock.opendj.server.config.server.LocalBackendCfg; import org.opends.server.api.LocalBackend; import org.opends.server.api.Backupable; import org.opends.server.api.ClientConnection; @@ -77,7 +78,7 @@ * needed for this specific backend, but this class is required to behave like other backends * during initialization. */ public final class ConfigurationBackendCfg implements BackendCfg public final class ConfigurationBackendCfg implements LocalBackendCfg { private ConfigurationBackendCfg() { @@ -91,7 +92,7 @@ } @Override public Class<? extends BackendCfg> configurationClass() public Class<? extends LocalBackendCfg> configurationClass() { return this.getClass(); } @@ -127,15 +128,31 @@ } @Override public void addChangeListener(ConfigurationChangeListener<BackendCfg> listener) public void addChangeListener(ConfigurationChangeListener<BackendCfg> arg0) { // no-op } @Override public void removeChangeListener(ConfigurationChangeListener<BackendCfg> listener) public void removeChangeListener(ConfigurationChangeListener<BackendCfg> arg0) { // no-op } @Override public void addLocalChangeListener(ConfigurationChangeListener<LocalBackendCfg> arg0) { // no-op } @Override public void removeLocalChangeListener(ConfigurationChangeListener<LocalBackendCfg> arg0) { // no-op } } 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; opendj-server-legacy/src/main/java/org/opends/server/core/BackendConfigManager.java
@@ -17,15 +17,23 @@ package org.opends.server.core; import static org.forgerock.opendj.ldap.ResultCode.*; 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; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; import org.forgerock.i18n.LocalizableMessage; @@ -37,10 +45,12 @@ import org.forgerock.opendj.config.server.ConfigurationDeleteListener; import org.forgerock.opendj.ldap.DN; import org.forgerock.opendj.ldap.ResultCode; import org.forgerock.opendj.server.config.meta.BackendCfgDefn; import org.forgerock.opendj.server.config.meta.LocalBackendCfgDefn; import org.forgerock.opendj.server.config.server.BackendCfg; import org.forgerock.opendj.server.config.server.LocalBackendCfg; 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.backends.ConfigurationBackend; import org.opends.server.config.ConfigConstants; @@ -50,11 +60,10 @@ import org.opends.server.types.WritabilityMode; /** * This class defines a utility that will be used to manage the configuration * for the set of backends defined in the Directory Server. It will perform * the necessary initialization of those backends when the server is first * started, and then will manage any changes to them while the server is * running. * Responsible for managing the configuration of backends defined in the Directory Server. * <p> * It will perform the necessary initialization of those backends when the server is first * started, and then will manage any changes to them while the server is running. */ public class BackendConfigManager implements ConfigurationChangeListener<BackendCfg>, @@ -64,8 +73,9 @@ private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); /** The mapping between configuration entry DNs and their corresponding backend implementations. */ private final ConcurrentHashMap<DN, LocalBackend<? extends BackendCfg>> registeredBackends = new ConcurrentHashMap<>(); private final ConcurrentHashMap<DN, Backend<? extends BackendCfg>> registeredBackends = new ConcurrentHashMap<>(); private final ServerContext serverContext; private final BaseDnRegistry localBackendsRegistry; /** * Creates a new instance of this backend config manager. @@ -76,6 +86,7 @@ public BackendConfigManager(ServerContext serverContext) { this.serverContext = serverContext; this.localBackendsRegistry = new BaseDnRegistry(); } /** @@ -201,7 +212,7 @@ initializeBackend(configBackend, configBackend.getBackendCfg()); } private void initializeBackend(LocalBackend<? extends BackendCfg> backend, BackendCfg backendCfg) private void initializeBackend(Backend<? extends BackendCfg> backend, BackendCfg backendCfg) { ConfigChangeResult ccr = new ConfigChangeResult(); initializeBackend(backend, backendCfg, ccr); @@ -211,10 +222,11 @@ } } private void initializeBackend(LocalBackend<? extends BackendCfg> backend, BackendCfg backendCfg, ConfigChangeResult ccr) private void initializeBackend(Backend<? extends BackendCfg> backend, BackendCfg backendCfg, ConfigChangeResult ccr) { backend.setBackendID(backendCfg.getBackendId()); backend.setWritabilityMode(toWritabilityMode(backendCfg.getWritabilityMode())); setLocalBackendWritabilityMode(backend, backendCfg); if (acquireSharedLock(backend, backendCfg.getBackendId(), ccr) && configureAndOpenBackend(backend, backendCfg, ccr)) { @@ -222,11 +234,18 @@ } } private void setLocalBackendWritabilityMode(Backend<?> backend, BackendCfg backendCfg) { LocalBackend<?> localBackend = asLocalBackend(backend); LocalBackendCfg localCfg = (LocalBackendCfg) backendCfg; localBackend.setWritabilityMode(toWritabilityMode(localCfg.getWritabilityMode())); } /** * Acquire a shared lock on this backend. This will prevent operations like LDIF import or restore * from occurring while the backend is active. */ private boolean acquireSharedLock(LocalBackend<?> backend, String backendID, final ConfigChangeResult ccr) private boolean acquireSharedLock(Backend<?> backend, String backendID, final ConfigChangeResult ccr) { try { @@ -259,7 +278,7 @@ ccr.addMessage(message); } private void releaseSharedLock(LocalBackend<?> backend, String backendID) private void releaseSharedLock(Backend<?> backend, String backendID) { try { @@ -280,6 +299,158 @@ } } /** * Returns the collection of all backends. * * @return all backends */ public Collection<Backend<?>> getAllBackends() { return new ArrayList<Backend<?>>(registeredBackends.values()); } /** * Retrieves the local backend with the specified base DN. * * @param baseDN The DN that is registered as one of the base DNs for the * backend to retrieve. * * @return The local backend with the specified base DN, or {@code null} if there * is no local backend registered with the specified base DN. */ public LocalBackend<?> getLocalBackendWithBaseDN(DN baseDN) { return localBackendsRegistry.getBackendWithBaseDN(baseDN); } /** * Retrieves the local backend and the corresponding baseDN that should be used to handle operations * on the specified entry. * * @param entryDN * The DN of the entry for which to retrieve the corresponding backend. * @return The local backend with its matching base DN or {@code null} if no appropriate backend * is registered with the server. */ public BackendAndName getLocalBackend(DN entryDN) { return localBackendsRegistry.getBackendAndName(entryDN); } /** * Retrieves the set of subordinate backends that of the backend that corresponds to provided base DN. * * @param baseDN * The base DN for which to retrieve the subordinates backends. * @return The set of subordinates backends (and associated base DN), which is never {@code null} */ public Set<BackendAndName> getSubordinateBackends(DN baseDN) { final Set<BackendAndName> subs = new HashSet<>(); LocalBackend<?> backend = getLocalBackendWithBaseDN(baseDN); if (backend == null) { return subs; } for (LocalBackend<?> subordinate : backend.getSubordinateBackends()) { for (DN subordinateDN : subordinate.getBaseDNs()) { if (subordinateDN.isSubordinateOrEqualTo(baseDN)) { subs.add(new BackendAndName(subordinate, subordinateDN)); } } } return subs; } /** * Gets the mapping of registered public naming contexts, not including * sub-suffixes, to their associated backend. * * @return mapping from naming context to backend */ public Map<DN, LocalBackend<?>> getPublicNamingContexts() { return localBackendsRegistry.getPublicNamingContextsMap(); } /** * Gets the mapping of registered public naming contexts, including sub-suffixes, * to their associated backend. * * @return mapping from naming context to backend */ public Map<DN, LocalBackend<?>> getAllPublicNamingContexts() { return localBackendsRegistry.getAllPublicNamingContextsMap(); } /** * Gets the mapping of registered private naming contexts to their * associated backend. * * @return mapping from naming context to backend */ public Map<DN, LocalBackend<?>> getPrivateNamingContexts() { return localBackendsRegistry.getPrivateNamingContextsMap(); } /** * Indicates whether the specified DN is contained in the backends as * a naming contexts. * * @param dn The DN for which to make the determination. * * @return {@code true} if the specified DN is a naming context in one * backend, or {@code false} if it is not. */ public boolean containsNamingContext(DN dn) { return localBackendsRegistry.containsNamingContext(dn); } /** * Registers the provided base DN. * * @param baseDN * The base DN to register. 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 void registerBaseDN(DN baseDN, LocalBackend<?> backend, boolean isPrivate) throws DirectoryException { List<LocalizableMessage> warnings = localBackendsRegistry.registerBaseDN(baseDN, backend, isPrivate); for (LocalizableMessage warning : warnings) { logger.error(warning); } } /** * Deregisters the provided base DN. * * @param baseDN * The base DN to deregister. It must not be {@code null}. * @throws DirectoryException * If a problem occurs while attempting to deregister the provided base DN. */ public void deregisterBaseDN(DN baseDN) throws DirectoryException { List<LocalizableMessage> warnings = localBackendsRegistry.deregisterBaseDN(baseDN); for (LocalizableMessage error : warnings) { logger.error(error); } } @Override public boolean isConfigurationChangeAcceptable( BackendCfg configEntry, @@ -287,12 +458,11 @@ { DN backendDN = configEntry.dn(); Set<DN> baseDNs = configEntry.getBaseDN(); // See if the backend is registered with the server. If it is, then // see what's changed and whether those changes are acceptable. LocalBackend<?> backend = registeredBackends.get(backendDN); Backend<?> backend = registeredBackends.get(backendDN); if (backend != null) { LinkedHashSet<DN> removedDNs = new LinkedHashSet<>(backend.getBaseDNs()); @@ -307,36 +477,39 @@ } } // Copy the directory server's base DN registry and make the // requested changes to see if it complains. BaseDnRegistry reg = DirectoryServer.copyBaseDnRegistry(); for (DN dn : removedDNs) if (backend instanceof LocalBackend<?>) { try // Copy the registry and make the requested changes to see if it complains. LocalBackend<?> localBackend = (LocalBackend<?>) backend; BaseDnRegistry registry = localBackendsRegistry.copy(); for (DN dn : removedDNs) { reg.deregisterBaseDN(dn); } catch (DirectoryException de) { logger.traceException(de); try { registry.deregisterBaseDN(dn); } catch (DirectoryException de) { logger.traceException(de); unacceptableReason.add(de.getMessageObject()); return false; unacceptableReason.add(de.getMessageObject()); return false; } } } for (DN dn : addedDNs) { try for (DN dn : addedDNs) { reg.registerBaseDN(dn, backend, false); } catch (DirectoryException de) { logger.traceException(de); try { registry.registerBaseDN(dn, localBackend, false); } catch (DirectoryException de) { logger.traceException(de); unacceptableReason.add(de.getMessageObject()); return false; unacceptableReason.add(de.getMessageObject()); return false; } } } } @@ -356,7 +529,7 @@ return false; } LocalBackend<BackendCfg> b = backendClass.newInstance(); Backend<BackendCfg> b = backendClass.newInstance(); if (! b.isConfigurationAcceptable(configEntry, unacceptableReason, serverContext)) { return false; @@ -381,7 +554,7 @@ public ConfigChangeResult applyConfigurationChange(BackendCfg cfg) { DN backendDN = cfg.dn(); LocalBackend<? extends BackendCfg> backend = registeredBackends.get(backendDN); Backend<? extends BackendCfg> backend = registeredBackends.get(backendDN); final ConfigChangeResult ccr = new ConfigChangeResult(); // See if the entry contains an attribute that indicates whether the @@ -488,43 +661,49 @@ } else if (ccr.getResultCode() == ResultCode.SUCCESS && backend != null) { backend.setWritabilityMode(toWritabilityMode(cfg.getWritabilityMode())); setLocalBackendWritabilityMode(backend, cfg); } return ccr; } private boolean registerBackend(LocalBackend<? extends BackendCfg> backend, BackendCfg backendCfg, ConfigChangeResult ccr) private boolean registerBackend(Backend<? extends BackendCfg> backend, BackendCfg backendCfg, ConfigChangeResult ccr) { for (BackendInitializationListener listener : getBackendInitializationListeners()) if (backend instanceof LocalBackend<?>) { listener.performBackendPreInitializationProcessing(backend); LocalBackend<?> localBackend = (LocalBackend<?>) backend; for (BackendInitializationListener listener : getBackendInitializationListeners()) { listener.performBackendPreInitializationProcessing(localBackend); } try { DirectoryServer.registerBackend(localBackend); } catch (Exception e) { logger.traceException(e); LocalizableMessage message = WARN_CONFIG_BACKEND_CANNOT_REGISTER_BACKEND.get(backendCfg.getBackendId(), getExceptionMessage(e)); logger.error(message); // FIXME -- Do we need to send an admin alert? ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(message); return false; } for (BackendInitializationListener listener : getBackendInitializationListeners()) { listener.performBackendPostInitializationProcessing(localBackend); } registeredBackends.put(backendCfg.dn(), backend); return true; } try { DirectoryServer.registerBackend(backend); } catch (Exception e) { logger.traceException(e); LocalizableMessage message = WARN_CONFIG_BACKEND_CANNOT_REGISTER_BACKEND.get(backendCfg.getBackendId(), getExceptionMessage(e)); logger.error(message); // FIXME -- Do we need to send an admin alert? ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(message); return false; } for (BackendInitializationListener listener : getBackendInitializationListeners()) { listener.performBackendPostInitializationProcessing(backend); } registeredBackends.put(backendCfg.dn(), backend); // TODO: manage proxy registration here return true; } @@ -576,7 +755,7 @@ // Make sure that all of the base DNs are acceptable for use in the server. BaseDnRegistry reg = DirectoryServer.copyBaseDnRegistry(); BaseDnRegistry registry = localBackendsRegistry.copy(); for (DN baseDN : baseDNs) { if (baseDN.isRootDN()) @@ -586,7 +765,7 @@ } try { reg.registerBaseDN(baseDN, backend, false); registry.registerBaseDN(baseDN, backend, false); } catch (DirectoryException de) { @@ -665,7 +844,7 @@ return ccr; } private boolean configureAndOpenBackend(LocalBackend<?> backend, BackendCfg cfg, ConfigChangeResult ccr) private boolean configureAndOpenBackend(Backend<?> backend, BackendCfg cfg, ConfigChangeResult ccr) { try { @@ -686,7 +865,7 @@ } @SuppressWarnings({ "unchecked", "rawtypes" }) private void configureAndOpenBackend(LocalBackend backend, BackendCfg cfg) throws ConfigException, InitializationException private void configureAndOpenBackend(Backend backend, BackendCfg cfg) throws ConfigException, InitializationException { backend.configureBackend(cfg, serverContext); backend.openBackend(); @@ -698,7 +877,7 @@ return (Class<LocalBackend<BackendCfg>>) DirectoryServer.loadClass(className); } private WritabilityMode toWritabilityMode(BackendCfgDefn.WritabilityMode writabilityMode) private WritabilityMode toWritabilityMode(LocalBackendCfgDefn.WritabilityMode writabilityMode) { switch (writabilityMode) { @@ -725,20 +904,23 @@ // provided DN. If not, then we don't care if the entry is deleted. If we // do know about it, then that means that it is enabled and we will not // allow removing a backend that is enabled. LocalBackend<?> backend = registeredBackends.get(backendDN); Backend<?> backend = registeredBackends.get(backendDN); if (backend == null) { return true; } // See if the backend has any subordinate backends. If so, then it is not // acceptable to remove it. Otherwise, it should be fine. LocalBackend<?>[] subBackends = backend.getSubordinateBackends(); if (subBackends != null && subBackends.length != 0) // TODO: what about non local backend ? if (backend instanceof LocalBackend) { unacceptableReason.add(NOTE_CONFIG_BACKEND_CANNOT_REMOVE_BACKEND_WITH_SUBORDINATES.get(backendDN)); return false; // See if the backend has any subordinate backends. If so, then it is not // acceptable to remove it. Otherwise, it should be fine. LocalBackend<?>[] subBackends = ((LocalBackend<?>) backend).getSubordinateBackends(); if (subBackends != null && subBackends.length != 0) { unacceptableReason.add(NOTE_CONFIG_BACKEND_CANNOT_REMOVE_BACKEND_WITH_SUBORDINATES.get(backendDN)); return false; } } return true; } @@ -751,20 +933,24 @@ // See if this backend config manager has a backend registered with the // provided DN. If not, then we don't care if the entry is deleted. LocalBackend<?> backend = registeredBackends.get(backendDN); Backend<?> backend = registeredBackends.get(backendDN); if (backend == null) { return ccr; } // See if the backend has any subordinate backends. If so, then it is not // acceptable to remove it. Otherwise, it should be fine. LocalBackend<?>[] subBackends = backend.getSubordinateBackends(); if (subBackends != null && subBackends.length > 0) // TODO: what about non local backend ? if (backend instanceof LocalBackend) { ccr.setResultCode(UNWILLING_TO_PERFORM); ccr.addMessage(NOTE_CONFIG_BACKEND_CANNOT_REMOVE_BACKEND_WITH_SUBORDINATES.get(backendDN)); return ccr; // See if the backend has any subordinate backends. If so, then it is not // acceptable to remove it. Otherwise, it should be fine. LocalBackend<?>[] subBackends = ((LocalBackend<?>) backend).getSubordinateBackends(); if (subBackends != null && subBackends.length > 0) { ccr.setResultCode(UNWILLING_TO_PERFORM); ccr.addMessage(NOTE_CONFIG_BACKEND_CANNOT_REMOVE_BACKEND_WITH_SUBORDINATES.get(backendDN)); return ccr; } } deregisterBackend(backendDN, backend); @@ -785,19 +971,546 @@ return ccr; } private void deregisterBackend(DN backendDN, LocalBackend<?> backend) private void deregisterBackend(DN backendDN, Backend<?> backend) { for (BackendInitializationListener listener : getBackendInitializationListeners()) if (backend instanceof LocalBackend<?>) { listener.performBackendPreFinalizationProcessing(backend); LocalBackend<?> localBackend = (LocalBackend<?>) backend; for (BackendInitializationListener listener : getBackendInitializationListeners()) { listener.performBackendPreFinalizationProcessing(localBackend); } registeredBackends.remove(backendDN); DirectoryServer.deregisterBackend(localBackend); for (BackendInitializationListener listener : getBackendInitializationListeners()) { listener.performBackendPostFinalizationProcessing(localBackend); } } else { // TODO: manage proxy deregistering here } } /** * Registry for maintaining the set of registered base DN's, associated local backends * and naming context information. */ static private class BaseDnRegistry { /** The set of base DNs registered with the server. */ private final TreeMap<DN, LocalBackend<?>> baseDNs = new TreeMap<>(); /** The set of private naming contexts registered with the server. */ private final TreeMap<DN, LocalBackend<?>> privateNamingContexts = new TreeMap<>(); /** The set of public naming contexts registered with the server. */ private final TreeMap<DN, LocalBackend<?>> publicNamingContexts = new TreeMap<>(); /** The set of public naming contexts, including sub-suffixes, registered with the server. */ private final TreeMap<DN, LocalBackend<?>> allPublicNamingContexts = new TreeMap<>(); /** * Indicates whether this base DN registry is in test mode. * A registry instance that is in test mode will not modify backend * objects referred to in the above maps. */ private boolean testOnly; /** * Registers a base DN with this registry. * * @param baseDN to register * @param backend with which the base DN is associated * @param isPrivate indicates whether this base DN is private * @return list of error messages generated by registering the base DN * that should be logged if the changes to this registry are * committed to the server * @throws DirectoryException if the base DN cannot be registered */ List<LocalizableMessage> registerBaseDN(DN baseDN, LocalBackend<?> backend, boolean isPrivate) throws DirectoryException { // Check to see if the base DN is already registered with the server. LocalBackend<?> existingBackend = baseDNs.get(baseDN); if (existingBackend != null) { LocalizableMessage message = ERR_REGISTER_BASEDN_ALREADY_EXISTS. get(baseDN, backend.getBackendID(), existingBackend.getBackendID()); throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message); } // Check to see if the backend is already registered with the server for // any other base DN(s). The new base DN must not have any hierarchical // relationship with any other base Dns for the same backend. LinkedList<DN> otherBaseDNs = new LinkedList<>(); for (DN dn : baseDNs.keySet()) { LocalBackend<?> b = baseDNs.get(dn); if (b.equals(backend)) { otherBaseDNs.add(dn); if (baseDN.isSuperiorOrEqualTo(dn) || baseDN.isSubordinateOrEqualTo(dn)) { LocalizableMessage message = ERR_REGISTER_BASEDN_HIERARCHY_CONFLICT. get(baseDN, backend.getBackendID(), dn); throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message); } } } // Check to see if the new base DN is subordinate to any other base DN // already defined. If it is, then any other base DN(s) for the same // backend must also be subordinate to the same base DN. final LocalBackend<?> superiorBackend = getSuperiorBackend(baseDN, otherBaseDNs, backend.getBackendID()); if (superiorBackend == null && backend.getParentBackend() != null) { LocalizableMessage message = ERR_REGISTER_BASEDN_NEW_BASE_NOT_SUBORDINATE. get(baseDN, backend.getBackendID(), backend.getParentBackend().getBackendID()); throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message); } // Check to see if the new base DN should be the superior base DN for any // other base DN(s) already defined. LinkedList<LocalBackend<?>> subordinateBackends = new LinkedList<>(); LinkedList<DN> subordinateBaseDNs = new LinkedList<>(); for (DN dn : baseDNs.keySet()) { LocalBackend<?> b = baseDNs.get(dn); DN parentDN = dn.parent(); while (parentDN != null) { if (parentDN.equals(baseDN)) { subordinateBaseDNs.add(dn); subordinateBackends.add(b); break; } else if (baseDNs.containsKey(parentDN)) { break; } parentDN = parentDN.parent(); } } // If we've gotten here, then the new base DN is acceptable. If we should // actually apply the changes then do so now. final List<LocalizableMessage> errors = new LinkedList<>(); // Check to see if any of the registered backends already contain an // entry with the DN specified as the base DN. This could happen if // we're creating a new subordinate backend in an existing directory // (e.g., moving the "ou=People,dc=example,dc=com" branch to its own // backend when that data already exists under the "dc=example,dc=com" // backend). This condition shouldn't prevent the new base DN from // being registered, but it's definitely important enough that we let // the administrator know about it and remind them that the existing // backend will need to be reinitialized. if (superiorBackend != null) { if (superiorBackend.entryExists(baseDN)) { errors.add(WARN_REGISTER_BASEDN_ENTRIES_IN_MULTIPLE_BACKENDS. get(superiorBackend.getBackendID(), baseDN, backend.getBackendID())); } } baseDNs.put(baseDN, backend); if (superiorBackend == null) { if (!testOnly) { backend.setPrivateBackend(isPrivate); } if (isPrivate) { privateNamingContexts.put(baseDN, backend); } else { publicNamingContexts.put(baseDN, backend); } } else if (otherBaseDNs.isEmpty() && !testOnly) { backend.setParentBackend(superiorBackend); superiorBackend.addSubordinateBackend(backend); } if (!testOnly) { for (LocalBackend<?> b : subordinateBackends) { LocalBackend<?> oldParentBackend = b.getParentBackend(); if (oldParentBackend != null) { oldParentBackend.removeSubordinateBackend(b); } b.setParentBackend(backend); backend.addSubordinateBackend(b); } } if (!isPrivate) { allPublicNamingContexts.put(baseDN, backend); } for (DN dn : subordinateBaseDNs) { publicNamingContexts.remove(dn); privateNamingContexts.remove(dn); } return errors; } registeredBackends.remove(backendDN); DirectoryServer.deregisterBackend(backend); for (BackendInitializationListener listener : getBackendInitializationListeners()) LocalBackend<?> getBackendWithBaseDN(DN entryDN) { listener.performBackendPostFinalizationProcessing(backend); return baseDNs.get(entryDN); } BackendAndName getBackendAndName(final DN entryDN) { /* * Try to minimize the number of lookups in the map to find the backend containing the entry. * 1) If the DN contains many RDNs it is faster to iterate through the list of registered backends, * 2) Otherwise iterating through the parents requires less lookups. It also avoids some attacks * where we would spend time going through the list of all parents to finally decide the * baseDN is absent. */ if (entryDN.size() <= baseDNs.size()) { DN matchedDN = entryDN; while (!matchedDN.isRootDN()) { final LocalBackend<?> backend = baseDNs.get(matchedDN); if (backend != null) { return new BackendAndName(backend, matchedDN); } matchedDN = matchedDN.parent(); } return null; } else { LocalBackend<?> backend = null; DN matchedDN = null; int currentSize = 0; for (DN backendDN : baseDNs.keySet()) { if (entryDN.isSubordinateOrEqualTo(backendDN) && backendDN.size() > currentSize) { backend = baseDNs.get(backendDN); matchedDN = backendDN; currentSize = backendDN.size(); } } return new BackendAndName(backend, matchedDN); } } private LocalBackend<?> getSuperiorBackend(DN baseDN, LinkedList<DN> otherBaseDNs, String backendID) throws DirectoryException { LocalBackend<?> superiorBackend = null; DN parentDN = baseDN.parent(); while (parentDN != null) { if (baseDNs.containsKey(parentDN)) { superiorBackend = baseDNs.get(parentDN); for (DN dn : otherBaseDNs) { if (!dn.isSubordinateOrEqualTo(parentDN)) { LocalizableMessage msg = ERR_REGISTER_BASEDN_DIFFERENT_PARENT_BASES.get(baseDN, backendID, dn); throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, msg); } } break; } parentDN = parentDN.parent(); } return superiorBackend; } /** * Deregisters a base DN with this registry. * * @param baseDN to deregister * @return list of error messages generated by deregistering the base DN * that should be logged if the changes to this registry are * committed to the server * @throws DirectoryException if the base DN could not be deregistered */ List<LocalizableMessage> deregisterBaseDN(DN baseDN) throws DirectoryException { ifNull(baseDN); // Make sure that the Directory Server actually contains a backend with // the specified base DN. LocalBackend<?> backend = baseDNs.get(baseDN); if (backend == null) { LocalizableMessage message = ERR_DEREGISTER_BASEDN_NOT_REGISTERED.get(baseDN); throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message); } // Check to see if the backend has a parent backend, and whether it has // any subordinates with base DNs that are below the base DN to remove. LocalBackend<?> superiorBackend = backend.getParentBackend(); LinkedList<LocalBackend<?>> subordinateBackends = new LinkedList<>(); if (backend.getSubordinateBackends() != null) { for (LocalBackend<?> b : backend.getSubordinateBackends()) { for (DN dn : b.getBaseDNs()) { if (dn.isSubordinateOrEqualTo(baseDN)) { subordinateBackends.add(b); break; } } } } // See if there are any other base DNs registered within the same backend. LinkedList<DN> otherBaseDNs = new LinkedList<>(); for (DN dn : baseDNs.keySet()) { if (dn.equals(baseDN)) { continue; } LocalBackend<?> b = baseDNs.get(dn); if (backend.equals(b)) { otherBaseDNs.add(dn); } } // If we've gotten here, then it's OK to make the changes. // Get rid of the references to this base DN in the mapping tree // information. baseDNs.remove(baseDN); publicNamingContexts.remove(baseDN); allPublicNamingContexts.remove(baseDN); privateNamingContexts.remove(baseDN); final LinkedList<LocalizableMessage> errors = new LinkedList<>(); if (superiorBackend == null) { // If there were any subordinate backends, then all of their base DNs // will now be promoted to naming contexts. for (LocalBackend<?> b : subordinateBackends) { if (!testOnly) { b.setParentBackend(null); backend.removeSubordinateBackend(b); } for (DN dn : b.getBaseDNs()) { if (b.isPrivateBackend()) { privateNamingContexts.put(dn, b); } else { publicNamingContexts.put(dn, b); } } } } else { // If there are no other base DNs for the associated backend, then // remove this backend as a subordinate of the parent backend. if (otherBaseDNs.isEmpty() && !testOnly) { superiorBackend.removeSubordinateBackend(backend); } // If there are any subordinate backends, then they need to be made // subordinate to the parent backend. Also, we should log a warning // message indicating that there may be inconsistent search results // because some of the structural entries will be missing. if (! subordinateBackends.isEmpty()) { // Suppress this warning message on server shutdown. if (!DirectoryServer.getInstance().isShuttingDown()) { errors.add(WARN_DEREGISTER_BASEDN_MISSING_HIERARCHY.get( baseDN, backend.getBackendID())); } if (!testOnly) { for (LocalBackend<?> b : subordinateBackends) { backend.removeSubordinateBackend(b); superiorBackend.addSubordinateBackend(b); b.setParentBackend(superiorBackend); } } } } return errors; } /** Creates a default instance. */ BaseDnRegistry() { this(false); } /** * Returns a copy of this registry. * * @return copy of this registry */ BaseDnRegistry copy() { final BaseDnRegistry registry = new BaseDnRegistry(true); registry.baseDNs.putAll(baseDNs); registry.publicNamingContexts.putAll(publicNamingContexts); registry.allPublicNamingContexts.putAll(allPublicNamingContexts); registry.privateNamingContexts.putAll(privateNamingContexts); return registry; } /** * Creates a parameterized instance. * * @param testOnly indicates whether this registry will be used for testing; * when <code>true</code> this registry will not modify backends */ private BaseDnRegistry(boolean testOnly) { this.testOnly = testOnly; } /** * Gets the mapping of registered base DNs to their associated backend. * * @return mapping from base DN to backend */ Map<DN, LocalBackend<?>> getBaseDnMap() { return this.baseDNs; } /** * Gets the mapping of registered public naming contexts, not including * sub-suffixes, to their associated backend. * * @return mapping from naming context to backend */ Map<DN, LocalBackend<?>> getPublicNamingContextsMap() { return this.publicNamingContexts; } /** * Gets the mapping of registered public naming contexts, including sub-suffixes, * to their associated backend. * * @return mapping from naming context to backend */ Map<DN, LocalBackend<?>> getAllPublicNamingContextsMap() { return this.allPublicNamingContexts; } /** * Gets the mapping of registered private naming contexts to their * associated backend. * * @return mapping from naming context to backend */ Map<DN, LocalBackend<?>> getPrivateNamingContextsMap() { return this.privateNamingContexts; } /** * Indicates whether the specified DN is contained in this registry as * a naming contexts. * * @param dn The DN for which to make the determination. * * @return {@code true} if the specified DN is a naming context in this * registry, or {@code false} if it is not. */ boolean containsNamingContext(DN dn) { return privateNamingContexts.containsKey(dn) || publicNamingContexts.containsKey(dn); } /** Clear and nullify this registry's internal state. */ void clear() { baseDNs.clear(); privateNamingContexts.clear(); publicNamingContexts.clear(); allPublicNamingContexts.clear(); } } /** * Holder for a backend and a single base DN managed by the backend. * <p> * A backend can manages multiple base DNs, this class allow to keep the association for a single DN. */ public static class BackendAndName { private final LocalBackend<?> backend; private final DN baseDn; /** * Creates a new holder for base DN and the backend that manages it. * @param backend * The backend that holds the base DN * @param baseDn * A base DN of the backend */ public BackendAndName(LocalBackend<?> backend, DN baseDn) { this.backend = backend; this.baseDn = baseDn; } /** * Returns the base DN. * * @return the base DN */ public DN getBaseDn() { return baseDn; } /** * Returns the backend. * * @return the backend that holds the base DN */ public LocalBackend<?> getBackend() { return backend; } } } opendj-server-legacy/src/main/java/org/opends/server/core/BaseDnRegistry.java
File was deleted opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java
@@ -163,8 +163,6 @@ import org.opends.server.util.RuntimeInformation; import org.opends.server.util.SetupUtils; import org.opends.server.util.TimeThread; import org.opends.server.workflowelement.localbackend.LocalBackendWorkflowElement; import com.forgerock.opendj.cli.ArgumentConstants; import com.forgerock.opendj.cli.ArgumentException; import com.forgerock.opendj.cli.ArgumentParser; @@ -582,9 +580,6 @@ /** The synchronization provider configuration manager for the Directory Server. */ private SynchronizationProviderConfigManager synchronizationProviderConfigManager; /** Registry for base DN and naming context information. */ private BaseDnRegistry baseDnRegistry; /** The set of backends registered with the server. */ private TreeMap<String, LocalBackend<?>> backends; @@ -1064,6 +1059,12 @@ { return directoryServer.cronExecutorService; } @Override public BackendConfigManager getBackendManager() { return directoryServer.backendConfigManager; } } /** @@ -1216,7 +1217,6 @@ directoryServer.monitorProviders = new ConcurrentHashMap<>(); directoryServer.backends = new TreeMap<>(); directoryServer.backendInitializationListeners = new CopyOnWriteArraySet<>(); directoryServer.baseDnRegistry = new BaseDnRegistry(); directoryServer.initializationCompletedListeners = new CopyOnWriteArrayList<>(); directoryServer.shutdownListeners = new CopyOnWriteArrayList<>(); directoryServer.synchronizationProviders = new CopyOnWriteArrayList<>(); @@ -1543,8 +1543,6 @@ initializeRemainingBackends(); createAndRegisterRemainingWorkflows(); // Check for and initialize user configured entry cache if any. // If not then stick with default entry cache initialized earlier. entryCacheConfigManager.initializeEntryCache(); @@ -1818,67 +1816,6 @@ } /** * Creates a set of workflows for a given backend and registers the * workflows with the default network group, the internal network group * and he admin network group. There are as many workflows * as base DNs defined in the backend. * * @param backend the backend handled by the workflow * * @throws DirectoryException If the workflow ID for the provided * workflow conflicts with the workflow * ID of an existing workflow. */ private static void createAndRegisterWorkflows(LocalBackend<?> backend) throws DirectoryException { // Create a workflow for each backend base DN and register the workflow // with the default/internal/admin network group. for (DN curBaseDN: backend.getBaseDNs()) { createWorkflow(curBaseDN, backend); } } /** * Creates one workflow for a given base DN in a backend. * * @param baseDN the base DN of the workflow to create * @param backend the backend handled by the workflow * @throws DirectoryException If the workflow ID for the provided * workflow conflicts with the workflow * ID of an existing workflow. */ private static void createWorkflow(DN baseDN, LocalBackend<?> backend) throws DirectoryException { LocalBackendWorkflowElement.createAndRegister(baseDN, backend); } /** * Creates the missing workflows, one for the config backend and one for * the rootDSE backend. * * This method should be invoked whatever may be the workflow * configuration mode because config backend and rootDSE backend * will not have any configuration section, ever. * * @throws ConfigException If there is a configuration problem with any of * the workflows. */ private void createAndRegisterRemainingWorkflows() throws ConfigException { try { createAndRegisterWorkflows(getConfigurationBackend()); createAndRegisterWorkflows(rootDSEBackend); } catch (DirectoryException de) { throw new ConfigException(de.getMessageObject()); } } /** * Initializes the Directory Server group manager. * * @throws ConfigException If there is a configuration problem with any of @@ -3559,12 +3496,6 @@ directoryServer.backends = newBackends; // Don't need anymore the local backend workflow element so we can remove it for (DN baseDN : backend.getBaseDNs()) { LocalBackendWorkflowElement.remove(baseDN); } BackendMonitor monitor = backend.getBackendMonitor(); if (monitor != null) { @@ -3576,21 +3507,21 @@ } /** * Retrieves the backend with the specified base DN. * Retrieves the local backend with the specified base DN. * * @param baseDN The DN that is registered as one of the base DNs for the * backend to retrieve. * * @return The backend with the specified base DN, or {@code null} if there * is no backend registered with the specified base DN. * @return The local backend with the specified base DN, or {@code null} if there * is no local backend registered with the specified base DN. */ public static LocalBackend<?> getBackendWithBaseDN(DN baseDN) public static LocalBackend<?> getLocalBackendWithBaseDN(DN baseDN) { return directoryServer.baseDnRegistry.getBaseDnMap().get(baseDN); return directoryServer.backendConfigManager.getLocalBackendWithBaseDN(baseDN); } /** * Retrieves the backend that should be used to handle operations on the * Retrieves the local backend that should be used to handle operations on the * specified entry. * * @param entryDN The DN of the entry for which to retrieve the @@ -3600,41 +3531,13 @@ * specified entry, or {@code null} if no appropriate backend is * registered with the server. */ public static LocalBackend<?> getBackend(DN entryDN) public static LocalBackend<?> getLocalBackend(DN entryDN) { if (entryDN.isRootDN()) { return directoryServer.rootDSEBackend; } Map<DN, LocalBackend<?>> baseDNs = directoryServer.baseDnRegistry.getBaseDnMap(); LocalBackend<?> b = baseDNs.get(entryDN); while (b == null) { entryDN = entryDN.parent(); if (entryDN == null) { return null; } b = baseDNs.get(entryDN); } return b; } /** * Obtains a copy of the server's base DN registry. The copy can be used * to test registration/deregistration of base DNs but cannot be used to * modify the backends. To modify the server's live base DN to backend * mappings use {@link #registerBaseDN(DN, LocalBackend, boolean)} and * {@link #deregisterBaseDN(DN)}. * * @return copy of the base DN registry */ public static BaseDnRegistry copyBaseDnRegistry() { return directoryServer.baseDnRegistry.copy(); return directoryServer.backendConfigManager.getLocalBackend(entryDN).getBackend(); } /** @@ -3656,29 +3559,9 @@ throws DirectoryException { ifNull(baseDN, backend); synchronized (directoryServer) { List<LocalizableMessage> warnings = directoryServer.baseDnRegistry.registerBaseDN( baseDN, backend, isPrivate); // Since we've committed the changes we need to log any issues // that this registration has caused for (LocalizableMessage warning : warnings) { logger.error(warning); } // When a new baseDN is registered with the server we have to create // a new workflow to handle the base DN. if (!baseDN.equals(DN.valueOf("cn=config"))) { // Now create a workflow for the registered baseDN and register // the workflow with the default network group, but don't register // the workflow if the backend happens to be the configuration // backend because it's too soon for the config backend. createWorkflow(baseDN, backend); } directoryServer.backendConfigManager.registerBaseDN(baseDN, backend, isPrivate); } } @@ -3695,22 +3578,8 @@ throws DirectoryException { ifNull(baseDN); synchronized(directoryServer) { List<LocalizableMessage> warnings = directoryServer.baseDnRegistry.deregisterBaseDN(baseDN); // Since we've committed the changes we need to log any issues // that this registration has caused for (LocalizableMessage error : warnings) { logger.error(error); } // Now we need to deregister the workflow that was associated with the base DN if (!baseDN.equals(DN.valueOf("cn=config"))) { LocalBackendWorkflowElement.remove(baseDN); } directoryServer.backendConfigManager.deregisterBaseDN(baseDN); } } @@ -3722,7 +3591,7 @@ */ public static Map<DN, LocalBackend<?>> getPublicNamingContexts() { return directoryServer.baseDnRegistry.getPublicNamingContextsMap(); return directoryServer.backendConfigManager.getPublicNamingContexts(); } /** @@ -3734,19 +3603,7 @@ */ public static Map<DN, LocalBackend<?>> getAllPublicNamingContexts() { return directoryServer.baseDnRegistry.getAllPublicNamingContextsMap(); } /** * Retrieves the set of private naming contexts defined in the Directory * Server, mapped from the naming context DN to the corresponding backend. * * @return The set of private naming contexts defined in the Directory * Server. */ public static Map<DN, LocalBackend<?>> getPrivateNamingContexts() { return directoryServer.baseDnRegistry.getPrivateNamingContextsMap(); return directoryServer.backendConfigManager.getAllPublicNamingContexts(); } /** @@ -3760,7 +3617,7 @@ */ public static boolean isNamingContext(DN dn) { return directoryServer.baseDnRegistry.containsNamingContext(dn); return directoryServer.backendConfigManager.containsNamingContext(dn); } /** @@ -3843,7 +3700,7 @@ { return directoryServer.rootDSEBackend.getRootDSE(); } final LocalBackend<?> backend = getBackend(entryDN); final LocalBackend<?> backend = getLocalBackend(entryDN); return backend != null ? backend.getEntry(entryDN) : null; } @@ -3870,7 +3727,7 @@ // Ask the appropriate backend if the entry exists. // If it is not appropriate for any backend, then return false. LocalBackend<?> backend = getBackend(entryDN); LocalBackend<?> backend = getLocalBackend(entryDN); return backend != null && backend.entryExists(entryDN); } @@ -5259,8 +5116,6 @@ logger.traceException(e); } } // Deregister all the local backend workflow elements that have been registered with the server. LocalBackendWorkflowElement.removeAll(); } /** @@ -5288,12 +5143,6 @@ shutdownHook = null; workQueue = null; if (baseDnRegistry != null) { baseDnRegistry.clear(); baseDnRegistry = null; } if (backends != null) { backends.clear(); opendj-server-legacy/src/main/java/org/opends/server/core/LockFileManager.java
@@ -23,7 +23,7 @@ import java.util.HashMap; import java.util.Map; import org.opends.server.api.LocalBackend; import org.opends.server.api.Backend; import org.forgerock.i18n.slf4j.LocalizedLogger; import static org.opends.messages.CoreMessages.*; @@ -436,7 +436,7 @@ * @return The filename that should be used for the lock file for the * specified backend. */ public static String getBackendLockFileName(LocalBackend backend) public static String getBackendLockFileName(Backend backend) { StringBuilder buffer = new StringBuilder(); buffer.append(getLockDirectoryPath()); opendj-server-legacy/src/main/java/org/opends/server/core/ServerContext.java
@@ -135,4 +135,11 @@ * @return the UNIX's cron-like executor service */ ScheduledExecutorService getCronExecutorService(); /** * Returns the manager of backends. * * @return backend manager */ BackendConfigManager getBackendManager(); } opendj-server-legacy/src/main/java/org/opends/server/crypto/CryptoManagerSync.java
@@ -163,7 +163,7 @@ attrAlias = getSchema().getAttributeType(ATTR_CRYPTO_KEY_ID); attrCompromisedTime = getSchema().getAttributeType(ATTR_CRYPTO_KEY_COMPROMISED_TIME); if (DirectoryServer.getBackendWithBaseDN(adminSuffixDN) != null) if (DirectoryServer.getLocalBackendWithBaseDN(adminSuffixDN) != null) { searchAdminSuffix(); } opendj-server-legacy/src/main/java/org/opends/server/extensions/ExactMatchIdentityMapper.java
@@ -111,7 +111,7 @@ { for (DN baseDN : cfgBaseDNs) { LocalBackend b = DirectoryServer.getBackend(baseDN); LocalBackend b = DirectoryServer.getLocalBackend(baseDN); if (b != null && ! b.isIndexed(t, IndexType.EQUALITY)) { throw new ConfigException(ERR_EXACTMAP_ATTR_UNINDEXED.get( @@ -274,7 +274,7 @@ { for (DN baseDN : cfgBaseDNs) { LocalBackend b = DirectoryServer.getBackend(baseDN); LocalBackend b = DirectoryServer.getLocalBackend(baseDN); if (b != null && ! b.isIndexed(t, IndexType.EQUALITY)) { unacceptableReasons.add(ERR_EXACTMAP_ATTR_UNINDEXED.get( opendj-server-legacy/src/main/java/org/opends/server/extensions/FIFOEntryCache.java
@@ -600,7 +600,7 @@ { // Determine which backend should be used for the provided base DN. If // there is none, then we don't need to do anything. LocalBackend<?> backend = DirectoryServer.getBackend(baseDN); LocalBackend<?> backend = DirectoryServer.getLocalBackend(baseDN); if (backend == null) { return; opendj-server-legacy/src/main/java/org/opends/server/extensions/FingerprintCertificateMapper.java
@@ -118,7 +118,7 @@ AttributeType t = configuration.getFingerprintAttribute(); for (DN baseDN : cfgBaseDNs) { LocalBackend<?> b = DirectoryServer.getBackend(baseDN); LocalBackend<?> b = DirectoryServer.getLocalBackend(baseDN); if (b != null && ! b.isIndexed(t, IndexType.EQUALITY)) { logger.warn(WARN_SATUACM_ATTR_UNINDEXED, configuration.dn(), @@ -317,7 +317,7 @@ AttributeType t = configuration.getFingerprintAttribute(); for (DN baseDN : cfgBaseDNs) { LocalBackend<?> b = DirectoryServer.getBackend(baseDN); LocalBackend<?> b = DirectoryServer.getLocalBackend(baseDN); if (b != null && ! b.isIndexed(t, IndexType.EQUALITY)) { LocalizableMessage message = WARN_SATUACM_ATTR_UNINDEXED.get( opendj-server-legacy/src/main/java/org/opends/server/extensions/HasSubordinatesVirtualAttributeProvider.java
@@ -60,7 +60,7 @@ @Override public Attribute getValues(Entry entry, VirtualAttributeRule rule) { LocalBackend backend = DirectoryServer.getBackend(entry.getName()); LocalBackend backend = DirectoryServer.getLocalBackend(entry.getName()); try { @@ -81,7 +81,7 @@ @Override public boolean hasValue(Entry entry, VirtualAttributeRule rule) { LocalBackend backend = DirectoryServer.getBackend(entry.getName()); LocalBackend backend = DirectoryServer.getLocalBackend(entry.getName()); try { @@ -99,7 +99,7 @@ @Override public boolean hasValue(Entry entry, VirtualAttributeRule rule, ByteString value) { LocalBackend backend = DirectoryServer.getBackend(entry.getName()); LocalBackend backend = DirectoryServer.getLocalBackend(entry.getName()); MatchingRule matchingRule = rule.getAttributeType().getEqualityMatchingRule(); opendj-server-legacy/src/main/java/org/opends/server/extensions/NumSubordinatesVirtualAttributeProvider.java
@@ -60,7 +60,7 @@ @Override public Attribute getValues(Entry entry, VirtualAttributeRule rule) { LocalBackend backend = DirectoryServer.getBackend(entry.getName()); LocalBackend backend = DirectoryServer.getLocalBackend(entry.getName()); try { @@ -81,7 +81,7 @@ @Override public boolean hasValue(Entry entry, VirtualAttributeRule rule) { LocalBackend<?> backend = DirectoryServer.getBackend(entry.getName()); LocalBackend<?> backend = DirectoryServer.getLocalBackend(entry.getName()); try { @@ -97,7 +97,7 @@ @Override public boolean hasValue(Entry entry, VirtualAttributeRule rule, ByteString value) { LocalBackend<?> backend = DirectoryServer.getBackend(entry.getName()); LocalBackend<?> backend = DirectoryServer.getLocalBackend(entry.getName()); try { long count = backend.getNumberOfChildren(entry.getName()); opendj-server-legacy/src/main/java/org/opends/server/extensions/RegularExpressionIdentityMapper.java
@@ -138,7 +138,7 @@ { for (DN baseDN : cfgBaseDNs) { LocalBackend b = DirectoryServer.getBackend(baseDN); LocalBackend b = DirectoryServer.getLocalBackend(baseDN); if (b != null && ! b.isIndexed(t, IndexType.EQUALITY)) { throw new ConfigException(ERR_REGEXMAP_ATTR_UNINDEXED.get( @@ -291,7 +291,7 @@ { for (DN baseDN : cfgBaseDNs) { LocalBackend b = DirectoryServer.getBackend(baseDN); LocalBackend b = DirectoryServer.getLocalBackend(baseDN); if (b != null && ! b.isIndexed(t, IndexType.EQUALITY)) { unacceptableReasons.add(ERR_REGEXMAP_ATTR_UNINDEXED.get( opendj-server-legacy/src/main/java/org/opends/server/extensions/SoftReferenceEntryCache.java
@@ -327,7 +327,7 @@ public void clearSubtree(DN baseDN) { // Determine the backend used to hold the specified base DN and clear it. LocalBackend<?> backend = DirectoryServer.getBackend(baseDN); LocalBackend<?> backend = DirectoryServer.getLocalBackend(baseDN); if (backend == null) { // FIXME -- Should we clear everything just to be safe? opendj-server-legacy/src/main/java/org/opends/server/extensions/SubjectAttributeToUserAttributeCertificateMapper.java
@@ -119,7 +119,7 @@ { for (AttributeType t : attributeMap.values()) { LocalBackend<?> b = DirectoryServer.getBackend(baseDN); LocalBackend<?> b = DirectoryServer.getLocalBackend(baseDN); if (b != null && ! b.isIndexed(t, IndexType.EQUALITY)) { logger.warn(WARN_SATUACM_ATTR_UNINDEXED, configuration.dn(), @@ -296,7 +296,7 @@ { for (AttributeType t : newAttributeMap.values()) { LocalBackend<?> b = DirectoryServer.getBackend(baseDN); LocalBackend<?> b = DirectoryServer.getLocalBackend(baseDN); if (b != null && !b.isIndexed(t, IndexType.EQUALITY)) { LocalizableMessage message = opendj-server-legacy/src/main/java/org/opends/server/extensions/SubjectDNToUserAttributeCertificateMapper.java
@@ -105,7 +105,7 @@ AttributeType t = configuration.getSubjectAttribute(); for (DN baseDN : cfgBaseDNs) { LocalBackend b = DirectoryServer.getBackend(baseDN); LocalBackend b = DirectoryServer.getLocalBackend(baseDN); if (b != null && ! b.isIndexed(t, IndexType.EQUALITY)) { logger.warn(WARN_SATUACM_ATTR_UNINDEXED, configuration.dn(), opendj-server-legacy/src/main/java/org/opends/server/plugins/ReferentialIntegrityPlugin.java
@@ -297,7 +297,7 @@ for (DN baseDN : cfgBaseDNs) { LocalBackend<?> b = DirectoryServer.getBackend(baseDN); LocalBackend<?> b = DirectoryServer.getLocalBackend(baseDN); if (b != null && !b.isIndexed(type, IndexType.EQUALITY)) { isAcceptable = false; opendj-server-legacy/src/main/java/org/opends/server/plugins/UniqueAttributePlugin.java
@@ -158,7 +158,7 @@ { for (DN baseDN : cfgBaseDNs) { LocalBackend<?> b = DirectoryServer.getBackend(baseDN); LocalBackend<?> b = DirectoryServer.getLocalBackend(baseDN); if (b != null && ! b.isIndexed(t, IndexType.EQUALITY)) { throw new ConfigException(ERR_PLUGIN_UNIQUEATTR_ATTR_UNINDEXED.get( @@ -690,7 +690,7 @@ { for (DN baseDN : cfgBaseDNs) { LocalBackend<?> b = DirectoryServer.getBackend(baseDN); LocalBackend<?> b = DirectoryServer.getLocalBackend(baseDN); if (b != null && ! b.isIndexed(t, IndexType.EQUALITY)) { unacceptableReasons.add(ERR_PLUGIN_UNIQUEATTR_ATTR_UNINDEXED.get( opendj-server-legacy/src/main/java/org/opends/server/replication/plugin/LDAPReplicationDomain.java
@@ -3694,7 +3694,7 @@ */ private LocalBackend<?> getBackend() { return DirectoryServer.getBackend(getBaseDN()); return DirectoryServer.getLocalBackend(getBaseDN()); } /* @@ -3761,7 +3761,7 @@ } // Check that the base DN is configured as a base-dn of the directory server if (DirectoryServer.getBackend(dn) == null) if (DirectoryServer.getLocalBackend(dn) == null) { unacceptableReasons.add(ERR_UNKNOWN_DN.get(dn)); return false; opendj-server-legacy/src/main/java/org/opends/server/tasks/ImportTask.java
@@ -299,7 +299,7 @@ // Find the backend that includes all the branches. for(DN includeBranch : includeBranches) { LocalBackend<?> locatedBackend = DirectoryServer.getBackend(includeBranch); LocalBackend<?> locatedBackend = DirectoryServer.getLocalBackend(includeBranch); if(locatedBackend != null) { if(backend == null) @@ -457,7 +457,7 @@ // Find the backend that includes all the branches. for(DN includeBranch : includeBranches) { LocalBackend<?> locatedBackend = DirectoryServer.getBackend(includeBranch); LocalBackend<?> locatedBackend = DirectoryServer.getLocalBackend(includeBranch); if(locatedBackend != null) { if(backend == null) opendj-server-legacy/src/main/java/org/opends/server/tasks/RebuildTask.java
@@ -166,7 +166,7 @@ rebuildConfig.setTmpDirectory(tmpDirectory); rebuildConfig.setRebuildMode(rebuildMode); final LocalBackend<?> backend = DirectoryServer.getBackendWithBaseDN(rebuildConfig.getBaseDN()); final LocalBackend<?> backend = DirectoryServer.getLocalBackendWithBaseDN(rebuildConfig.getBaseDN()); if (backend == null) { logger.error(ERR_NO_BACKENDS_FOR_BASE, baseDN); opendj-server-legacy/src/main/java/org/opends/server/tools/BackendCreationHelper.java
@@ -26,11 +26,12 @@ import org.forgerock.opendj.ldap.DN; import org.forgerock.opendj.server.config.client.BackendCfgClient; import org.forgerock.opendj.server.config.client.BackendIndexCfgClient; import org.forgerock.opendj.server.config.client.LocalBackendCfgClient; import org.forgerock.opendj.server.config.client.PluggableBackendCfgClient; import org.forgerock.opendj.server.config.client.RootCfgClient; import org.forgerock.opendj.server.config.meta.BackendCfgDefn.WritabilityMode; import org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn; import org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn.IndexType; import org.forgerock.opendj.server.config.meta.LocalBackendCfgDefn.WritabilityMode; import org.forgerock.opendj.server.config.server.BackendCfg; import org.opends.admin.ads.util.ConnectionWrapper; import org.opends.guitools.controlpanel.util.Utilities; @@ -169,7 +170,8 @@ private static void createBackend(RootCfgClient rootConfiguration, String backendName, Collection<DN> baseDNs, ManagedObjectDefinition<? extends BackendCfgClient, ? extends BackendCfg> backendType) throws Exception { final BackendCfgClient backendCfgClient = rootConfiguration.createBackend(backendType, backendName, null); final LocalBackendCfgClient backendCfgClient = (LocalBackendCfgClient) rootConfiguration.createBackend(backendType, backendName, null); backendCfgClient.setEnabled(true); backendCfgClient.setBaseDN(baseDNs); backendCfgClient.setWritabilityMode(WritabilityMode.ENABLED); opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java
@@ -141,15 +141,15 @@ /** * Process this add operation against a local backend. * * @param wfe * The local backend work-flow element. * @param backend * The backend on which operation is performed. * @throws CanceledOperationException * if this operation should be cancelled */ public void processLocalAdd(final LocalBackendWorkflowElement wfe) public void processLocalAdd(final LocalBackend<?> backend) throws CanceledOperationException { this.backend = wfe.getBackend(); this.backend = backend; ClientConnection clientConnection = getClientConnection(); // Check for a request to cancel this operation. opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendBindOperation.java
@@ -128,12 +128,12 @@ /** * Process this bind operation in a local backend. * * @param wfe * The local backend work-flow element. * @param backend * The backend on which operation is performed. */ public void processLocalBind(LocalBackendWorkflowElement wfe) public void processLocalBind(LocalBackend<?> backend) { this.backend = wfe.getBackend(); this.backend = backend; // Initialize a number of variables for use during the bind processing. clientConnection = getClientConnection(); opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java
@@ -104,16 +104,15 @@ /** * Process this compare operation in a local backend. * * @param wfe * The local backend work-flow element. * @param backend * The backend on which operation is performed. * @throws CanceledOperationException * if this operation should be cancelled */ public void processLocalCompare(LocalBackendWorkflowElement wfe) public void processLocalCompare(LocalBackend<?> backend) throws CanceledOperationException { this.backend = wfe.getBackend(); this.backend = backend; clientConnection = getClientConnection(); // Check for a request to cancel this operation. opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java
@@ -115,15 +115,15 @@ /** * Process this delete operation in a local backend. * * @param wfe * The local backend work-flow element. * @param backend * The backend on which operation is performed. * @throws CanceledOperationException * if this operation should be cancelled */ public void processLocalDelete(final LocalBackendWorkflowElement wfe) public void processLocalDelete(final LocalBackend<?> backend) throws CanceledOperationException { this.backend = wfe.getBackend(); this.backend = backend; clientConnection = getClientConnection(); opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java
@@ -155,15 +155,15 @@ /** * Process this modify DN operation in a local backend. * * @param wfe * The local backend work-flow element. * @param backend * The backend on which operation is performed. * @throws CanceledOperationException * if this operation should be cancelled */ public void processLocalModifyDN(final LocalBackendWorkflowElement wfe) public void processLocalModifyDN(final LocalBackend<?> backend) throws CanceledOperationException { this.backend = wfe.getBackend(); this.backend = backend; clientConnection = getClientConnection(); @@ -270,7 +270,7 @@ return; } LocalBackend<?> newBackend = DirectoryServer.getBackend(newDN); LocalBackend<?> newBackend = DirectoryServer.getLocalBackend(newDN); if (newBackend == null) { setResultCode(ResultCode.NO_SUCH_OBJECT); opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java
@@ -263,14 +263,14 @@ /** * Process this modify operation against a local backend. * * @param wfe * The local backend work-flow element. * @param backend * The backend on which operation is performed. * @throws CanceledOperationException * if this operation should be cancelled */ void processLocalModify(final LocalBackendWorkflowElement wfe) throws CanceledOperationException void processLocalModify(final LocalBackend<?> backend) throws CanceledOperationException { this.backend = wfe.getBackend(); this.backend = backend; this.clientConnection = getClientConnection(); checkIfCanceled(false); opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java
@@ -81,15 +81,15 @@ /** * Process this search operation against a local backend. * * @param wfe * The local backend work-flow element. * @param backend * The backend on which operation is performed. * @throws CanceledOperationException * if this operation should be cancelled */ public void processLocalSearch(LocalBackendWorkflowElement wfe) public void processLocalSearch(LocalBackend<?> backend) throws CanceledOperationException { this.backend = wfe.getBackend(); this.backend = backend; this.clientConnection = getClientConnection(); // Check for a request to cancel this operation. opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
@@ -17,11 +17,8 @@ package org.opends.server.workflowelement.localbackend; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.TreeMap; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.LocalizableMessageBuilder; import org.forgerock.i18n.LocalizableMessageDescriptor; @@ -31,7 +28,6 @@ import org.forgerock.opendj.ldap.SearchScope; import org.opends.server.api.AccessControlHandler; import org.opends.server.api.LocalBackend; import org.opends.server.backends.RootDSEBackend; import org.opends.server.controls.LDAPPostReadRequestControl; import org.opends.server.controls.LDAPPostReadResponseControl; import org.opends.server.controls.LDAPPreReadRequestControl; @@ -40,6 +36,8 @@ import org.opends.server.controls.ProxiedAuthV2Control; import org.opends.server.core.AccessControlConfigManager; import org.opends.server.core.AddOperation; import org.opends.server.core.BackendConfigManager; import org.opends.server.core.BackendConfigManager.BackendAndName; import org.opends.server.core.BindOperation; import org.opends.server.core.CompareOperation; import org.opends.server.core.DeleteOperation; @@ -61,6 +59,7 @@ import static org.opends.messages.CoreMessages.*; import static org.opends.messages.ProtocolMessages.ERR_PROXYAUTH_AUTHZ_NOT_PERMITTED; import static org.opends.server.core.DirectoryServer.getRootDSEBackend; import static org.opends.server.util.ServerConstants.*; /** @@ -209,91 +208,10 @@ private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); /** The backend's baseDN mapped by this object. */ private final DN baseDN; /** The backend associated with the local workflow element. */ private final LocalBackend<?> backend; /** The set of local backend workflow elements registered with the server. */ private static TreeMap<DN, LocalBackendWorkflowElement> registeredLocalBackends = new TreeMap<>(); /** A lock to guarantee safe concurrent access to the registeredLocalBackends variable. */ private static final Object registeredLocalBackendsLock = new Object(); /** * Creates a new instance of the local backend workflow element. * * @param baseDN * the backend's baseDN mapped by this object * @param backend * the backend associated to that workflow element */ private LocalBackendWorkflowElement(DN baseDN, LocalBackend<?> backend) { this.baseDN = baseDN; this.backend = backend; } /** * Indicates whether the workflow element encapsulates a private local backend. * * @return <code>true</code> if the workflow element encapsulates a private * local backend, <code>false</code> otherwise */ public boolean isPrivate() { return this.backend != null && this.backend.isPrivateBackend(); } /** * Creates and registers a local backend with the server. * * @param baseDN * the backend's baseDN mapped by this object * @param backend * the backend to associate with the local backend workflow element * @return the existing local backend workflow element if it was already * created or a newly created local backend workflow element. */ public static LocalBackendWorkflowElement createAndRegister(DN baseDN, LocalBackend<?> backend) { LocalBackendWorkflowElement localBackend = registeredLocalBackends.get(baseDN); if (localBackend == null) { localBackend = new LocalBackendWorkflowElement(baseDN, backend); registerLocalBackend(localBackend); } return localBackend; } /** * Removes a local backend that was registered with the server. * * @param baseDN * the identifier of the workflow to remove */ public static void remove(DN baseDN) { deregisterLocalBackend(baseDN); } /** * Removes all the local backends that were registered with the server. * This function is intended to be called when the server is shutting down. */ public static void removeAll() { synchronized (registeredLocalBackendsLock) { for (LocalBackendWorkflowElement localBackend : registeredLocalBackends.values()) { deregisterLocalBackend(localBackend.getBaseDN()); } } } /** * Check if an OID is for a proxy authorization control. * * @param oid The OID to check @@ -674,82 +592,45 @@ } /** * Registers a local backend with the server. * * @param localBackend the local backend to register with the server */ private static void registerLocalBackend(LocalBackendWorkflowElement localBackend) { synchronized (registeredLocalBackendsLock) { DN baseDN = localBackend.getBaseDN(); LocalBackendWorkflowElement existingLocalBackend = registeredLocalBackends.get(baseDN); if (existingLocalBackend == null) { TreeMap<DN, LocalBackendWorkflowElement> newLocalBackends = new TreeMap<>(registeredLocalBackends); newLocalBackends.put(baseDN, localBackend); registeredLocalBackends = newLocalBackends; } } } /** * Deregisters a local backend with the server. * * @param baseDN * the identifier of the local backend to remove */ private static void deregisterLocalBackend(DN baseDN) { synchronized (registeredLocalBackendsLock) { LocalBackendWorkflowElement existingLocalBackend = registeredLocalBackends.get(baseDN); if (existingLocalBackend != null) { TreeMap<DN, LocalBackendWorkflowElement> newLocalBackends = new TreeMap<>(registeredLocalBackends); newLocalBackends.remove(baseDN); registeredLocalBackends = newLocalBackends; } } } /** * Executes the workflow for an operation. * Executes an operation on the provided backend. * * @param operation * the operation to execute * @param backend * the backend on which operation must be executed * @throws CanceledOperationException * if this operation should be canceled */ private void execute(Operation operation) throws CanceledOperationException { private static void executeOperation(Operation operation, LocalBackend<?> backend) throws CanceledOperationException { switch (operation.getOperationType()) { case BIND: new LocalBackendBindOperation((BindOperation) operation).processLocalBind(this); new LocalBackendBindOperation((BindOperation) operation).processLocalBind(backend); break; case SEARCH: new LocalBackendSearchOperation((SearchOperation) operation).processLocalSearch(this); new LocalBackendSearchOperation((SearchOperation) operation).processLocalSearch(backend); break; case ADD: new LocalBackendAddOperation((AddOperation) operation).processLocalAdd(this); new LocalBackendAddOperation((AddOperation) operation).processLocalAdd(backend); break; case DELETE: new LocalBackendDeleteOperation((DeleteOperation) operation).processLocalDelete(this); new LocalBackendDeleteOperation((DeleteOperation) operation).processLocalDelete(backend); break; case MODIFY: new LocalBackendModifyOperation((ModifyOperation) operation).processLocalModify(this); new LocalBackendModifyOperation((ModifyOperation) operation).processLocalModify(backend); break; case MODIFY_DN: new LocalBackendModifyDNOperation((ModifyDNOperation) operation).processLocalModifyDN(this); new LocalBackendModifyDNOperation((ModifyDNOperation) operation).processLocalModifyDN(backend); break; case COMPARE: new LocalBackendCompareOperation((CompareOperation) operation).processLocalCompare(this); new LocalBackendCompareOperation((CompareOperation) operation).processLocalCompare(backend); break; case ABANDON: @@ -791,28 +672,6 @@ } /** * Provides the workflow element identifier. * * @return the workflow element identifier */ public DN getBaseDN() { return baseDN; } /** * Gets the backend associated with this local backend workflow * element. * * @return The backend associated with this local backend workflow * element. */ public LocalBackend<?> getBackend() { return backend; } /** * Checks if an update operation can be performed against a backend. The * operation will be rejected based on the server and backend writability * modes. @@ -873,8 +732,10 @@ */ public static boolean execute(Operation operation, DN entryDN) throws CanceledOperationException { LocalBackendWorkflowElement workflow = getLocalBackendWorkflowElement(entryDN); if (workflow == null) BackendAndName backendAndName = entryDN.isRootDN() ? new BackendAndName(getRootDSEBackend(), entryDN) : getBackendManager().getLocalBackend(entryDN); if (backendAndName == null) { // We have found no backend for the requested base DN, // just return a no such entry result code and stop the processing. @@ -885,213 +746,55 @@ return false; } if (workflow.getBaseDN().isRootDN()) executeOperation(operation, backendAndName.getBackend()); if (!entryDN.isRootDN()) { executeOnRootDSE(operation, workflow); // For subtree search operation we need to go through the subordinate nodes. if (operation.getOperationType() == OperationType.SEARCH) { executeSearchOnSubordinates((SearchOperation) operation, backendAndName.getBaseDn()); } } else { executeOnNonRootDSE(operation, workflow); } return true; } private static LocalBackendWorkflowElement getLocalBackendWorkflowElement(DN entryDN) private static BackendConfigManager getBackendManager() { if (entryDN.isRootDN()) { return registeredLocalBackends.get(entryDN); } /* * Try to minimize the number of lookups in the Map to find the backend containing the entry. * If the DN contains many RDNs it is faster to iterate through the list of registered backends, * otherwise iterating through the parents requires less lookups. It also avoids some attacks * where we would spend time going through the list of all parents to finally decide the * baseDN is absent. */ if (entryDN.size() <= registeredLocalBackends.size()) { while (!entryDN.isRootDN()) { final LocalBackendWorkflowElement workflow = registeredLocalBackends.get(entryDN); if (workflow != null) { return workflow; } entryDN = entryDN.parent(); } return null; } else { LocalBackendWorkflowElement workflow = null; int currentSize = 0; for (DN backendDN : registeredLocalBackends.keySet()) { if (entryDN.isSubordinateOrEqualTo(backendDN) && backendDN.size() > currentSize) { workflow = registeredLocalBackends.get(backendDN); currentSize = backendDN.size(); } } return workflow; } return DirectoryServer.getInstance().getServerContext().getBackendManager(); } /** * Executes an operation on the root DSE entry. * * @param operation * the operation to execute * @param workflow * the workflow where to execute the operation * @throws CanceledOperationException * if this operation should be cancelled. */ private static void executeOnRootDSE(Operation operation, LocalBackendWorkflowElement workflow) throws CanceledOperationException { OperationType operationType = operation.getOperationType(); if (operationType == OperationType.SEARCH) { executeSearch((SearchOperation) operation, workflow); } else { workflow.execute(operation); } } /** * Executes a search operation on the the root DSE entry. * * @param searchOp * the operation to execute * @param workflow * the workflow where to execute the operation * @throws CanceledOperationException * if this operation should be cancelled. */ private static void executeSearch(SearchOperation searchOp, LocalBackendWorkflowElement workflow) throws CanceledOperationException { // Keep a the original search scope because we will alter it in the operation SearchScope originalScope = searchOp.getScope(); // Search base? // The root DSE entry itself is never returned unless the operation // is a search base on the null suffix. if (originalScope == SearchScope.BASE_OBJECT) { workflow.execute(searchOp); return; } // Create a workflow result code in case we need to perform search in // subordinate workflows. SearchResultCode searchResultCode = new SearchResultCode(searchOp.getResultCode(), searchOp.getErrorMessage()); // The search scope is not 'base', so let's do a search on all the public // naming contexts with appropriate new search scope and new base DN. SearchScope newScope = elaborateScopeForSearchInSubordinates(originalScope); searchOp.setScope(newScope); DN originalBaseDN = searchOp.getBaseDN(); for (LocalBackendWorkflowElement subordinate : getRootDSESubordinates()) { // We have to change the operation request base DN to match the // subordinate workflow base DN. Otherwise the workflow will // return a no such entry result code as the operation request // base DN is a superior of the workflow base DN! DN ncDN = subordinate.getBaseDN(); // Set the new request base DN then do execute the operation // in the naming context workflow. searchOp.setBaseDN(ncDN); execute(searchOp, ncDN); boolean sendReferenceEntry = searchResultCode.elaborateGlobalResultCode( searchOp.getResultCode(), searchOp.getErrorMessage()); if (sendReferenceEntry) { // TODO jdemendi - turn a referral result code into a reference entry // and send the reference entry to the client application } } // Now restore the original request base DN and original search scope searchOp.setBaseDN(originalBaseDN); searchOp.setScope(originalScope); // If the result code is still uninitialized (ie no naming context), // we should return NO_SUCH_OBJECT searchResultCode.elaborateGlobalResultCode( ResultCode.NO_SUCH_OBJECT, new LocalizableMessageBuilder(LocalizableMessage.EMPTY)); // Set the operation result code and error message searchOp.setResultCode(searchResultCode.resultCode); searchOp.setErrorMessage(searchResultCode.errorMessage); } private static Collection<LocalBackendWorkflowElement> getRootDSESubordinates() { final RootDSEBackend rootDSEBackend = DirectoryServer.getRootDSEBackend(); final List<LocalBackendWorkflowElement> results = new ArrayList<>(); for (DN subordinateBaseDN : rootDSEBackend.getSubordinateBaseDNs().keySet()) { results.add(registeredLocalBackends.get(subordinateBaseDN)); } return results; } private static void executeOnNonRootDSE(Operation operation, LocalBackendWorkflowElement workflow) throws CanceledOperationException { workflow.execute(operation); // For subtree search operation we need to go through the subordinate nodes. if (operation.getOperationType() == OperationType.SEARCH) { executeSearchOnSubordinates((SearchOperation) operation, workflow); } } /** * Executes a search operation on the subordinate workflows. * Executes a search operation on the subordinates of backend corresponding to provided base DN. * * @param searchOp * the search operation to execute * @param workflow * the workflow element * @param baseDN * base DN to search * @throws CanceledOperationException * if this operation should be canceled. */ private static void executeSearchOnSubordinates(SearchOperation searchOp, LocalBackendWorkflowElement workflow) private static void executeSearchOnSubordinates(SearchOperation searchOp, DN baseDN) throws CanceledOperationException { // If the scope of the search is 'base' then it's useless to search // in the subordinate workflows. SearchScope originalScope = searchOp.getScope(); if (originalScope == SearchScope.BASE_OBJECT) { return; } // Elaborate the new search scope before executing the search operation // in the subordinate workflows. SearchScope newScope = elaborateScopeForSearchInSubordinates(originalScope); searchOp.setScope(newScope); // Let's search in the subordinate workflows. SearchResultCode searchResultCode = new SearchResultCode(searchOp.getResultCode(), searchOp.getErrorMessage()); DN originalBaseDN = searchOp.getBaseDN(); for (LocalBackendWorkflowElement subordinate : getSubordinates(workflow)) for (BackendAndName subordinate : getBackendManager().getSubordinateBackends(baseDN)) { // We have to change the operation request base DN to match the // subordinate workflow base DN. Otherwise the workflow will // return a no such entry result code as the operation request // base DN is a superior of the subordinate workflow base DN. DN subordinateDN = subordinate.getBaseDN(); DN subordinateDN = subordinate.getBaseDn(); // If the new search scope is 'base' and the search base DN does not // map the subordinate workflow then skip the subordinate workflow. @@ -1130,25 +833,6 @@ searchOp.setErrorMessage(searchResultCode.errorMessage); } private static Collection<LocalBackendWorkflowElement> getSubordinates(LocalBackendWorkflowElement workflow) { final DN baseDN = workflow.getBaseDN(); final LocalBackend<?> backend = workflow.getBackend(); final ArrayList<LocalBackendWorkflowElement> results = new ArrayList<>(); for (LocalBackend<?> subordinate : backend.getSubordinateBackends()) { for (DN subordinateDN : subordinate.getBaseDNs()) { if (subordinateDN.isSubordinateOrEqualTo(baseDN)) { results.add(registeredLocalBackends.get(subordinateDN)); } } } return results; } /** * Elaborates a new search scope according to the current search scope. The * new scope is intended to be used for searches on subordinate workflows. @@ -1195,12 +879,4 @@ } return null; } @Override public String toString() { return getClass().getSimpleName() + " backend=" + this.backend + " baseDN=" + this.baseDN; } } opendj-server-legacy/src/messages/org/opends/messages/backend.properties
@@ -1097,3 +1097,6 @@ ERR_BACKEND_FAULTY_CRYPTO_TRANSFORMATION_608=Error while enabling confidentiality with cipher %s, %d bits: %s ERR_IMPORT_DUPLICATE_ENTRY_609=The import has been aborted because the data to be imported contains duplicate \ copies of entry '%s' ERR_ROOTDSE_NOT_SUPPORTED_SCOPE_610=Unwilling to perform a search \ (connection ID %d, operation ID %d) with a scope of "%s" in the root DSE \ backend. Only the BASE scope is supported for the root DSE backend. opendj-server-legacy/src/test/java/org/opends/server/backends/task/TaskBackendTestCase.java
@@ -472,7 +472,7 @@ String taskSchedule = "00 * * " + scheduledMonth + " *"; TaskBackend taskBackend = (TaskBackend) DirectoryServer.getBackend(DN.valueOf("cn=tasks")); (TaskBackend) DirectoryServer.getLocalBackend(DN.valueOf("cn=tasks")); long tasksCountBefore = taskBackend.getNumberOfEntriesInBaseDN(DN.valueOf("cn=Scheduled Tasks,cn=tasks")); assertTrue(addRecurringTask(taskID, taskSchedule)); opendj-server-legacy/src/test/java/org/opends/server/core/AddOperationTestCase.java
@@ -72,7 +72,7 @@ /** Some of the tests disable the backends, so we reenable them here. */ @AfterMethod(alwaysRun=true) public void reenableBackend() throws DirectoryException { LocalBackend<?> b = DirectoryServer.getBackend(DN.valueOf("o=test")); LocalBackend<?> b = DirectoryServer.getLocalBackend(DN.valueOf("o=test")); b.setWritabilityMode(WritabilityMode.ENABLED); } @@ -1209,7 +1209,7 @@ "cn: Test User", "userPassword: password"); LocalBackend<?> b = DirectoryServer.getBackend(DN.valueOf("o=test")); LocalBackend<?> b = DirectoryServer.getLocalBackend(DN.valueOf("o=test")); b.setWritabilityMode(WritabilityMode.DISABLED); AddOperation addOperation = getRootConnection().processAdd(entry); @@ -1241,7 +1241,7 @@ "cn: Test User", "userPassword: password"); LocalBackend<?> b = DirectoryServer.getBackend(DN.valueOf("o=test")); LocalBackend<?> b = DirectoryServer.getLocalBackend(DN.valueOf("o=test")); b.setWritabilityMode(WritabilityMode.INTERNAL_ONLY); AddOperation addOperation = getRootConnection().processAdd(entry); @@ -1266,7 +1266,7 @@ { conn.bind("cn=Directory Manager", "password"); LocalBackend<?> b = DirectoryServer.getBackend(DN.valueOf("o=test")); LocalBackend<?> b = DirectoryServer.getLocalBackend(DN.valueOf("o=test")); b.setWritabilityMode(WritabilityMode.INTERNAL_ONLY); long addRequests = ldapStatistics.getAddRequests(); opendj-server-legacy/src/test/java/org/opends/server/core/BackendConfigManagerTestCase.java
@@ -129,7 +129,7 @@ processAdd(backendEntry); assertNull(DirectoryServer.getBackend(backendID)); assertNull(DirectoryServer.getBackendWithBaseDN(baseDN)); assertNull(DirectoryServer.getLocalBackendWithBaseDN(baseDN)); DeleteOperation deleteOperation = getRootConnection().processDelete(backendEntry.getName()); assertEquals(deleteOperation.getResultCode(), ResultCode.SUCCESS); @@ -234,7 +234,7 @@ LocalBackend<?> childBackend = DirectoryServer.getBackend(childBackendID); assertNotNull(childBackend); assertEquals(childBackend, DirectoryServer.getBackendWithBaseDN(childBaseDN)); DirectoryServer.getLocalBackendWithBaseDN(childBaseDN)); assertNotNull(childBackend.getParentBackend()); assertEquals(parentBackend, childBackend.getParentBackend()); assertEquals(parentBackend.getSubordinateBackends().length, 1); @@ -305,7 +305,7 @@ LocalBackend<?> parentBackend = DirectoryServer.getBackend(parentBackendID); assertNotNull(parentBackend); assertEquals(parentBackend, DirectoryServer.getBackendWithBaseDN(parentBaseDN)); DirectoryServer.getLocalBackendWithBaseDN(parentBaseDN)); assertNotNull(childBackend.getParentBackend()); assertEquals(parentBackend, childBackend.getParentBackend()); assertEquals(parentBackend.getSubordinateBackends().length, 1); @@ -336,7 +336,7 @@ private void assertBackend(DN baseDN, LocalBackend<?> backend) throws DirectoryException { assertNotNull(backend); assertEquals(backend, DirectoryServer.getBackendWithBaseDN(baseDN)); assertEquals(backend, DirectoryServer.getLocalBackendWithBaseDN(baseDN)); assertFalse(backend.entryExists(baseDN)); assertNull(backend.getParentBackend()); assertEquals(backend.getSubordinateBackends().length, 0); @@ -377,7 +377,7 @@ LocalBackend<?> grandchildBackend = DirectoryServer.getBackend(grandchildBackendID); assertNotNull(grandchildBackend); assertEquals(grandchildBackend, DirectoryServer.getBackendWithBaseDN(grandchildBaseDN)); DirectoryServer.getLocalBackendWithBaseDN(grandchildBaseDN)); assertNotNull(grandchildBackend.getParentBackend()); assertEquals(grandchildBackend.getParentBackend(), parentBackend); assertEquals(parentBackend.getSubordinateBackends().length, 1); @@ -480,7 +480,7 @@ LocalBackend<?> grandchildBackend) throws DirectoryException { assertNotNull(childBackend); assertEquals(childBackend, DirectoryServer.getBackendWithBaseDN(childBaseDN)); assertEquals(childBackend, DirectoryServer.getLocalBackendWithBaseDN(childBaseDN)); assertNotNull(childBackend.getParentBackend()); assertEquals(parentBackend, childBackend.getParentBackend()); assertEquals(parentBackend.getSubordinateBackends().length, 1); opendj-server-legacy/src/test/java/org/opends/server/core/DeleteOperationTestCase.java
@@ -58,7 +58,7 @@ /** Some of the tests disable the backends, so we reenable them here. */ @AfterMethod(alwaysRun=true) public void reenableBackend() throws DirectoryException { LocalBackend<?> b = DirectoryServer.getBackend(DN.valueOf("o=test")); LocalBackend<?> b = DirectoryServer.getLocalBackend(DN.valueOf("o=test")); b.setWritabilityMode(WritabilityMode.ENABLED); } @@ -569,7 +569,7 @@ { TestCaseUtils.initializeTestBackend(true); LocalBackend<?> backend = DirectoryServer.getBackend(DN.valueOf("o=test")); LocalBackend<?> backend = DirectoryServer.getLocalBackend(DN.valueOf("o=test")); backend.setWritabilityMode(WritabilityMode.DISABLED); DeleteOperation deleteOperation = processDeleteRaw("o=test"); @@ -591,7 +591,7 @@ { TestCaseUtils.initializeTestBackend(true); LocalBackend<?> backend = DirectoryServer.getBackend(DN.valueOf("o=test")); LocalBackend<?> backend = DirectoryServer.getLocalBackend(DN.valueOf("o=test")); backend.setWritabilityMode(WritabilityMode.INTERNAL_ONLY); DeleteOperation deleteOperation = processDeleteRaw("o=test"); @@ -613,7 +613,7 @@ { TestCaseUtils.initializeTestBackend(true); LocalBackend<?> backend = DirectoryServer.getBackend(DN.valueOf("o=test")); LocalBackend<?> backend = DirectoryServer.getLocalBackend(DN.valueOf("o=test")); backend.setWritabilityMode(WritabilityMode.INTERNAL_ONLY); String[] args = getArgs("o=test"); opendj-server-legacy/src/test/java/org/opends/server/core/ModifyOperationTestCase.java
@@ -96,7 +96,7 @@ for (Object[] backendBaseDN2 : getBaseDNs()) { final DN baseDN = DN.valueOf(backendBaseDN2[0].toString()); LocalBackend<?> b = DirectoryServer.getBackend(baseDN); LocalBackend<?> b = DirectoryServer.getLocalBackend(baseDN); b.setWritabilityMode(WritabilityMode.ENABLED); } } @@ -2429,7 +2429,7 @@ "mail: foo", "employeeNumber: 1"); LocalBackend<?> b = DirectoryServer.getBackend(DN.valueOf(baseDN)); LocalBackend<?> b = DirectoryServer.getLocalBackend(DN.valueOf(baseDN)); b.setWritabilityMode(WritabilityMode.DISABLED); RawModification mod = newRawModification(ADD, "objectClass", "extensibleObject"); @@ -2467,7 +2467,7 @@ "mail: foo", "employeeNumber: 1"); LocalBackend<?> b = DirectoryServer.getBackend(DN.valueOf(baseDN)); LocalBackend<?> b = DirectoryServer.getLocalBackend(DN.valueOf(baseDN)); b.setWritabilityMode(WritabilityMode.INTERNAL_ONLY); RawModification mod = newRawModification(ADD, "objectClass", "extensibleObject"); @@ -2505,7 +2505,7 @@ "mail: foo", "employeeNumber: 1"); LocalBackend<?> b = DirectoryServer.getBackend(DN.valueOf(baseDN)); LocalBackend<?> b = DirectoryServer.getLocalBackend(DN.valueOf(baseDN)); b.setWritabilityMode(WritabilityMode.INTERNAL_ONLY); try (RemoteConnection conn = new RemoteConnection("localhost", TestCaseUtils.getServerLdapPort())) opendj-server-legacy/src/test/java/org/opends/server/extensions/CommonEntryCacheTestCase.java
@@ -95,7 +95,7 @@ cache.toVerboseString()); TestCaseUtils.initializeTestBackend(false); String b = DirectoryServer.getBackend(DN.valueOf("o=test")).getBackendID(); String b = DirectoryServer.getLocalBackend(DN.valueOf("o=test")).getBackendID(); assertFalse(cache.containsEntry(testEntriesList.get(0).getName()), "Not expected to find " + testEntriesList.get(0).getName() + @@ -129,7 +129,7 @@ cache.toVerboseString()); TestCaseUtils.initializeTestBackend(false); String b = DirectoryServer.getBackend(DN.valueOf("o=test")).getBackendID(); String b = DirectoryServer.getLocalBackend(DN.valueOf("o=test")).getBackendID(); assertNull(cache.getEntry(testEntriesList.get(0).getName()), "Not expected to find " + testEntriesList.get(0).getName() + @@ -163,7 +163,7 @@ cache.toVerboseString()); TestCaseUtils.initializeTestBackend(false); String b = DirectoryServer.getBackend(DN.valueOf("o=test")).getBackendID(); String b = DirectoryServer.getLocalBackend(DN.valueOf("o=test")).getBackendID(); assertNull(cache.getEntry(testEntriesList.get(0).getName()), "Not expected to find " + testEntriesList.get(0).getName() + @@ -197,7 +197,7 @@ cache.toVerboseString()); TestCaseUtils.initializeTestBackend(false); String b = DirectoryServer.getBackend(DN.valueOf("o=test")).getBackendID(); String b = DirectoryServer.getLocalBackend(DN.valueOf("o=test")).getBackendID(); assertNull(cache.getEntry(b, -1), "Not expected to find entry id " + -1 + @@ -230,7 +230,7 @@ cache.toVerboseString()); TestCaseUtils.initializeTestBackend(false); String b = DirectoryServer.getBackend(DN.valueOf("o=test")).getBackendID(); String b = DirectoryServer.getLocalBackend(DN.valueOf("o=test")).getBackendID(); assertEquals(cache.getEntryID(testEntriesList.get(0).getName()), -1, "Not expected to find " + testEntriesList.get(0).getName() + @@ -263,7 +263,7 @@ cache.toVerboseString()); TestCaseUtils.initializeTestBackend(false); String b = DirectoryServer.getBackend(DN.valueOf("o=test")).getBackendID(); String b = DirectoryServer.getLocalBackend(DN.valueOf("o=test")).getBackendID(); cache.putEntry(testEntriesList.get(0), b, 1); @@ -296,7 +296,7 @@ cache.toVerboseString()); TestCaseUtils.initializeTestBackend(false); String b = DirectoryServer.getBackend(DN.valueOf("o=test")).getBackendID(); String b = DirectoryServer.getLocalBackend(DN.valueOf("o=test")).getBackendID(); assertTrue(cache.putEntryIfAbsent(testEntriesList.get(0), b, 1), "Not expected to find " + testEntriesList.get(0).getName() + @@ -337,7 +337,7 @@ cache.toVerboseString()); TestCaseUtils.initializeTestBackend(false); String b = DirectoryServer.getBackend(DN.valueOf("o=test")).getBackendID(); String b = DirectoryServer.getLocalBackend(DN.valueOf("o=test")).getBackendID(); cache.removeEntry(testEntriesList.get(0).getName()); cache.putEntry(testEntriesList.get(0), b, 1); @@ -372,7 +372,7 @@ cache.toVerboseString()); TestCaseUtils.initializeTestBackend(false); String b = DirectoryServer.getBackend(DN.valueOf("o=test")).getBackendID(); String b = DirectoryServer.getLocalBackend(DN.valueOf("o=test")).getBackendID(); cache.clear(); cache.putEntry(testEntriesList.get(0), b, 1); @@ -407,8 +407,8 @@ cache.toVerboseString()); TestCaseUtils.initializeTestBackend(false); String b = DirectoryServer.getBackend(DN.valueOf("o=test")).getBackendID(); String c = DirectoryServer.getBackend(DN.valueOf("cn=config")).getBackendID(); String b = DirectoryServer.getLocalBackend(DN.valueOf("o=test")).getBackendID(); String c = DirectoryServer.getLocalBackend(DN.valueOf("cn=config")).getBackendID(); cache.clearBackend(b); cache.putEntry(testEntriesList.get(0), b, 1); @@ -449,8 +449,8 @@ cache.toVerboseString()); TestCaseUtils.initializeTestBackend(false); String b = DirectoryServer.getBackend(DN.valueOf("o=test")).getBackendID(); String c = DirectoryServer.getBackend(DN.valueOf("cn=config")).getBackendID(); String b = DirectoryServer.getLocalBackend(DN.valueOf("o=test")).getBackendID(); String c = DirectoryServer.getLocalBackend(DN.valueOf("cn=config")).getBackendID(); cache.putEntry(testEntriesList.get(0), b, 1); Entry testEntry = testEntriesList.get(1); @@ -510,7 +510,7 @@ public void testCacheConcurrency() throws Exception { String b = DirectoryServer.getBackend(DN.valueOf("o=test")).getBackendID(); String b = DirectoryServer.getLocalBackend(DN.valueOf("o=test")).getBackendID(); for(int loops = 0; loops < CONCURRENCYLOOPS; loops++) { for(int i = 0; i < NUMTESTENTRIES; i++) { opendj-server-legacy/src/test/java/org/opends/server/extensions/DefaultEntryCacheTestCase.java
@@ -361,7 +361,7 @@ cache.toVerboseString()); TestCaseUtils.initializeTestBackend(false); String b = DirectoryServer.getBackend(DN.valueOf("o=test")).getBackendID(); String b = DirectoryServer.getLocalBackend(DN.valueOf("o=test")).getBackendID(); // Spread test entries among all cache levels via default cache. for (int i = 0; i < NUMTESTENTRIES; i++) { opendj-server-legacy/src/test/java/org/opends/server/extensions/FIFOEntryCacheTestCase.java
@@ -252,7 +252,7 @@ "Expected empty cache. " + "Cache contents:" + ServerConstants.EOL + cache.toVerboseString()); String b = DirectoryServer.getBackend(DN.valueOf("o=test")).getBackendID(); String b = DirectoryServer.getLocalBackend(DN.valueOf("o=test")).getBackendID(); for(int i = 0; i < super.NUMTESTENTRIES; i++ ) { super.cache.putEntry(super.testEntriesList.get(i), b, i); @@ -322,7 +322,7 @@ "Expected empty cache. " + "Cache contents:" + ServerConstants.EOL + cache.toVerboseString()); String b = DirectoryServer.getBackend(DN.valueOf("o=test")).getBackendID(); String b = DirectoryServer.getLocalBackend(DN.valueOf("o=test")).getBackendID(); for(int i = 0; i < super.NUMTESTENTRIES; i++ ) { super.cache.putEntry(super.testEntriesList.get(i), b, i); opendj-server-legacy/src/test/java/org/opends/server/tasks/TasksTestCase.java
@@ -108,7 +108,7 @@ @Test(enabled=false) // This isn't a test method, but TestNG thinks it is. public static Task getTask(final DN taskEntryDN) throws Exception { final TaskBackend taskBackend = (TaskBackend) DirectoryServer.getBackend(DN.valueOf("cn=tasks")); final TaskBackend taskBackend = (TaskBackend) DirectoryServer.getLocalBackend(DN.valueOf("cn=tasks")); TestTimer timer = new TestTimer.Builder() .maxSleep(10, SECONDS) opendj-server-legacy/src/test/java/org/opends/server/types/PrivilegeTestCase.java
@@ -2378,7 +2378,7 @@ private Task getCompletedTask(DN taskEntryDN) throws Exception { TaskBackend taskBackend = (TaskBackend) DirectoryServer.getBackend(DN.valueOf("cn=tasks")); (TaskBackend) DirectoryServer.getLocalBackend(DN.valueOf("cn=tasks")); Task task = taskBackend.getScheduledTask(taskEntryDN); if (task == null) { opendj-server-legacy/src/test/java/org/opends/server/types/TestDN.java
@@ -40,7 +40,8 @@ public Object[][] getNamingContexts() { ArrayList<DN> contextList = new ArrayList<>(); contextList.addAll(DirectoryServer.getPublicNamingContexts().keySet()); contextList.addAll(DirectoryServer.getPrivateNamingContexts().keySet()); contextList.addAll(DirectoryServer.getInstance().getServerContext().getBackendManager(). getPrivateNamingContexts().keySet()); Object[][] contextArray = new Object[contextList.size()][1]; for (int i = 0;i < contextArray.length;i++) {