| | |
| | | |
| | | private RootDSEBackend rootDSEBackend; |
| | | |
| | | /** Lock to protect reads of the backend maps. */ |
| | | private final ReadLock readLock; |
| | | /** Lock to protect updates of the backends maps. */ |
| | | private final WriteLock writeLock; |
| | | |
| | | /** |
| | | * Creates a new instance of this backend config manager. |
| | | * |
| | |
| | | { |
| | | this.serverContext = serverContext; |
| | | this.localBackendsRegistry = new BaseDnRegistry(); |
| | | ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| | | readLock = lock.readLock(); |
| | | writeLock = lock.writeLock(); |
| | | } |
| | | |
| | | /** |
| | |
| | | backend.setBackendID(backendCfg.getBackendId()); |
| | | setLocalBackendWritabilityMode(backend, backendCfg); |
| | | |
| | | if (acquireSharedLock(backend, backendCfg.getBackendId(), ccr) && configureAndOpenBackend(backend, backendCfg, ccr)) |
| | | if (acquireSharedLock(backend, backendCfg.getBackendId(), ccr) |
| | | && configureAndOpenBackend(backend, backendCfg, ccr)) |
| | | { |
| | | registerBackend(backend, backendCfg, ccr); |
| | | } |
| | |
| | | ifNull(backend); |
| | | String backendID = backend.getBackendID(); |
| | | ifNull(backendID); |
| | | writeLock.lock(); |
| | | try |
| | | { |
| | | if (localBackends.containsKey(backendID)) |
| | | { |
| | | LocalizableMessage message = ERR_REGISTER_BACKEND_ALREADY_EXISTS.get(backendID); |
| | |
| | | backend.setBackendMonitor(monitor); |
| | | registerMonitorProvider(monitor); |
| | | } |
| | | finally { |
| | | writeLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Registers a local backend initialization listener. |
| | |
| | | public void deregisterLocalBackend(LocalBackend<?> backend) |
| | | { |
| | | ifNull(backend); |
| | | writeLock.lock(); |
| | | try |
| | | { |
| | | localBackends.remove(backend.getBackendID()); |
| | | LocalBackendMonitor monitor = backend.getBackendMonitor(); |
| | | if (monitor != null) |
| | |
| | | backend.setBackendMonitor(null); |
| | | } |
| | | } |
| | | finally { |
| | | writeLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public boolean isConfigurationChangeAcceptable( |
| | |
| | | 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<>(); |
| | | /** Lock to protect reads of the maps. */ |
| | | private final ReadLock readLock; |
| | | /** Lock to protect updates of the maps. */ |
| | | private final WriteLock writeLock; |
| | | |
| | | /** |
| | | * Indicates whether this base DN registry is in test mode. |
| | |
| | | List<LocalizableMessage> registerBaseDN(DN baseDN, LocalBackend<?> backend, boolean isPrivate) |
| | | throws DirectoryException |
| | | { |
| | | writeLock.lock(); |
| | | try |
| | | { |
| | | return registerBaseDN0(baseDN, backend, isPrivate); |
| | | } |
| | | finally |
| | | { |
| | | writeLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | private List<LocalizableMessage> registerBaseDN0(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) |
| | |
| | | |
| | | LocalBackend<?> getBackendWithBaseDN(DN entryDN) |
| | | { |
| | | readLock.lock(); |
| | | try |
| | | { |
| | | return baseDNs.get(entryDN); |
| | | } |
| | | finally |
| | | { |
| | | readLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | |
| | | BackendAndName getBackendAndName(final DN entryDN) |
| | | { |
| | | readLock.lock(); |
| | | try |
| | | { |
| | | /* |
| | | * 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, |
| | |
| | | return new BackendAndName(backend, matchedDN); |
| | | } |
| | | } |
| | | finally |
| | | { |
| | | readLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | private LocalBackend<?> getSuperiorBackend(DN baseDN, LinkedList<DN> otherBaseDNs, String backendID) |
| | | throws DirectoryException |
| | | { |
| | | readLock.lock(); |
| | | try |
| | | { |
| | | LocalBackend<?> superiorBackend = null; |
| | | DN parentDN = baseDN.parent(); |
| | | while (parentDN != null) |
| | |
| | | } |
| | | return superiorBackend; |
| | | } |
| | | finally |
| | | { |
| | | readLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Deregisters a base DN with this registry. |
| | |
| | | * committed to the server |
| | | * @throws DirectoryException if the base DN could not be deregistered |
| | | */ |
| | | List<LocalizableMessage> deregisterBaseDN(DN baseDN) |
| | | throws DirectoryException |
| | | List<LocalizableMessage> deregisterBaseDN(DN baseDN) throws DirectoryException |
| | | { |
| | | writeLock.lock(); |
| | | try |
| | | { |
| | | return deregisterBaseDN0(baseDN); |
| | | } |
| | | finally |
| | | { |
| | | writeLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | List<LocalizableMessage> deregisterBaseDN0(DN baseDN) throws DirectoryException |
| | | { |
| | | ifNull(baseDN); |
| | | |
| | |
| | | */ |
| | | BaseDnRegistry copy() |
| | | { |
| | | readLock.lock(); |
| | | try |
| | | { |
| | | final BaseDnRegistry registry = new BaseDnRegistry(true); |
| | | registry.baseDNs.putAll(baseDNs); |
| | | registry.publicNamingContexts.putAll(publicNamingContexts); |
| | |
| | | registry.privateNamingContexts.putAll(privateNamingContexts); |
| | | return registry; |
| | | } |
| | | finally |
| | | { |
| | | readLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Creates a parameterized instance. |
| | |
| | | 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; |
| | | ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| | | readLock = lock.readLock(); |
| | | writeLock = lock.writeLock(); |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | Map<DN, LocalBackend<?>> getPublicNamingContextsMap() |
| | | { |
| | | readLock.lock(); |
| | | try |
| | | { |
| | | return this.publicNamingContexts; |
| | | } |
| | | finally |
| | | { |
| | | readLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Gets the mapping of registered public naming contexts, including sub-suffixes, |
| | |
| | | */ |
| | | Map<DN, LocalBackend<?>> getAllPublicNamingContextsMap() |
| | | { |
| | | readLock.lock(); |
| | | try |
| | | { |
| | | return this.allPublicNamingContexts; |
| | | } |
| | | finally |
| | | { |
| | | readLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Gets the mapping of registered private naming contexts to their |
| | |
| | | */ |
| | | Map<DN, LocalBackend<?>> getPrivateNamingContextsMap() |
| | | { |
| | | readLock.lock(); |
| | | try |
| | | { |
| | | return this.privateNamingContexts; |
| | | } |
| | | finally |
| | | { |
| | | readLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Indicates whether the specified DN is contained in this registry as |
| | |
| | | */ |
| | | boolean containsNamingContext(DN dn) |
| | | { |
| | | readLock.lock(); |
| | | try |
| | | { |
| | | 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(); |
| | | finally |
| | | { |
| | | readLock.unlock(); |
| | | } |
| | | } |
| | | } |
| | | |