From da62427f3da608acc65cea059cff0232d7980727 Mon Sep 17 00:00:00 2001
From: Jean-Noel Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Thu, 04 Dec 2014 17:02:39 +0000
Subject: [PATCH] OPENDJ-1602 (CR-5566) New pluggable storage based backend
---
opendj3-server-dev/src/server/org/opends/server/authorization/dseecompat/AciHandler.java | 150 +++++-------------------
opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryContainer.java | 101 ++++++----------
opendj3-server-dev/src/server/org/opends/server/backends/pluggable/SuffixContainer.java | 20 +++
opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryIDSetSorter.java | 37 +----
4 files changed, 105 insertions(+), 203 deletions(-)
diff --git a/opendj3-server-dev/src/server/org/opends/server/authorization/dseecompat/AciHandler.java b/opendj3-server-dev/src/server/org/opends/server/authorization/dseecompat/AciHandler.java
index 063e5b7..b89d0f7 100644
--- a/opendj3-server-dev/src/server/org/opends/server/authorization/dseecompat/AciHandler.java
+++ b/opendj3-server-dev/src/server/org/opends/server/authorization/dseecompat/AciHandler.java
@@ -43,7 +43,7 @@
import org.opends.server.api.AccessControlHandler;
import org.opends.server.api.ClientConnection;
import org.opends.server.api.ConfigHandler;
-import org.opends.server.backends.jeb.EntryContainer;
+import org.opends.server.backends.pluggable.SuffixContainer;
import org.opends.server.controls.GetEffectiveRightsRequestControl;
import org.opends.server.core.*;
import org.opends.server.protocols.internal.InternalClientConnection;
@@ -64,8 +64,7 @@
import static org.opends.server.util.StaticUtils.*;
/**
- * The AciHandler class performs the main processing for the dseecompat
- * package.
+ * The AciHandler class performs the main processing for the dseecompat package.
*/
public final class AciHandler extends
AccessControlHandler<DseeCompatAccessControlHandlerCfg>
@@ -80,8 +79,7 @@
* String used to indicate that the evaluating ACI had a all user
* attributes targetattr match (targetattr="*").
*/
- public static final String ALL_USER_ATTRS_MATCHED =
- "allUserAttrsMatched";
+ public static final String ALL_USER_ATTRS_MATCHED = "allUserAttrsMatched";
/**
* String used to save the original authorization entry in an
@@ -89,25 +87,16 @@
*/
public static final String ORIG_AUTH_ENTRY = "origAuthorizationEntry";
- /**
- * Attribute type corresponding to "aci" attribute.
- */
+ /** Attribute type corresponding to "aci" attribute. */
static AttributeType aciType;
- /**
- * Attribute type corresponding to global "ds-cfg-global-aci"
- * attribute.
- */
+ /** Attribute type corresponding to global "ds-cfg-global-aci" attribute. */
static AttributeType globalAciType;
- /**
- * Attribute type corresponding to "debugsearchindex" attribute.
- */
+ /** Attribute type corresponding to "debugsearchindex" attribute. */
private static AttributeType debugSearchIndex;
- /**
- * DN corresponding to "debugsearchindex" attribute type.
- */
+ /** DN corresponding to "debugsearchindex" attribute type. */
private static DN debugSearchIndexDN;
/**
@@ -132,7 +121,7 @@
{
aciType = getAttributeType("aci");
globalAciType = getAttributeType(ATTR_AUTHZ_GLOBAL_ACI);
- debugSearchIndex = getAttributeType(EntryContainer.ATTR_DEBUG_SEARCH_INDEX);
+ debugSearchIndex = getAttributeType(SuffixContainer.ATTR_DEBUG_SEARCH_INDEX);
refAttrType = getAttributeType(ATTR_REFERRAL_URL);
try
@@ -157,35 +146,23 @@
- /**
- * The list that holds that ACIs keyed by the DN of the entry holding
- * the ACI.
- */
+ /** The list that holds that ACIs keyed by the DN of the entry holding the ACI. */
private AciList aciList;
/**
* The listener that handles ACI changes caused by LDAP operations,
- * ACI decode failure alert logging and backend initialization ACI
- * list adjustment.
+ * ACI decode failure alert logging and backend initialization ACI list adjustment.
*/
private AciListenerManager aciListenerMgr;
-
-
- /**
- * Creates a new DSEE-compatible access control handler.
- */
+ /** Creates a new DSEE-compatible access control handler. */
public AciHandler()
{
// No implementation required. All initialization should be done in
// the intializeAccessControlHandler method.
}
-
-
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public void filterEntry(Operation operation,
SearchResultEntry unfilteredEntry, SearchResultEntry filteredEntry)
@@ -211,12 +188,8 @@
}
}
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
+ /** {@inheritDoc} */
+ @Override
public void finalizeAccessControlHandler()
{
aciListenerMgr.finalizeListenerManager();
@@ -224,12 +197,8 @@
DirectoryServer.deregisterSupportedControl(OID_GET_EFFECTIVE_RIGHTS);
}
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
+ /** {@inheritDoc} */
+ @Override
public void initializeAccessControlHandler(
DseeCompatAccessControlHandlerCfg configuration)
throws ConfigException, InitializationException
@@ -243,11 +212,7 @@
DirectoryServer.registerSupportedControl(OID_GET_EFFECTIVE_RIGHTS);
}
-
-
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public boolean isAllowed(DN entryDN, Operation op, Control control)
throws DirectoryException
@@ -286,11 +251,7 @@
return true;
}
-
-
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public boolean isAllowed(ExtendedOperation operation)
{
@@ -305,33 +266,19 @@
return accessAllowed(container);
}
-
-
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public boolean isAllowed(LocalBackendAddOperation operation)
throws DirectoryException
{
- AciContainer container =
- new AciLDAPOperationContainer(operation, ACI_ADD);
- if (!isAllowed(container, operation))
- {
- return false;
- }
-
- // LDAP add needs a verify ACI syntax step in case any
- // "aci" attribute types are being added.
- return verifySyntax(operation.getEntryToAdd(), operation, container
- .getClientDN());
+ AciContainer container = new AciLDAPOperationContainer(operation, ACI_ADD);
+ return isAllowed(container, operation)
+ // LDAP add needs a verify ACI syntax step in case any
+ // "aci" attribute types are being added.
+ && verifySyntax(operation.getEntryToAdd(), operation, container.getClientDN());
}
-
-
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public boolean isAllowed(BindOperation bindOperation)
{
@@ -428,9 +375,8 @@
// original entry DN has export access.
if (rdnChangesAllowed && newSuperiorDN != null)
{
- AciContainer container =
- new AciLDAPOperationContainer(operation, ACI_EXPORT, operation
- .getOriginalEntry());
+ AciContainer container = new AciLDAPOperationContainer(
+ operation, ACI_EXPORT, operation.getOriginalEntry());
if (!oldRDN.equals(newRDN))
{
// The RDNs are not equal, skip the proxy check since it was
@@ -442,11 +388,7 @@
return rdnChangesAllowed;
}
-
-
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public boolean isAllowed(LocalBackendModifyOperation operation)
throws DirectoryException
@@ -455,11 +397,7 @@
return aciCheckMods(container, operation, skipAccessCheck(operation));
}
-
-
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public boolean isAllowed(SearchOperation searchOperation)
{
@@ -467,11 +405,7 @@
return true;
}
-
-
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public boolean isAllowed(Operation operation, Entry entry,
SearchFilter filter) throws DirectoryException
@@ -486,14 +420,9 @@
return testFilter(container, filter);
}
-
-
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
- public boolean mayProxy(Entry proxyUser, Entry proxiedUser,
- Operation op)
+ public boolean mayProxy(Entry proxyUser, Entry proxiedUser, Operation op)
{
if (skipAccessCheck(proxyUser))
{
@@ -508,14 +437,9 @@
return accessAllowedEntry(container);
}
-
-
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
- public boolean maySend(DN dn, Operation operation,
- SearchResultReference reference)
+ public boolean maySend(DN dn, Operation operation, SearchResultReference reference)
{
if (skipAccessCheck(operation))
{
@@ -541,11 +465,7 @@
return accessAllowed(container);
}
-
-
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public boolean maySend(Operation operation, SearchResultEntry entry)
{
diff --git a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryContainer.java b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryContainer.java
index 1997c79..e5058a5 100644
--- a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryContainer.java
+++ b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryContainer.java
@@ -90,8 +90,6 @@
private static final String REFERRAL_DATABASE_NAME = REFERRAL_INDEX_NAME;
/** The name of the state database. */
private static final String STATE_DATABASE_NAME = STATE_INDEX_NAME;
- /** The attribute used to return a search index debug string to the client. */
- public static final String ATTR_DEBUG_SEARCH_INDEX = "debugsearchindex";
/** The attribute index configuration manager. */
private final AttributeJEIndexCfgManager attributeJEIndexCfgManager;
@@ -769,8 +767,7 @@
searchOperation.setResultCode(ResultCode.UNAVAILABLE_CRITICAL_EXTENSION);
return;
}
- VLVRequestControl vlvRequest = searchOperation
- .getRequestControl(VLVRequestControl.DECODER);
+ VLVRequestControl vlvRequest = searchOperation.getRequestControl(VLVRequestControl.DECODER);
if (vlvRequest != null && pageRequest != null)
{
@@ -889,8 +886,7 @@
{
LocalizableMessage message = ERR_JEB_SEARCH_NO_SUCH_OBJECT.get(aBaseDN);
DN matchedDN = getMatchedDN(aBaseDN);
- throw new DirectoryException(ResultCode.NO_SUCH_OBJECT,
- message, matchedDN, null);
+ throw new DirectoryException(ResultCode.NO_SUCH_OBJECT, message, matchedDN, null);
}
DatabaseEntry baseIDData = baseID.getDatabaseEntry();
@@ -940,11 +936,11 @@
else
{
/*
- There is no sort key associated with the sort control. Since it
- came here it means that the criticality is false so let the
- server return all search results unsorted and include the
- sortKeyResponseControl in the searchResultDone message.
- */
+ * There is no sort key associated with the sort control. Since it
+ * came here it means that the criticality is false so let the
+ * server return all search results unsorted and include the
+ * sortKeyResponseControl in the searchResultDone message.
+ */
searchOperation.addResponseControl(new ServerSideSortResponseControl(NO_SUCH_ATTRIBUTE, null));
}
}
@@ -1018,8 +1014,7 @@
if (sortRequest.isCritical())
{
LocalizableMessage message = ERR_JEB_SEARCH_CANNOT_SORT_UNINDEXED.get();
- throw new DirectoryException(
- ResultCode.UNAVAILABLE_CRITICAL_EXTENSION, message);
+ throw new DirectoryException(ResultCode.UNAVAILABLE_CRITICAL_EXTENSION, message);
}
}
@@ -1048,7 +1043,6 @@
private void searchNotIndexed(SearchOperation searchOperation, PagedResultsControl pageRequest)
throws DirectoryException, CanceledOperationException
{
- EntryCache<?> entryCache = DirectoryServer.getEntryCache();
DN aBaseDN = searchOperation.getBaseDN();
SearchScope searchScope = searchOperation.getScope();
boolean manageDsaIT = isManageDsaITOperation(searchOperation);
@@ -1171,20 +1165,8 @@
|| findDNKeyParent(key.getData(), 0, key.getSize()) == baseDNKey.length;
if (isInScope)
{
- // Try the entry cache first.
- final Entry cacheEntry = entryCache.getEntry(backend, entryID.longValue());
-
- final Entry entry;
- if (cacheEntry != null)
- {
- entry = cacheEntry;
- }
- else
- {
- entry = id2entry.get(null, entryID, LockMode.DEFAULT);
- }
-
// Process the candidate entry.
+ final Entry entry = getEntry(entryID);
if (entry != null)
{
lookthroughCount++;
@@ -1238,6 +1220,28 @@
}
}
+ /** {@inheritDoc} */
+ @Override
+ public Entry getEntry(EntryID entryID) throws DirectoryException
+ {
+ // Try the entry cache first.
+ final EntryCache entryCache = getEntryCache();
+ final Entry cacheEntry = entryCache.getEntry(backend, entryID.longValue());
+ if (cacheEntry != null)
+ {
+ return cacheEntry;
+ }
+
+ final Entry entry = id2entry.get(null, entryID, LockMode.DEFAULT);
+ if (entry != null)
+ {
+ // Put the entry in the cache making sure not to overwrite a newer copy
+ // that may have been inserted since the time we read the cache.
+ entryCache.putEntryIfAbsent(entry, backend, entryID.longValue());
+ }
+ return entry;
+ }
+
/**
* We were able to obtain a set of candidate entry IDs for the
* search from the indexes.
@@ -1266,7 +1270,6 @@
PagedResultsControl pageRequest)
throws DirectoryException, CanceledOperationException
{
- EntryCache<?> entryCache = DirectoryServer.getEntryCache();
SearchScope searchScope = searchOperation.getScope();
DN aBaseDN = searchOperation.getBaseDN();
boolean manageDsaIT = isManageDsaITOperation(searchOperation);
@@ -1315,49 +1318,27 @@
{
final EntryID id = it.next();
- // Try the entry cache first.
Entry entry;
- Entry cacheEntry = entryCache.getEntry(backend, id.longValue());
- if (cacheEntry == null)
+ try
{
- // Fetch the candidate entry from the database.
- try
- {
- entry = id2entry.get(null, id, LockMode.DEFAULT);
- }
- catch (Exception e)
- {
- logger.traceException(e);
- continue;
- }
+ entry = getEntry(id);
}
- else
+ catch (Exception e)
{
- entry = cacheEntry;
+ logger.traceException(e);
+ continue;
}
// Process the candidate entry.
if (entry != null)
{
- boolean isInScope = isInScope(candidatesAreInScope, searchScope, aBaseDN, entry);
-
- // Put this entry in the cache if it did not come from the cache.
- if (cacheEntry == null)
- {
- // Put the entry in the cache making sure not to overwrite
- // a newer copy that may have been inserted since the time
- // we read the cache.
- entryCache.putEntryIfAbsent(entry, backend, id.longValue());
- }
-
// Filter the entry if it is in scope.
- if (isInScope
+ if (isInScope(candidatesAreInScope, searchScope, aBaseDN, entry)
&& (manageDsaIT || entry.getReferralURLs() == null)
&& searchOperation.getFilter().matchesEntry(entry))
{
- if (pageRequest != null &&
- searchOperation.getEntriesSent() ==
- pageRequest.getSize())
+ if (pageRequest != null
+ && searchOperation.getEntriesSent() == pageRequest.getSize())
{
// The current page is full.
// Set the cookie to remember where we were.
@@ -1384,8 +1365,8 @@
// Before we return success from the search we must ensure the base entry
// exists. However, if we have returned at least one entry or subordinate
// reference it implies the base does exist, so we can omit the check.
- if (searchOperation.getEntriesSent() == 0 &&
- searchOperation.getReferencesSent() == 0)
+ if (searchOperation.getEntriesSent() == 0
+ && searchOperation.getReferencesSent() == 0)
{
// Fetch the base entry if it exists.
Entry baseEntry = fetchBaseEntry(aBaseDN, searchScope);
diff --git a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryIDSetSorter.java b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryIDSetSorter.java
index 2d5a7ec..fb127d6 100644
--- a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryIDSetSorter.java
+++ b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryIDSetSorter.java
@@ -35,6 +35,7 @@
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.SearchScope;
+import org.opends.server.backends.pluggable.SuffixContainer;
import org.opends.server.controls.VLVRequestControl;
import org.opends.server.controls.VLVResponseControl;
import org.opends.server.core.DirectoryServer;
@@ -42,8 +43,6 @@
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.types.*;
-import com.sleepycat.je.LockMode;
-
import static org.opends.messages.JebMessages.*;
import static org.opends.server.util.StaticUtils.*;
@@ -57,8 +56,7 @@
* Creates a new entry ID set which is a sorted representation of the provided
* set using the given sort order.
*
- * @param entryContainer The entry container with which the ID list is
- * associated.
+ * @param suffixContainer The suffix container with which the ID list is associated.
* @param entryIDSet The entry ID set to be sorted.
* @param searchOperation The search operation being processed.
* @param sortOrder The sort order to use for the entry ID set.
@@ -70,7 +68,7 @@
*
* @throws DirectoryException If an error occurs while performing the sort.
*/
- public static EntryIDSet sort(EntryContainer entryContainer,
+ public static EntryIDSet sort(SuffixContainer suffixContainer,
EntryIDSet entryIDSet,
SearchOperation searchOperation,
SortOrder sortOrder,
@@ -82,7 +80,6 @@
return new EntryIDSet();
}
- ID2Entry id2Entry = entryContainer.getID2Entry();
DN baseDN = searchOperation.getBaseDN();
SearchScope scope = searchOperation.getScope();
SearchFilter filter = searchOperation.getFilter();
@@ -92,15 +89,11 @@
{
try
{
- Entry e = id2Entry.get(null, id, LockMode.DEFAULT);
-
- if ((! e.matchesBaseAndScope(baseDN, scope)) ||
- (! filter.matchesEntry(e)))
+ Entry e = suffixContainer.getEntry(id);
+ if (e.matchesBaseAndScope(baseDN, scope) && filter.matchesEntry(e))
{
- continue;
+ sortMap.put(new SortValues(id, e, sortOrder), id);
}
-
- sortMap.put(new SortValues(id, e, sortOrder), id);
}
catch (Exception e)
{
@@ -111,8 +104,7 @@
// See if there is a VLV request to further pare down the set of results,
- // and if there is where it should be processed by offset or assertion
- // value.
+ // and if there is where it should be processed by offset or assertion value.
long[] sortedIDs;
if (vlvRequest != null)
{
@@ -124,8 +116,7 @@
int targetOffset = vlvRequest.getOffset();
if (targetOffset < 0)
{
- // The client specified a negative target offset. This should never
- // be allowed.
+ // The client specified a negative target offset. This should never be allowed.
searchOperation.addResponseControl(
new VLVResponseControl(targetOffset, sortMap.size(),
LDAPResultCode.OFFSET_RANGE_ERROR));
@@ -167,10 +158,8 @@
int treePos = 0;
int arrayPos = 0;
- Iterator<EntryID> idIterator = sortMap.values().iterator();
- while (idIterator.hasNext())
+ for (EntryID id : sortMap.values())
{
- EntryID id = idIterator.next();
if (treePos++ < startPos)
{
continue;
@@ -206,11 +195,8 @@
int includedAfterCount = 0;
int listSize = 0;
LinkedList<EntryID> idList = new LinkedList<EntryID>();
- Iterator<Map.Entry<SortValues,EntryID>> mapIterator =
- sortMap.entrySet().iterator();
- while (mapIterator.hasNext())
+ for (Map.Entry<SortValues, EntryID> entry : sortMap.entrySet())
{
- Map.Entry<SortValues,EntryID> entry = mapIterator.next();
SortValues sortValues = entry.getKey();
EntryID id = entry.getValue();
@@ -226,7 +212,7 @@
}
else
{
- targetFound = (sortValues.compareTo(assertionValue) >= 0);
+ targetFound = sortValues.compareTo(assertionValue) >= 0;
targetOffset++;
if (targetFound)
@@ -283,4 +269,3 @@
return new EntryIDSet(sortedIDs, 0, sortedIDs.length);
}
}
-
diff --git a/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/SuffixContainer.java b/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/SuffixContainer.java
index a90682a..d566e57 100644
--- a/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/SuffixContainer.java
+++ b/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/SuffixContainer.java
@@ -26,7 +26,10 @@
import java.io.Closeable;
+import org.opends.server.backends.jeb.EntryID;
import org.opends.server.types.DN;
+import org.opends.server.types.DirectoryException;
+import org.opends.server.types.Entry;
/**
* Container for a whole suffix environment which stores all entries from the
@@ -50,12 +53,13 @@
String ID2ENTRY_INDEX_NAME = "id2entry";
/**
* The name of the index associating an entry id to the entry id set of all
- * its children.
+ * its children, i.e. its immediate children.
*/
String ID2CHILDREN_INDEX_NAME = "id2children";
/**
* The name of the index associating an entry id to the entry id set of all
- * its subordinates.
+ * its subordinates, i.e. the children, grand-children, grand-grand-children,
+ * ....
*/
String ID2SUBTREE_INDEX_NAME = "id2subtree";
/** The name of the index associating normalized DNs to normalized URIs. */
@@ -65,6 +69,8 @@
* does the index needs to be rebuilt ?
*/
String STATE_INDEX_NAME = "state";
+ /** The attribute used to return a search index debug string to the client. */
+ String ATTR_DEBUG_SEARCH_INDEX = "debugsearchindex";
/**
* Returns the baseDN that this suffix container is responsible for.
@@ -81,4 +87,14 @@
*/
long getEntryCount();
+ /**
+ * Returns the entry corresponding to the provided entryID.
+ *
+ * @param entryID
+ * the id of the entry to retrieve
+ * @return the entry corresponding to the provided entryID
+ * @throws DirectoryException
+ * If an error occurs retrieving the entry
+ */
+ Entry getEntry(EntryID entryID) throws DirectoryException;
}
--
Gitblit v1.10.0