Fix OPEND-250: Add an option to the JE backend for disabling the subordinate indexes id2children and id2subtree
Add a boolean option "subordinate-indexes-enabled" to the JE backend configuration which can be used for disabling the subordinate indexes id2children and id2subtree.
1 files added
9 files modified
| | |
| | | SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 |
| | | SINGLE-VALUE |
| | | X-ORIGIN 'OpenDJ Directory Server' ) |
| | | attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.11 |
| | | NAME 'ds-cfg-subordinate-indexes-enabled' |
| | | SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 |
| | | SINGLE-VALUE |
| | | X-ORIGIN 'OpenDJ Directory Server' ) |
| | | objectClasses: ( 1.3.6.1.4.1.26027.1.2.1 |
| | | NAME 'ds-cfg-access-control-handler' |
| | | SUP top |
| | |
| | | ds-cfg-disk-full-threshold $ |
| | | ds-cfg-disk-low-threshold $ |
| | | ds-cfg-index-filter-analyzer-enabled $ |
| | | ds-cfg-index-filter-analyzer-max-filters ) |
| | | ds-cfg-index-filter-analyzer-max-filters $ |
| | | ds-cfg-subordinate-indexes-enabled ) |
| | | X-ORIGIN 'OpenDS Directory Server' ) |
| | | objectClasses: ( 1.3.6.1.4.1.26027.1.2.7 |
| | | NAME 'ds-cfg-local-db-index' |
| | |
| | | </ldap:attribute> |
| | | </adm:profile> |
| | | </adm:property> |
| | | <adm:property name="subordinate-indexes-enabled" advanced="true"> |
| | | <adm:synopsis> |
| | | Indicates whether id2children and id2subtree indexes should be used for |
| | | this backend. These indexes are used for constraining filtered searches |
| | | to the search request's scope as well as for generating values for the |
| | | hasSubordinates and numSubordinates virtual attributes. |
| | | </adm:synopsis> |
| | | <adm:description> |
| | | Subordinate indexing is enabled by default and should only be disabled |
| | | for specialized use cases. A typical use case is where the backend is |
| | | to be subjected to heavy add/delete load beneath the same parent entry |
| | | such as when used as a session database. Disabling the subordinate |
| | | indexes means that the numSubordinates and hasSubordinates virtual |
| | | attributes will not be supported. |
| | | </adm:description> |
| | | <adm:default-behavior> |
| | | <adm:defined> |
| | | <adm:value>true</adm:value> |
| | | </adm:defined> |
| | | </adm:default-behavior> |
| | | <adm:syntax> |
| | | <adm:boolean /> |
| | | </adm:syntax> |
| | | <adm:profile name="ldap"> |
| | | <ldap:attribute> |
| | | <ldap:name>ds-cfg-subordinate-indexes-enabled</ldap:name> |
| | | </ldap:attribute> |
| | | </adm:profile> |
| | | </adm:property> |
| | | </adm:managed-object> |
| | |
| | | property.je-property.description=Any Berkeley DB Java Edition property can be specified using the following form: property-name=property-value. Refer to OpenDJ documentation for further information on related properties, their implications, and range values. The definitive identification of all the property parameters is available in the example.properties file of Berkeley DB Java Edition distribution. |
| | | property.preload-time-limit.synopsis=Specifies the length of time that the backend is allowed to spend "pre-loading" data when it is initialized. |
| | | property.preload-time-limit.description=The pre-load process is used to pre-populate the database cache, so that it can be more quickly available when the server is processing requests. A duration of zero means there is no pre-load. |
| | | property.subordinate-indexes-enabled.synopsis=Indicates whether id2children and id2subtree indexes should be used for this backend. These indexes are used for constraining filtered searches to the search request's scope as well as for generating values for the hasSubordinates and numSubordinates virtual attributes. |
| | | property.subordinate-indexes-enabled.description=Subordinate indexing is enabled by default and should only be disabled for specialized use cases. A typical use case is where the backend is to be subjected to heavy add/delete load beneath the same parent entry such as when used as a session database. Disabling the subordinate indexes means that the numSubordinates and hasSubordinates virtual attributes will not be supported. |
| | | property.writability-mode.synopsis=Specifies the behavior that the backend should use when processing write operations. |
| | | property.writability-mode.syntax.enumeration.value.disabled.synopsis=Causes all write attempts to fail. |
| | | property.writability-mode.syntax.enumeration.value.enabled.synopsis=Allows write operations to be performed in that backend (if the requested operation is valid, the user has permission to perform the operation, the backend supports that type of write operation, and the global writability-mode property is also enabled). |
| | |
| | | index entry limit for the %s index |
| | | INFO_JEB_INDEX_FILTER_MATCHING_RULE_NOT_INDEXED_229=Matching rule %s is \ |
| | | disabled for the extensible index of the %s attribute |
| | | NOTICE_JEB_SUBORDINATE_INDEXES_DISABLED_230=The subordinate indexes have been \ |
| | | disabled for database backend %s |
| | | |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public synchronized boolean isConfigurationDeleteAcceptable( |
| | | public boolean isConfigurationDeleteAcceptable( |
| | | LocalDBIndexCfg cfg, List<Message> unacceptableReasons) |
| | | { |
| | | // TODO: validate more before returning true? |
| | |
| | | state = new State(databasePrefix + "_" + STATE_DATABASE_NAME, env, this); |
| | | state.open(); |
| | | |
| | | id2children = new Index(databasePrefix + "_" + ID2CHILDREN_DATABASE_NAME, |
| | | new ID2CIndexer(), state, |
| | | config.getIndexEntryLimit(), 0, true, |
| | | env,this); |
| | | id2children.open(); |
| | | |
| | | if(!id2children.isTrusted()) |
| | | if (config.isSubordinateIndexesEnabled()) |
| | | { |
| | | logError(NOTE_JEB_INDEX_ADD_REQUIRES_REBUILD.get( |
| | | id2children.getName())); |
| | | id2children = new Index(databasePrefix + "_" |
| | | + ID2CHILDREN_DATABASE_NAME, new ID2CIndexer(), state, |
| | | config.getIndexEntryLimit(), 0, true, env, this); |
| | | id2children.open(); |
| | | if (!id2children.isTrusted()) |
| | | { |
| | | logError(NOTE_JEB_INDEX_ADD_REQUIRES_REBUILD.get(id2children |
| | | .getName())); |
| | | } |
| | | |
| | | id2subtree = new Index(databasePrefix + "_" + ID2SUBTREE_DATABASE_NAME, |
| | | new ID2SIndexer(), state, config.getIndexEntryLimit(), 0, true, |
| | | env, this); |
| | | id2subtree.open(); |
| | | if (!id2subtree.isTrusted()) |
| | | { |
| | | logError(NOTE_JEB_INDEX_ADD_REQUIRES_REBUILD |
| | | .get(id2subtree.getName())); |
| | | } |
| | | } |
| | | |
| | | id2subtree = new Index(databasePrefix + "_" + ID2SUBTREE_DATABASE_NAME, |
| | | new ID2SIndexer(), state, |
| | | config.getIndexEntryLimit(), 0, true, |
| | | env, this); |
| | | id2subtree.open(); |
| | | |
| | | if(!id2subtree.isTrusted()) |
| | | else |
| | | { |
| | | logError(NOTE_JEB_INDEX_ADD_REQUIRES_REBUILD.get( |
| | | id2subtree.getName())); |
| | | // Use a null index and ensure that future attempts to use the real |
| | | // subordinate indexes will fail. |
| | | id2children = new NullIndex(databasePrefix + "_" |
| | | + ID2CHILDREN_DATABASE_NAME, new ID2CIndexer(), state, env, this); |
| | | if (!env.getConfig().getReadOnly()) |
| | | { |
| | | state.putIndexTrustState(null, id2children, false); |
| | | } |
| | | id2children.open(); // No-op |
| | | |
| | | id2subtree = new NullIndex(databasePrefix + "_" |
| | | + ID2SUBTREE_DATABASE_NAME, new ID2SIndexer(), state, env, this); |
| | | if (!env.getConfig().getReadOnly()) |
| | | { |
| | | state.putIndexTrustState(null, id2subtree, false); |
| | | } |
| | | id2subtree.open(); // No-op |
| | | |
| | | logError(NOTE_JEB_SUBORDINATE_INDEXES_DISABLED.get(backend |
| | | .getBackendID())); |
| | | } |
| | | |
| | | dn2uri = new DN2URI(databasePrefix + "_" + REFERRAL_DATABASE_NAME, |
| | |
| | | return count; |
| | | } |
| | | |
| | | /** |
| | | * Close cursors in the indexes of the context. |
| | | * |
| | | * @throws DatabaseException If a database error occurs. |
| | | */ |
| | | public void closeIndexCursors() throws DatabaseException { |
| | | id2children.closeCursor(); |
| | | id2subtree.closeCursor(); |
| | | for (AttributeIndex index : attrIndexMap.values()) |
| | | { |
| | | index.closeCursors(); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Get a list of the databases opened by the entryContainer. |
| | |
| | | dbList.add(dn2id); |
| | | dbList.add(id2entry); |
| | | dbList.add(dn2uri); |
| | | dbList.add(id2children); |
| | | dbList.add(id2subtree); |
| | | if (config.isSubordinateIndexesEnabled()) |
| | | { |
| | | dbList.add(id2children); |
| | | dbList.add(id2subtree); |
| | | } |
| | | dbList.add(state); |
| | | |
| | | for(AttributeIndex index : attrIndexMap.values()) |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public synchronized boolean isConfigurationChangeAcceptable( |
| | | public boolean isConfigurationChangeAcceptable( |
| | | LocalDBBackendCfg cfg, List<Message> unacceptableReasons) |
| | | { |
| | | // This is always true because only all config attributes used |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public synchronized ConfigChangeResult applyConfigurationChange( |
| | | LocalDBBackendCfg cfg) |
| | | public ConfigChangeResult applyConfigurationChange(LocalDBBackendCfg cfg) |
| | | { |
| | | boolean adminActionRequired = false; |
| | | ArrayList<Message> messages = new ArrayList<Message>(); |
| | | |
| | | if(config.getIndexEntryLimit() != cfg.getIndexEntryLimit()) |
| | | exclusiveLock.lock(); |
| | | try |
| | | { |
| | | if(id2children.setIndexEntryLimit(cfg.getIndexEntryLimit())) |
| | | if (config.isSubordinateIndexesEnabled() != cfg |
| | | .isSubordinateIndexesEnabled()) |
| | | { |
| | | adminActionRequired = true; |
| | | Message message = |
| | | NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get( |
| | | id2children.getName()); |
| | | messages.add(message); |
| | | if (cfg.isSubordinateIndexesEnabled()) |
| | | { |
| | | // Re-enabling subordinate indexes. |
| | | id2children = new Index(databasePrefix + "_" |
| | | + ID2CHILDREN_DATABASE_NAME, new ID2CIndexer(), state, |
| | | config.getIndexEntryLimit(), 0, true, env, this); |
| | | id2children.open(); |
| | | if (!id2children.isTrusted()) |
| | | { |
| | | logError(NOTE_JEB_INDEX_ADD_REQUIRES_REBUILD.get(id2children |
| | | .getName())); |
| | | } |
| | | |
| | | id2subtree = new Index(databasePrefix + "_" +ID2SUBTREE_DATABASE_NAME, |
| | | new ID2SIndexer(), state, config.getIndexEntryLimit(), 0, true, |
| | | env, this); |
| | | id2subtree.open(); |
| | | if (!id2subtree.isTrusted()) |
| | | { |
| | | logError(NOTE_JEB_INDEX_ADD_REQUIRES_REBUILD |
| | | .get(id2subtree.getName())); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | // Disabling subordinate indexes. Use a null index and ensure that |
| | | // future attempts to use the real indexes will fail. |
| | | id2children.close(); |
| | | id2children = new NullIndex(databasePrefix + "_" |
| | | + ID2CHILDREN_DATABASE_NAME, new ID2CIndexer(), state, env, this); |
| | | state.putIndexTrustState(null, id2children, false); |
| | | id2children.open(); // No-op |
| | | |
| | | id2subtree.close(); |
| | | id2subtree = new NullIndex(databasePrefix + "_" |
| | | + ID2SUBTREE_DATABASE_NAME, new ID2SIndexer(), state, env, this); |
| | | state.putIndexTrustState(null, id2subtree, false); |
| | | id2subtree.open(); // No-op |
| | | |
| | | logError(NOTE_JEB_SUBORDINATE_INDEXES_DISABLED |
| | | .get(cfg.getBackendId())); |
| | | } |
| | | } |
| | | |
| | | if(id2subtree.setIndexEntryLimit(cfg.getIndexEntryLimit())) |
| | | if (config.getIndexEntryLimit() != cfg.getIndexEntryLimit()) |
| | | { |
| | | adminActionRequired = true; |
| | | Message message = |
| | | NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get( |
| | | id2subtree.getName()); |
| | | messages.add(message); |
| | | if (id2children.setIndexEntryLimit(cfg.getIndexEntryLimit())) |
| | | { |
| | | adminActionRequired = true; |
| | | Message message = NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD |
| | | .get(id2children.getName()); |
| | | messages.add(message); |
| | | } |
| | | |
| | | if (id2subtree.setIndexEntryLimit(cfg.getIndexEntryLimit())) |
| | | { |
| | | adminActionRequired = true; |
| | | Message message = NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD |
| | | .get(id2subtree.getName()); |
| | | messages.add(message); |
| | | } |
| | | } |
| | | |
| | | DataConfig entryDataConfig = new DataConfig(cfg.isEntriesCompressed(), |
| | | cfg.isCompactEncoding(), rootContainer.getCompressedSchema()); |
| | | id2entry.setDataConfig(entryDataConfig); |
| | | |
| | | this.config = cfg; |
| | | } |
| | | catch (DatabaseException e) |
| | | { |
| | | messages.add(Message.raw(stackTraceToSingleLineString(e))); |
| | | return new ConfigChangeResult(DirectoryServer.getServerErrorResultCode(), |
| | | false, messages); |
| | | } |
| | | finally |
| | | { |
| | | exclusiveLock.unlock(); |
| | | } |
| | | |
| | | DataConfig entryDataConfig = |
| | | new DataConfig(cfg.isEntriesCompressed(), |
| | | cfg.isCompactEncoding(), |
| | | rootContainer.getCompressedSchema()); |
| | | id2entry.setDataConfig(entryDataConfig); |
| | | |
| | | this.config = cfg; |
| | | return new ConfigChangeResult(ResultCode.SUCCESS, |
| | | adminActionRequired, messages); |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * Copyright 2011 ForgeRock AS |
| | | */ |
| | | |
| | | package org.opends.server.backends.jeb; |
| | | |
| | | |
| | | |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | import org.opends.server.backends.jeb.importLDIF.ImportIDSet; |
| | | import org.opends.server.types.ConditionResult; |
| | | import org.opends.server.types.DirectoryException; |
| | | import org.opends.server.types.Entry; |
| | | import org.opends.server.types.Modification; |
| | | |
| | | import com.sleepycat.je.*; |
| | | |
| | | |
| | | |
| | | /** |
| | | * A null index which replaces id2children and id2subtree when they have been |
| | | * disabled. |
| | | */ |
| | | final class NullIndex extends Index |
| | | { |
| | | |
| | | /** |
| | | * Create a new null index object. |
| | | * |
| | | * @param name |
| | | * The name of the index database within the entryContainer. |
| | | * @param indexer |
| | | * The indexer object to construct index keys from LDAP attribute |
| | | * values. |
| | | * @param state |
| | | * The state database to persist index state info. |
| | | * @param env |
| | | * The JE Environemnt |
| | | * @param entryContainer |
| | | * The database entryContainer holding this index. |
| | | * @throws DatabaseException |
| | | * If an error occurs in the JE database. |
| | | */ |
| | | public NullIndex(String name, Indexer indexer, State state, Environment env, |
| | | EntryContainer entryContainer) throws DatabaseException |
| | | { |
| | | super(name, indexer, state, 0, 0, false, env, entryContainer); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean insertID(IndexBuffer buffer, byte[] keyBytes, EntryID entryID) |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean insertID(Transaction txn, DatabaseEntry key, EntryID entryID) |
| | | throws DatabaseException |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void insert(DatabaseEntry key, ImportIDSet importIdSet, |
| | | DatabaseEntry data) throws DatabaseException |
| | | { |
| | | // Do nothing. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void delete(DatabaseEntry key, ImportIDSet importIdSet, |
| | | DatabaseEntry data) throws DatabaseException |
| | | { |
| | | // Do nothing. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public synchronized boolean insert(ImportIDSet importIDSet, |
| | | Set<byte[]> keySet, DatabaseEntry keyData, DatabaseEntry data) |
| | | throws DatabaseException |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | void updateKey(Transaction txn, DatabaseEntry key, EntryIDSet deletedIDs, |
| | | EntryIDSet addedIDs) throws DatabaseException |
| | | { |
| | | // Do nothing. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean removeID(IndexBuffer buffer, byte[] keyBytes, EntryID entryID) |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void removeID(Transaction txn, DatabaseEntry key, EntryID entryID) |
| | | throws DatabaseException |
| | | { |
| | | // Do nothing. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void delete(Transaction txn, Set<byte[]> keySet, EntryID entryID) |
| | | throws DatabaseException |
| | | { |
| | | // Do nothing. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void delete(IndexBuffer buffer, byte[] keyBytes) |
| | | { |
| | | // Do nothing. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public ConditionResult containsID(Transaction txn, DatabaseEntry key, |
| | | EntryID entryID) throws DatabaseException |
| | | { |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public EntryIDSet readKey(DatabaseEntry key, Transaction txn, |
| | | LockMode lockMode) |
| | | { |
| | | return new EntryIDSet(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void writeKey(Transaction txn, DatabaseEntry key, |
| | | EntryIDSet entryIDList) throws DatabaseException |
| | | { |
| | | // Do nothing. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public EntryIDSet readRange(byte[] lower, byte[] upper, |
| | | boolean lowerIncluded, boolean upperIncluded) |
| | | { |
| | | return new EntryIDSet(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public int getEntryLimitExceededCount() |
| | | { |
| | | return 0; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void closeCursor() throws DatabaseException |
| | | { |
| | | // Do nothing. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean addEntry(IndexBuffer buffer, EntryID entryID, Entry entry) |
| | | throws DatabaseException, DirectoryException |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean addEntry(Transaction txn, EntryID entryID, Entry entry) |
| | | throws DatabaseException, DirectoryException |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void removeEntry(IndexBuffer buffer, EntryID entryID, Entry entry) |
| | | throws DatabaseException, DirectoryException |
| | | { |
| | | // Do nothing. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void removeEntry(Transaction txn, EntryID entryID, Entry entry) |
| | | throws DatabaseException, DirectoryException |
| | | { |
| | | // Do nothing. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void modifyEntry(Transaction txn, EntryID entryID, Entry oldEntry, |
| | | Entry newEntry, List<Modification> mods) throws DatabaseException |
| | | { |
| | | // Do nothing. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void modifyEntry(IndexBuffer buffer, EntryID entryID, Entry oldEntry, |
| | | Entry newEntry, List<Modification> mods) throws DatabaseException |
| | | { |
| | | // Do nothing. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean setIndexEntryLimit(int indexEntryLimit) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public int getIndexEntryLimit() |
| | | { |
| | | return 0; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public synchronized void setTrusted(Transaction txn, boolean trusted) |
| | | throws DatabaseException |
| | | { |
| | | // Do nothing. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public synchronized boolean isTrusted() |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public synchronized boolean isRebuildRunning() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public synchronized void setRebuildStatus(boolean rebuildRunning) |
| | | { |
| | | // Do nothing. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean getMaintainCount() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void open() throws DatabaseException |
| | | { |
| | | // Do nothing. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | synchronized void close() throws DatabaseException |
| | | { |
| | | // Do nothing. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | protected OperationStatus put(Transaction txn, DatabaseEntry key, |
| | | DatabaseEntry data) throws DatabaseException |
| | | { |
| | | return OperationStatus.SUCCESS; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | protected OperationStatus read(Transaction txn, DatabaseEntry key, |
| | | DatabaseEntry data, LockMode lockMode) throws DatabaseException |
| | | { |
| | | return OperationStatus.SUCCESS; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | protected OperationStatus insert(Transaction txn, DatabaseEntry key, |
| | | DatabaseEntry data) throws DatabaseException |
| | | { |
| | | return OperationStatus.SUCCESS; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | protected OperationStatus delete(Transaction txn, DatabaseEntry key) |
| | | throws DatabaseException |
| | | { |
| | | return OperationStatus.SUCCESS; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public Cursor openCursor(Transaction txn, CursorConfig cursorConfig) |
| | | throws DatabaseException |
| | | { |
| | | // FIXME: this will be called during verify and dbtest. |
| | | throw new IllegalStateException(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public long getRecordCount() throws DatabaseException |
| | | { |
| | | return 0; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public PreloadStats preload(PreloadConfig config) throws DatabaseException |
| | | { |
| | | return new PreloadStats(); |
| | | } |
| | | |
| | | } |
| | |
| | | import java.util.concurrent.atomic.AtomicLong; |
| | | import java.util.*; |
| | | import java.io.File; |
| | | import java.io.FilenameFilter; |
| | | import org.opends.server.monitors.DatabaseEnvironmentMonitor; |
| | | import org.opends.server.types.DebugLogLevel; |
| | | import org.opends.server.types.DN; |
| | |
| | | } |
| | | |
| | | /** |
| | | * Synchronously invokes the cleaner on the database environment then forces a |
| | | * checkpoint to delete the log files that are no longer in use. |
| | | * |
| | | * @throws DatabaseException If an error occurs while cleaning the database |
| | | * environment. |
| | | */ |
| | | private void cleanDatabase() |
| | | throws DatabaseException |
| | | { |
| | | Message message; |
| | | |
| | | FilenameFilter filenameFilter = new FilenameFilter() |
| | | { |
| | | public boolean accept(File d, String name) |
| | | { |
| | | return name.endsWith(".jdb"); |
| | | } |
| | | }; |
| | | |
| | | File backendDirectory = env.getHome(); |
| | | int beforeLogfileCount = backendDirectory.list(filenameFilter).length; |
| | | |
| | | message = NOTE_JEB_CLEAN_DATABASE_START.get( |
| | | beforeLogfileCount, backendDirectory.getPath()); |
| | | logError(message); |
| | | |
| | | int currentCleaned = 0; |
| | | int totalCleaned = 0; |
| | | while ((currentCleaned = env.cleanLog()) > 0) |
| | | { |
| | | totalCleaned += currentCleaned; |
| | | } |
| | | |
| | | message = NOTE_JEB_CLEAN_DATABASE_MARKED.get(totalCleaned); |
| | | logError(message); |
| | | |
| | | if (totalCleaned > 0) |
| | | { |
| | | CheckpointConfig force = new CheckpointConfig(); |
| | | force.setForce(true); |
| | | env.checkpoint(force); |
| | | } |
| | | |
| | | int afterLogfileCount = backendDirectory.list(filenameFilter).length; |
| | | |
| | | message = NOTE_JEB_CLEAN_DATABASE_FINISH.get(afterLogfileCount); |
| | | logError(message); |
| | | |
| | | } |
| | | |
| | | /** |
| | | * Close the root entryContainer. |
| | | * |
| | | * @throws DatabaseException If an error occurs while attempting to close |
| | |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Portions copyright 2011 ForgeRock AS |
| | | */ |
| | | package org.opends.server.backends.jeb; |
| | | |
| | | import org.opends.server.loggers.debug.DebugTracer; |
| | | import static org.opends.server.loggers.debug.DebugLogger.getTracer; |
| | | import org.opends.server.util.StaticUtils; |
| | | import com.sleepycat.je.*; |
| | | |
| | |
| | | */ |
| | | public class State extends DatabaseContainer |
| | | { |
| | | /** |
| | | * The tracer object for the debug logger. |
| | | */ |
| | | private static final DebugTracer TRACER = getTracer(); |
| | | |
| | | private static final byte[] falseBytes = new byte[]{0x00}; |
| | | private static final byte[] trueBytes = new byte[]{0x01}; |
| | | |
| | |
| | | * |
| | | * |
| | | * Copyright 2006-2010 Sun Microsystems, Inc. |
| | | * Portions copyright 2011 ForgeRock AS |
| | | */ |
| | | package org.opends.server.backends.jeb; |
| | | import org.opends.messages.Message; |
| | |
| | | import org.opends.server.types.*; |
| | | |
| | | import static org.opends.messages.JebMessages.*; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | | import java.util.HashMap; |
| | |
| | | if (completeList.isEmpty() && cleanList.isEmpty()) |
| | | { |
| | | verifyDN2ID = true; |
| | | verifyID2Children = true; |
| | | verifyID2Subtree = true; |
| | | if (rootContainer.getConfiguration().isSubordinateIndexesEnabled()) |
| | | { |
| | | verifyID2Children = true; |
| | | verifyID2Subtree = true; |
| | | } |
| | | attrIndexList.addAll(entryContainer.getAttributeIndexes()); |
| | | } |
| | | else |
| | |
| | | } |
| | | else if (lowerName.equals("id2children")) |
| | | { |
| | | verifyID2Children = true; |
| | | if (rootContainer.getConfiguration().isSubordinateIndexesEnabled()) |
| | | { |
| | | verifyID2Children = true; |
| | | } |
| | | else |
| | | { |
| | | Message msg = NOTE_JEB_SUBORDINATE_INDEXES_DISABLED |
| | | .get(rootContainer.getConfiguration().getBackendId()); |
| | | throw new JebException(msg); |
| | | } |
| | | } |
| | | else if (lowerName.equals("id2subtree")) |
| | | { |
| | | verifyID2Subtree = true; |
| | | if (rootContainer.getConfiguration().isSubordinateIndexesEnabled()) |
| | | { |
| | | verifyID2Subtree = true; |
| | | } |
| | | else |
| | | { |
| | | Message msg = NOTE_JEB_SUBORDINATE_INDEXES_DISABLED |
| | | .get(rootContainer.getConfiguration().getBackendId()); |
| | | throw new JebException(msg); |
| | | } |
| | | } |
| | | else if(lowerName.startsWith("vlv.")) |
| | | { |
| | |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Portions copyright 2011 ForgeRock AS |
| | | */ |
| | | package org.opends.server.admin; |
| | | |
| | | import static org.opends.server.util.ServerConstants.*; |
| | | |
| | | import java.io.File; |
| | | import java.io.FilenameFilter; |
| | | import java.lang.reflect.Method; |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | | import java.util.Collection; |
| | |
| | | @Test(dataProvider="enumrateManageObjectDefns") |
| | | public void validateConfigObjectDefinitions(AbstractManagedObjectDefinition<?, ?> objectDef) { |
| | | String objName = objectDef.getName(); |
| | | StringBuilder errors = new StringBuilder(); |
| | | StringBuilder errors = new StringBuilder(); |
| | | Collection<PropertyDefinition<?>> allDefinitions = |
| | | objectDef.getAllPropertyDefinitions(); |
| | | |
| | |
| | | } |
| | | ObjectClass configObjectClass = DirectoryServer.getSchema().getObjectClass(ldapObjectclassName.toLowerCase());; |
| | | |
| | | for (PropertyDefinition<?> propDef: allDefinitions) { |
| | | for (PropertyDefinition<?> propDef: allDefinitions) { |
| | | validatePropertyDefinition(objectDef, configObjectClass, propDef, errors); |
| | | } |
| | | |
| | |
| | | // Exceptions to properties ending in -enabled being exactly 'enabled'. |
| | | private static final List<String> ENABLED_PROPERTY_EXCEPTIONS = |
| | | Arrays.asList(new String[]{ |
| | | "index-filter-analyzer-enabled" |
| | | "index-filter-analyzer-enabled", |
| | | "subordinate-indexes-enabled" |
| | | // e.g. "prop-name-ending-with-enabled" |
| | | }); |
| | | |
| | |
| | | } |
| | | |
| | | // It's redundant for properties to be prefixed with the name of their objecty |
| | | if (propName.startsWith(objName) && !propName.equals(objName) && |
| | | if (propName.startsWith(objName) && !propName.equals(objName) && |
| | | !OBJECT_PREFIX_PROPERTY_EXCEPTIONS.contains(propName)) |
| | | { |
| | | errors.append("The " + propName + " property on config object " + objName + |