From 3a209faa6fafaa9ee7ba9640a850449062b4b78d Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Fri, 13 Jan 2012 23:13:48 +0000
Subject: [PATCH] Fix OPENDJ-98: Searches on cn=monitor take a long time
---
opends/src/server/org/opends/server/backends/MonitorBackend.java | 1785 ++++++++++++++++++++++++++++-------------------------------
1 files changed, 841 insertions(+), 944 deletions(-)
diff --git a/opends/src/server/org/opends/server/backends/MonitorBackend.java b/opends/src/server/org/opends/server/backends/MonitorBackend.java
index 9fd6d86..be0a594 100644
--- a/opends/src/server/org/opends/server/backends/MonitorBackend.java
+++ b/opends/src/server/org/opends/server/backends/MonitorBackend.java
@@ -23,62 +23,34 @@
*
*
* Copyright 2006-2010 Sun Microsystems, Inc.
+ * Portions copyright 2012 ForgeRock AS.
*/
package org.opends.server.backends;
+
+
import static org.opends.messages.BackendMessages.*;
import static org.opends.messages.ConfigMessages.*;
import static org.opends.server.config.ConfigConstants.*;
-import static org.opends.server.loggers.debug.DebugLogger.*;
+import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
+import static org.opends.server.loggers.debug.DebugLogger.getTracer;
import static org.opends.server.util.ServerConstants.*;
-import static org.opends.server.util.StaticUtils.*;
+import static org.opends.server.util.StaticUtils.getExceptionMessage;
+import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
+import java.util.*;
-import java.util.Set;
import org.opends.messages.Message;
import org.opends.server.admin.Configuration;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.std.server.MonitorBackendCfg;
-import org.opends.server.admin.std.server.MonitorProviderCfg;
import org.opends.server.api.Backend;
import org.opends.server.api.MonitorProvider;
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;
-import org.opends.server.core.AddOperation;
-import org.opends.server.core.DeleteOperation;
-import org.opends.server.core.DirectoryServer;
-import org.opends.server.core.ModifyDNOperation;
-import org.opends.server.core.ModifyOperation;
-import org.opends.server.core.SearchOperation;
+import org.opends.server.core.*;
import org.opends.server.loggers.debug.DebugTracer;
-import org.opends.server.types.Attribute;
-import org.opends.server.types.AttributeType;
-import org.opends.server.types.AttributeValue;
-import org.opends.server.types.Attributes;
-import org.opends.server.types.BackupConfig;
-import org.opends.server.types.BackupDirectory;
-import org.opends.server.types.ConditionResult;
-import org.opends.server.types.ConfigChangeResult;
-import org.opends.server.types.DN;
-import org.opends.server.types.DebugLogLevel;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.Entry;
-import org.opends.server.types.IndexType;
-import org.opends.server.types.InitializationException;
-import org.opends.server.types.LDIFExportConfig;
-import org.opends.server.types.LDIFImportConfig;
-import org.opends.server.types.LDIFImportResult;
-import org.opends.server.types.ObjectClass;
-import org.opends.server.types.RDN;
-import org.opends.server.types.RestoreConfig;
-import org.opends.server.types.ResultCode;
-import org.opends.server.types.SearchFilter;
-import org.opends.server.types.SearchScope;
+import org.opends.server.types.*;
import org.opends.server.util.DynamicConstants;
import org.opends.server.util.LDIFWriter;
import org.opends.server.util.TimeThread;
@@ -87,14 +59,13 @@
/**
- * This class defines a backend to hold Directory Server monitor entries. It
+ * This class defines a backend to hold Directory Server monitor entries. It
* will not actually store anything, but upon request will retrieve the
- * requested monitor and dynamically generate the associated entry. It will
- * also construct a base monitor entry with some useful server-wide data.
+ * requested monitor and dynamically generate the associated entry. It will also
+ * construct a base monitor entry with some useful server-wide data.
*/
-public class MonitorBackend
- extends Backend
- implements ConfigurationChangeListener<MonitorBackendCfg>
+public class MonitorBackend extends Backend implements
+ ConfigurationChangeListener<MonitorBackendCfg>
{
/**
* The tracer object for the debug logger.
@@ -106,7 +77,7 @@
private ArrayList<Attribute> userDefinedAttributes;
// The set of objectclasses that will be used in monitor entries.
- private HashMap<ObjectClass,String> monitorObjectClasses;
+ private HashMap<ObjectClass, String> monitorObjectClasses;
// The DN of the configuration entry for this backend.
private DN configEntryDN;
@@ -126,13 +97,10 @@
// The set of supported features for this backend.
private HashSet<String> supportedFeatures;
- // The mapping between entry DNs and the corresponding entries.
- private LinkedHashMap<DN,Entry> entryMap;
- // The mapping between parent DNs and their immediate children.
- private HashMap<DN,HashSet<DN>> childDNs;
+
/**
- * Creates a new backend with the provided information. All backend
+ * Creates a new backend with the provided information. All backend
* implementations must implement a default constructor that use
* <CODE>super()</CODE> to invoke this constructor.
*/
@@ -142,95 +110,167 @@
}
+
/**
* {@inheritDoc}
*/
@Override()
- public void configureBackend(Configuration config)
- throws ConfigException
+ public void addEntry(final Entry entry, final AddOperation addOperation)
+ throws DirectoryException
{
- Validator.ensureNotNull(config);
- Validator.ensureTrue(config instanceof MonitorBackendCfg);
-
- MonitorBackendCfg cfg = (MonitorBackendCfg)config;
- ConfigEntry configEntry = DirectoryServer.getConfigEntry(cfg.dn());
+ final Message message = ERR_MONITOR_ADD_NOT_SUPPORTED.get(String
+ .valueOf(entry.getDN()));
+ throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
+ }
- // Make sure that a configuration entry was provided. If not, then we will
- // not be able to complete initialization.
- if (configEntry == null)
- {
- Message message = ERR_MONITOR_CONFIG_ENTRY_NULL.get();
- throw new ConfigException(message);
- }
- configEntryDN = configEntry.getDN();
+ /**
+ * {@inheritDoc}
+ */
+ public ConfigChangeResult applyConfigurationChange(
+ final MonitorBackendCfg backendCfg)
+ {
+ ResultCode resultCode = ResultCode.SUCCESS;
+ final boolean adminActionRequired = false;
+ final ArrayList<Message> messages = new ArrayList<Message>();
-
- // Get the set of user-defined attributes for the configuration entry. Any
- // attributes that we don't recognize will be included directly in the base
- // monitor entry.
- userDefinedAttributes = new ArrayList<Attribute>();
- for (List<Attribute> attrs :
- configEntry.getEntry().getUserAttributes().values())
- {
- for (Attribute a : attrs)
- {
- if (! isMonitorConfigAttribute(a))
- {
- userDefinedAttributes.add(a);
- }
- }
- }
- for (List<Attribute> attrs :
- configEntry.getEntry().getOperationalAttributes().values())
- {
- for (Attribute a : attrs)
- {
- if (! isMonitorConfigAttribute(a))
- {
- userDefinedAttributes.add(a);
- }
- }
- }
-
-
- // Construct the set of objectclasses to include in the base monitor entry.
- monitorObjectClasses = new LinkedHashMap<ObjectClass,String>(2);
- ObjectClass topOC = DirectoryServer.getObjectClass(OC_TOP, true);
- monitorObjectClasses.put(topOC, OC_TOP);
-
- ObjectClass monitorOC = DirectoryServer.getObjectClass(OC_MONITOR_ENTRY,
- true);
- monitorObjectClasses.put(monitorOC, OC_MONITOR_ENTRY);
-
-
- // Define an empty sets for the supported controls and features.
- supportedControls = new HashSet<String>(0);
- supportedFeatures = new HashSet<String>(0);
-
- // Create the set of base DNs that we will handle. In this case, it's just
- // the DN of the base monitor entry.
+ // Check to see if there is a new set of user-defined attributes.
+ final ArrayList<Attribute> userAttrs = new ArrayList<Attribute>();
try
{
- baseMonitorDN = DN.decode(DN_MONITOR_ROOT);
+ final ConfigEntry configEntry = DirectoryServer
+ .getConfigEntry(configEntryDN);
+ for (final List<Attribute> attrs : configEntry.getEntry()
+ .getUserAttributes().values())
+ {
+ for (final Attribute a : attrs)
+ {
+ if (!isMonitorConfigAttribute(a))
+ {
+ userAttrs.add(a);
+ }
+ }
+ }
+ for (final List<Attribute> attrs : configEntry.getEntry()
+ .getOperationalAttributes().values())
+ {
+ for (final Attribute a : attrs)
+ {
+ if (!isMonitorConfigAttribute(a))
+ {
+ userAttrs.add(a);
+ }
+ }
+ }
}
- catch (Exception e)
+ catch (final Exception e)
{
if (debugEnabled())
{
TRACER.debugCaught(DebugLogLevel.ERROR, e);
}
- Message message =
- ERR_MONITOR_CANNOT_DECODE_MONITOR_ROOT_DN.get(getExceptionMessage(e));
+ messages.add(ERR_CONFIG_BACKEND_ERROR_INTERACTING_WITH_BACKEND_ENTRY.get(
+ String.valueOf(configEntryDN), stackTraceToSingleLineString(e)));
+ resultCode = DirectoryServer.getServerErrorResultCode();
+ }
+
+ userDefinedAttributes = userAttrs;
+
+ final Message message = INFO_MONITOR_USING_NEW_USER_ATTRS.get();
+ messages.add(message);
+
+ currentConfig = backendCfg;
+ return new ConfigChangeResult(resultCode, adminActionRequired, messages);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public void configureBackend(final Configuration config)
+ throws ConfigException
+ {
+ Validator.ensureNotNull(config);
+ Validator.ensureTrue(config instanceof MonitorBackendCfg);
+
+ final MonitorBackendCfg cfg = (MonitorBackendCfg) config;
+ final ConfigEntry configEntry = DirectoryServer.getConfigEntry(cfg.dn());
+
+ // Make sure that a configuration entry was provided. If not, then we will
+ // not be able to complete initialization.
+ if (configEntry == null)
+ {
+ final Message message = ERR_MONITOR_CONFIG_ENTRY_NULL.get();
+ throw new ConfigException(message);
+ }
+
+ configEntryDN = configEntry.getDN();
+
+ // Get the set of user-defined attributes for the configuration entry. Any
+ // attributes that we don't recognize will be included directly in the base
+ // monitor entry.
+ userDefinedAttributes = new ArrayList<Attribute>();
+ for (final List<Attribute> attrs : configEntry.getEntry()
+ .getUserAttributes().values())
+ {
+ for (final Attribute a : attrs)
+ {
+ if (!isMonitorConfigAttribute(a))
+ {
+ userDefinedAttributes.add(a);
+ }
+ }
+ }
+ for (final List<Attribute> attrs : configEntry.getEntry()
+ .getOperationalAttributes().values())
+ {
+ for (final Attribute a : attrs)
+ {
+ if (!isMonitorConfigAttribute(a))
+ {
+ userDefinedAttributes.add(a);
+ }
+ }
+ }
+
+ // Construct the set of objectclasses to include in the base monitor entry.
+ monitorObjectClasses = new LinkedHashMap<ObjectClass, String>(2);
+ final ObjectClass topOC = DirectoryServer.getObjectClass(OC_TOP, true);
+ monitorObjectClasses.put(topOC, OC_TOP);
+
+ final ObjectClass monitorOC = DirectoryServer.getObjectClass(
+ OC_MONITOR_ENTRY, true);
+ monitorObjectClasses.put(monitorOC, OC_MONITOR_ENTRY);
+
+ // Define an empty sets for the supported controls and features.
+ supportedControls = new HashSet<String>(0);
+ supportedFeatures = new HashSet<String>(0);
+
+ // Create the set of base DNs that we will handle. In this case, it's just
+ // the DN of the base monitor entry.
+ try
+ {
+ baseMonitorDN = DN.decode(DN_MONITOR_ROOT);
+ }
+ catch (final Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ final Message message = ERR_MONITOR_CANNOT_DECODE_MONITOR_ROOT_DN
+ .get(getExceptionMessage(e));
throw new ConfigException(message, e);
}
// FIXME -- Deal with this more correctly.
this.baseDNs = new DN[] { baseMonitorDN };
-
currentConfig = cfg;
}
@@ -240,32 +280,146 @@
* {@inheritDoc}
*/
@Override()
- public void initializeBackend()
- throws ConfigException, InitializationException
+ public void createBackup(final BackupConfig backupConfig)
+ throws DirectoryException
{
- // Register with the Directory Server as a configurable component.
- currentConfig.addMonitorChangeListener(this);
+ // This backend does not provide a backup/restore mechanism.
+ final Message message = ERR_MONITOR_BACKUP_AND_RESTORE_NOT_SUPPORTED.get();
+ throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
+ }
- entryMap = new LinkedHashMap<DN,Entry>();
- childDNs = new HashMap<DN,HashSet<DN>>();
- this.initEntryMaps();
- // Register the monitor base as a private suffix.
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public void deleteEntry(final DN entryDN,
+ final DeleteOperation deleteOperation) throws DirectoryException
+ {
+ final Message message = ERR_MONITOR_DELETE_NOT_SUPPORTED.get(String
+ .valueOf(entryDN));
+ throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public boolean entryExists(final DN entryDN) throws DirectoryException
+ {
+ return getDIT().containsKey(entryDN);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public void exportLDIF(final LDIFExportConfig exportConfig)
+ throws DirectoryException
+ {
+ // TODO export-ldif reports nonsense for upTime etc.
+
+ // Create the LDIF writer.
+ LDIFWriter ldifWriter;
try
{
- DirectoryServer.registerBaseDN(baseMonitorDN, this, true);
+ ldifWriter = new LDIFWriter(exportConfig);
}
- catch (Exception e)
+ catch (final Exception e)
{
if (debugEnabled())
{
TRACER.debugCaught(DebugLogLevel.ERROR, e);
}
- Message message = ERR_BACKEND_CANNOT_REGISTER_BASEDN.get(
- baseMonitorDN.toString(), getExceptionMessage(e));
- throw new InitializationException(message, e);
+ final Message message = ERR_ROOTDSE_UNABLE_TO_CREATE_LDIF_WRITER
+ .get(stackTraceToSingleLineString(e));
+ throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
+ message);
+ }
+
+ // Write the base monitor entry to the LDIF.
+ try
+ {
+ ldifWriter.writeEntry(getBaseMonitorEntry());
+ }
+ catch (final Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ try
+ {
+ ldifWriter.close();
+ }
+ catch (final Exception e2)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e2);
+ }
+ }
+
+ final Message message = ERR_MONITOR_UNABLE_TO_EXPORT_BASE
+ .get(stackTraceToSingleLineString(e));
+ throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
+ message);
+ }
+
+ // Get all the monitor providers, convert them to entries, and write them to
+ // LDIF.
+ for (final MonitorProvider<?> monitorProvider : DirectoryServer
+ .getMonitorProviders().values())
+ {
+ try
+ {
+ // TODO implementation of export is incomplete
+ }
+ catch (final Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ try
+ {
+ ldifWriter.close();
+ }
+ catch (final Exception e2)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e2);
+ }
+ }
+
+ final Message message = ERR_MONITOR_UNABLE_TO_EXPORT_PROVIDER_ENTRY
+ .get(monitorProvider.getMonitorInstanceName(),
+ stackTraceToSingleLineString(e));
+ throw new DirectoryException(
+ DirectoryServer.getServerErrorResultCode(), message);
+ }
+ }
+
+ // Close the monitor provider and return.
+ try
+ {
+ ldifWriter.close();
+ }
+ catch (final Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
}
}
@@ -277,15 +431,12 @@
@Override()
public void finalizeBackend()
{
- entryMap.clear();
- childDNs.clear();
currentConfig.removeMonitorChangeListener(this);
-
try
{
DirectoryServer.deregisterBaseDN(baseMonitorDN);
}
- catch (Exception e)
+ catch (final Exception e)
{
if (debugEnabled())
{
@@ -297,33 +448,6 @@
/**
- * Indicates whether the provided attribute is one that is used in the
- * configuration of this backend.
- *
- * @param attribute The attribute for which to make the determination.
- *
- * @return <CODE>true</CODE> if the provided attribute is one that is used in
- * the configuration of this backend, <CODE>false</CODE> if not.
- */
- private boolean isMonitorConfigAttribute(Attribute attribute)
- {
- AttributeType attrType = attribute.getAttributeType();
- if (attrType.hasName(ATTR_COMMON_NAME) ||
- attrType.hasName(ATTR_BACKEND_ENABLED.toLowerCase()) ||
- attrType.hasName(ATTR_BACKEND_CLASS.toLowerCase()) ||
- attrType.hasName(ATTR_BACKEND_BASE_DN.toLowerCase()) ||
- attrType.hasName(ATTR_BACKEND_ID.toLowerCase()) ||
- attrType.hasName(ATTR_BACKEND_WRITABILITY_MODE.toLowerCase()))
- {
- return true;
- }
-
- return false;
- }
-
-
-
- /**
* {@inheritDoc}
*/
@Override()
@@ -338,12 +462,166 @@
* {@inheritDoc}
*/
@Override()
+ public Entry getEntry(final DN entryDN) throws DirectoryException
+ {
+ // If the requested entry was null, then throw an exception.
+ if (entryDN == null)
+ {
+ final Message message = ERR_MONITOR_GET_ENTRY_NULL.get();
+ throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
+ message);
+ }
+
+ // If the requested entry was the monitor base entry, then retrieve it
+ // without constructing the DIT.
+ if (entryDN.equals(baseMonitorDN))
+ {
+ return getBaseMonitorEntry();
+ }
+
+ // From now on we'll need the DIT.
+ final Map<DN, MonitorProvider<?>> dit = getDIT();
+ if (!dit.containsKey(entryDN))
+ {
+ final Message message = ERR_MONITOR_INVALID_BASE.get(
+ String.valueOf(entryDN), String.valueOf(baseMonitorDN));
+ throw new DirectoryException(ResultCode.NO_SUCH_OBJECT, message);
+ }
+
+ // The DN is associated with a valid monitor/glue entry.
+ return getEntry(entryDN, dit);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
public long getEntryCount()
{
- if (entryMap != null) {
- return entryMap.size();
+ return getDIT().size();
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public HashSet<String> getSupportedControls()
+ {
+ return supportedControls;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public HashSet<String> getSupportedFeatures()
+ {
+ return supportedFeatures;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public ConditionResult hasSubordinates(final DN entryDN)
+ throws DirectoryException
+ {
+ final NavigableMap<DN, MonitorProvider<?>> dit = getDIT();
+ if (!dit.containsKey(entryDN))
+ {
+ return ConditionResult.UNDEFINED;
}
- return -1;
+ else
+ {
+ final DN nextDN = dit.higherKey(entryDN);
+ if (nextDN == null || !nextDN.isDescendantOf(entryDN))
+ {
+ return ConditionResult.FALSE;
+ }
+ else
+ {
+ return ConditionResult.TRUE;
+ }
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public LDIFImportResult importLDIF(final LDIFImportConfig importConfig)
+ throws DirectoryException
+ {
+ // This backend does not support LDIF imports.
+ final Message message = ERR_MONITOR_IMPORT_NOT_SUPPORTED.get();
+ throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public void initializeBackend() throws ConfigException,
+ InitializationException
+ {
+ // Register with the Directory Server as a configurable component.
+ currentConfig.addMonitorChangeListener(this);
+
+ // Register the monitor base as a private suffix.
+ try
+ {
+ DirectoryServer.registerBaseDN(baseMonitorDN, this, true);
+ }
+ catch (final Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ final Message message = ERR_BACKEND_CANNOT_REGISTER_BASEDN.get(
+ baseMonitorDN.toString(), getExceptionMessage(e));
+ throw new InitializationException(message, e);
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isConfigurationChangeAcceptable(
+ final MonitorBackendCfg backendCfg,
+ final List<Message> unacceptableReasons)
+ {
+ // We'll pretty much accept anything here as long as it isn't one of our
+ // private attributes.
+ return true;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public boolean isIndexed(final AttributeType attributeType,
+ final IndexType indexType)
+ {
+ // All searches in this backend will always be considered indexed.
+ return true;
}
@@ -364,120 +642,42 @@
* {@inheritDoc}
*/
@Override()
- public boolean isIndexed(AttributeType attributeType, IndexType indexType)
+ public long numSubordinates(final DN entryDN, final boolean subtree)
+ throws DirectoryException
{
- // All searches in this backend will always be considered indexed.
- return true;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public ConditionResult hasSubordinates(DN entryDN)
- throws DirectoryException
- {
- long ret = numSubordinates(entryDN, false);
- if(ret < 0)
+ final NavigableMap<DN, MonitorProvider<?>> dit = getDIT();
+ if (!dit.containsKey(entryDN))
{
- return ConditionResult.UNDEFINED;
- }
- else if(ret == 0)
- {
- return ConditionResult.FALSE;
- }
- else
- {
- return ConditionResult.TRUE;
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public long numSubordinates(DN entryDN, boolean subtree)
- throws DirectoryException {
-
- Set<DN> children = childDNs.get(entryDN);
- if (children == null)
- {
- if(entryMap.get(entryDN) != null)
- {
- // The entry does exist but just no children.
- return 0;
- }
- return -1;
- }
-
- if(!subtree)
- {
- return children.size();
+ return -1L;
}
else
{
long count = 0;
- for(DN child : children)
+ final int childDNSize = entryDN.getNumComponents() + 1;
+ for (final DN dn : dit.tailMap(entryDN, false).navigableKeySet())
{
- count += numSubordinates(child, true);
- count++;
+ if (!dn.isDescendantOf(entryDN))
+ {
+ break;
+ }
+ else if (subtree || dn.getNumComponents() == childDNSize)
+ {
+ count++;
+ }
}
return count;
}
}
+
+
/**
* {@inheritDoc}
*/
- @Override()
- public Entry getEntry(DN entryDN)
- throws DirectoryException
+ @Override
+ public void preloadEntryCache() throws UnsupportedOperationException
{
- // If the requested entry was null, then throw an exception.
- if (entryDN == null)
- {
- Message message = ERR_MONITOR_GET_ENTRY_NULL.get();
- throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
- message);
- }
-
-
- // If the requested entry was the monitor base entry, then retrieve it.
- if (entryDN.equals(baseMonitorDN))
- {
- return getBaseMonitorEntry();
- }
-
- if (!isATreeNode(entryDN)) {
- Message message = ERR_MONITOR_INVALID_BASE.get(
- String.valueOf(entryDN), String.valueOf(baseMonitorDN));
- throw new DirectoryException(ResultCode.NO_SUCH_OBJECT, message);
- }
-
-
- // Get the RDN for the requested DN and make sure it is single-valued.
- RDN entryRDN = entryDN.getRDN();
- if (entryRDN.isMultiValued())
- {
- Message message =
- ERR_MONITOR_MULTIVALUED_RDN.get(String.valueOf(entryDN));
- throw new DirectoryException(
- ResultCode.NO_SUCH_OBJECT, message, baseMonitorDN, null);
- }
-
- String rdnValue = getRdns(entryDN);
- MonitorProvider<? extends MonitorProviderCfg> monitorProvider =
- DirectoryServer.getMonitorProvider(rdnValue.toLowerCase());
-
- // Could be a monitor branch
- if (monitorProvider == null) {
- return getBranchMonitorEntry(entryDN);
- }
-
- // Take the data from the monitor provider and stuff it into an entry.
- return getMonitorEntry(entryDN, monitorProvider);
+ throw new UnsupportedOperationException("Operation not supported.");
}
@@ -486,10 +686,193 @@
* {@inheritDoc}
*/
@Override()
- public boolean entryExists(DN entryDN)
- throws DirectoryException
+ public void removeBackup(final BackupDirectory backupDirectory,
+ final String backupID) throws DirectoryException
{
- return this.isATreeNode(entryDN);
+ // This backend does not provide a backup/restore mechanism.
+ final Message message = ERR_MONITOR_BACKUP_AND_RESTORE_NOT_SUPPORTED.get();
+ throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public void renameEntry(final DN currentDN, final Entry entry,
+ final ModifyDNOperation modifyDNOperation) throws DirectoryException
+ {
+ final Message message = ERR_MONITOR_MODIFY_DN_NOT_SUPPORTED.get(String
+ .valueOf(currentDN));
+ throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public void replaceEntry(final Entry oldEntry, final Entry newEntry,
+ final ModifyOperation modifyOperation) throws DirectoryException
+ {
+ final Message message = ERR_MONITOR_MODIFY_NOT_SUPPORTED.get(
+ String.valueOf(newEntry.getDN()), String.valueOf(configEntryDN));
+ throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public void restoreBackup(final RestoreConfig restoreConfig)
+ throws DirectoryException
+ {
+ // This backend does not provide a backup/restore mechanism.
+ final Message message = ERR_MONITOR_BACKUP_AND_RESTORE_NOT_SUPPORTED.get();
+ throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public void search(final SearchOperation searchOperation)
+ throws DirectoryException
+ {
+ // Get the base DN, scope, and filter for the search.
+ final DN baseDN = searchOperation.getBaseDN();
+ final SearchScope scope = searchOperation.getScope();
+ final SearchFilter filter = searchOperation.getFilter();
+
+ // Compute the current monitor DIT.
+ final NavigableMap<DN, MonitorProvider<?>> dit = getDIT();
+
+ // Resolve the base entry and return no such object if it does not exist.
+ if (!dit.containsKey(baseDN))
+ {
+ // Not found, so find the nearest match.
+ DN matchedDN = baseDN.getParent();
+ while (matchedDN != null)
+ {
+ if (dit.containsKey(matchedDN))
+ {
+ break;
+ }
+ matchedDN = matchedDN.getParent();
+ }
+ final Message message = ERR_MEMORYBACKEND_ENTRY_DOESNT_EXIST.get(String
+ .valueOf(baseDN));
+ throw new DirectoryException(ResultCode.NO_SUCH_OBJECT, message,
+ matchedDN, null);
+ }
+
+ // Walk through all entries and send the ones that match.
+ for (final Map.Entry<DN, MonitorProvider<?>> e : dit.tailMap(baseDN)
+ .entrySet())
+ {
+ final DN dn = e.getKey();
+ if (dn.matchesBaseAndScope(baseDN, scope))
+ {
+ final Entry entry = getEntry(dn, dit);
+ if (filter.matchesEntry(entry))
+ {
+ searchOperation.returnEntry(entry, null);
+ }
+ }
+ else if (scope == SearchScope.BASE_OBJECT || !dn.isDescendantOf(baseDN))
+ {
+ // No more entries will be in scope.
+ break;
+ }
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public boolean supportsBackup()
+ {
+ // This backend does not provide a backup/restore mechanism.
+ return false;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public boolean supportsBackup(final BackupConfig backupConfig,
+ final StringBuilder unsupportedReason)
+ {
+ // This backend does not provide a backup/restore mechanism.
+ return false;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public boolean supportsLDIFExport()
+ {
+ // We can export all the monitor entries as a point-in-time snapshot.
+ // TODO implementation of export is incomplete
+ // TODO export-ldif reports nonsense for upTime etc.
+ return false;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public boolean supportsLDIFImport()
+ {
+ // This backend does not support LDIF imports.
+ return false;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public boolean supportsRestore()
+ {
+ // This backend does not provide a backup/restore mechanism.
+ return false;
+ }
+
+
+
+ /**
+ * Creates an attribute for a monitor entry with the following criteria.
+ *
+ * @param name
+ * The name for the attribute.
+ * @param lowerName
+ * The name for the attribute formatted in all lowercase characters.
+ * @param value
+ * The value to use for the attribute.
+ * @return The constructed attribute.
+ */
+ private Attribute createAttribute(final String name, final String lowerName,
+ final String value)
+ {
+ return Attributes.create(name, value);
}
@@ -497,130 +880,110 @@
/**
* Retrieves the base monitor entry for the Directory Server.
*
- * @return The base monitor entry for the Directory Server.
+ * @return The base monitor entry for the Directory Server.
*/
- public Entry getBaseMonitorEntry()
+ private Entry getBaseMonitorEntry()
{
- HashMap<ObjectClass,String> monitorClasses =
- new LinkedHashMap<ObjectClass,String>(3);
+ final HashMap<ObjectClass, String> monitorClasses =
+ new LinkedHashMap<ObjectClass, String>(3);
monitorClasses.putAll(monitorObjectClasses);
- ObjectClass extensibleObjectOC =
- DirectoryServer.getObjectClass(OC_EXTENSIBLE_OBJECT_LC, true);
+ final ObjectClass extensibleObjectOC = DirectoryServer.getObjectClass(
+ OC_EXTENSIBLE_OBJECT_LC, true);
monitorClasses.put(extensibleObjectOC, OC_EXTENSIBLE_OBJECT);
- HashMap<AttributeType,List<Attribute>> monitorUserAttrs =
- new LinkedHashMap<AttributeType,List<Attribute>>();
-
- HashMap<AttributeType,List<Attribute>> monitorOperationalAttrs =
- new LinkedHashMap<AttributeType,List<Attribute>>();
-
+ final HashMap<AttributeType, List<Attribute>> monitorUserAttrs =
+ new LinkedHashMap<AttributeType, List<Attribute>>();
+ final HashMap<AttributeType, List<Attribute>> monitorOperationalAttrs =
+ new LinkedHashMap<AttributeType, List<Attribute>>();
// Add the "cn" attribute.
- Attribute cnAttr = createAttribute(ATTR_COMMON_NAME, ATTR_COMMON_NAME,
- "monitor");
- ArrayList<Attribute> cnList = new ArrayList<Attribute>(1);
+ final Attribute cnAttr = createAttribute(ATTR_COMMON_NAME,
+ ATTR_COMMON_NAME, "monitor");
+ final ArrayList<Attribute> cnList = new ArrayList<Attribute>(1);
cnList.add(cnAttr);
monitorUserAttrs.put(cnAttr.getAttributeType(), cnList);
-
// Add the server product name.
- Attribute productNameAttr = createAttribute(ATTR_PRODUCT_NAME,
- ATTR_PRODUCT_NAME_LC,
- DynamicConstants.PRODUCT_NAME);
- ArrayList<Attribute> productNameList = new ArrayList<Attribute>(1);
+ final Attribute productNameAttr = createAttribute(ATTR_PRODUCT_NAME,
+ ATTR_PRODUCT_NAME_LC, DynamicConstants.PRODUCT_NAME);
+ final ArrayList<Attribute> productNameList = new ArrayList<Attribute>(1);
productNameList.add(productNameAttr);
monitorUserAttrs.put(productNameAttr.getAttributeType(), productNameList);
-
// Add the vendor name.
- Attribute vendorNameAttr = createAttribute(ATTR_VENDOR_NAME,
- ATTR_VENDOR_NAME_LC,
- SERVER_VENDOR_NAME);
- ArrayList<Attribute> vendorNameList = new ArrayList<Attribute>(1);
+ final Attribute vendorNameAttr = createAttribute(ATTR_VENDOR_NAME,
+ ATTR_VENDOR_NAME_LC, SERVER_VENDOR_NAME);
+ final ArrayList<Attribute> vendorNameList = new ArrayList<Attribute>(1);
vendorNameList.add(vendorNameAttr);
monitorUserAttrs.put(vendorNameAttr.getAttributeType(), vendorNameList);
-
// Add the vendor version.
- Attribute versionAttr = createAttribute(ATTR_VENDOR_VERSION,
- ATTR_VENDOR_VERSION_LC,
- DirectoryServer.getVersionString());
- ArrayList<Attribute> versionList = new ArrayList<Attribute>(1);
+ final Attribute versionAttr = createAttribute(ATTR_VENDOR_VERSION,
+ ATTR_VENDOR_VERSION_LC, DirectoryServer.getVersionString());
+ final ArrayList<Attribute> versionList = new ArrayList<Attribute>(1);
versionList.add(versionAttr);
monitorUserAttrs.put(versionAttr.getAttributeType(), versionList);
-
// Add the server startup time.
- Attribute startTimeAttr =
- createAttribute(ATTR_START_TIME, ATTR_START_TIME_LC,
- DirectoryServer.getStartTimeUTC());
- ArrayList<Attribute> startTimeList = new ArrayList<Attribute>(1);
+ final Attribute startTimeAttr = createAttribute(ATTR_START_TIME,
+ ATTR_START_TIME_LC, DirectoryServer.getStartTimeUTC());
+ final ArrayList<Attribute> startTimeList = new ArrayList<Attribute>(1);
startTimeList.add(startTimeAttr);
monitorUserAttrs.put(startTimeAttr.getAttributeType(), startTimeList);
-
// Add the current time.
- Attribute currentTimeAttr =
- createAttribute(ATTR_CURRENT_TIME, ATTR_CURRENT_TIME_LC,
- TimeThread.getGMTTime());
- ArrayList<Attribute> currentTimeList = new ArrayList<Attribute>(1);
+ final Attribute currentTimeAttr = createAttribute(ATTR_CURRENT_TIME,
+ ATTR_CURRENT_TIME_LC, TimeThread.getGMTTime());
+ final ArrayList<Attribute> currentTimeList = new ArrayList<Attribute>(1);
currentTimeList.add(currentTimeAttr);
monitorUserAttrs.put(currentTimeAttr.getAttributeType(), currentTimeList);
-
// Add the uptime as a human-readable string.
- long upSeconds =
- ((System.currentTimeMillis() - DirectoryServer.getStartTime()) / 1000);
- long upDays = (upSeconds / 86400);
+ long upSeconds = ((System.currentTimeMillis() - DirectoryServer
+ .getStartTime()) / 1000);
+ final long upDays = (upSeconds / 86400);
upSeconds %= 86400;
- long upHours = (upSeconds / 3600);
+ final long upHours = (upSeconds / 3600);
upSeconds %= 3600;
- long upMinutes = (upSeconds / 60);
+ final long upMinutes = (upSeconds / 60);
upSeconds %= 60;
- Message upTimeStr =
- INFO_MONITOR_UPTIME.get(upDays, upHours, upMinutes, upSeconds);
- Attribute upTimeAttr = createAttribute(ATTR_UP_TIME, ATTR_UP_TIME_LC,
- upTimeStr.toString());
- ArrayList<Attribute> upTimeList = new ArrayList<Attribute>(1);
+ final Message upTimeStr = INFO_MONITOR_UPTIME.get(upDays, upHours,
+ upMinutes, upSeconds);
+ final Attribute upTimeAttr = createAttribute(ATTR_UP_TIME, ATTR_UP_TIME_LC,
+ upTimeStr.toString());
+ final ArrayList<Attribute> upTimeList = new ArrayList<Attribute>(1);
upTimeList.add(upTimeAttr);
monitorUserAttrs.put(upTimeAttr.getAttributeType(), upTimeList);
-
// Add the number of connections currently established.
- long currentConns = DirectoryServer.getCurrentConnections();
- Attribute currentConnsAttr = createAttribute(ATTR_CURRENT_CONNS,
- ATTR_CURRENT_CONNS_LC,
- String.valueOf(currentConns));
- ArrayList<Attribute> currentConnsList = new ArrayList<Attribute>(1);
+ final long currentConns = DirectoryServer.getCurrentConnections();
+ final Attribute currentConnsAttr = createAttribute(ATTR_CURRENT_CONNS,
+ ATTR_CURRENT_CONNS_LC, String.valueOf(currentConns));
+ final ArrayList<Attribute> currentConnsList = new ArrayList<Attribute>(1);
currentConnsList.add(currentConnsAttr);
monitorUserAttrs.put(currentConnsAttr.getAttributeType(), currentConnsList);
-
// Add the maximum number of connections established at one time.
- long maxConns = DirectoryServer.getMaxConnections();
- Attribute maxConnsAttr = createAttribute(ATTR_MAX_CONNS,
- ATTR_MAX_CONNS_LC,
- String.valueOf(maxConns));
- ArrayList<Attribute> maxConnsList = new ArrayList<Attribute>(1);
+ final long maxConns = DirectoryServer.getMaxConnections();
+ final Attribute maxConnsAttr = createAttribute(ATTR_MAX_CONNS,
+ ATTR_MAX_CONNS_LC, String.valueOf(maxConns));
+ final ArrayList<Attribute> maxConnsList = new ArrayList<Attribute>(1);
maxConnsList.add(maxConnsAttr);
monitorUserAttrs.put(maxConnsAttr.getAttributeType(), maxConnsList);
-
// Add the total number of connections the server has accepted.
- long totalConns = DirectoryServer.getTotalConnections();
- Attribute totalConnsAttr = createAttribute(ATTR_TOTAL_CONNS,
- ATTR_TOTAL_CONNS_LC,
- String.valueOf(totalConns));
- ArrayList<Attribute> totalConnsList = new ArrayList<Attribute>(1);
+ final long totalConns = DirectoryServer.getTotalConnections();
+ final Attribute totalConnsAttr = createAttribute(ATTR_TOTAL_CONNS,
+ ATTR_TOTAL_CONNS_LC, String.valueOf(totalConns));
+ final ArrayList<Attribute> totalConnsList = new ArrayList<Attribute>(1);
totalConnsList.add(totalConnsAttr);
monitorUserAttrs.put(totalConnsAttr.getAttributeType(), totalConnsList);
-
// Add all the user-defined attributes.
- for (Attribute a : userDefinedAttributes)
+ for (final Attribute a : userDefinedAttributes)
{
- AttributeType type = a.getAttributeType();
+ final AttributeType type = a.getAttributeType();
if (type.isOperational())
{
@@ -652,95 +1015,167 @@
}
}
-
// Construct and return the entry.
- Entry e = new Entry(baseMonitorDN, monitorClasses, monitorUserAttrs,
- monitorOperationalAttrs);
+ final Entry e = new Entry(baseMonitorDN, monitorClasses, monitorUserAttrs,
+ monitorOperationalAttrs);
e.processVirtualAttributes();
return e;
}
- /**
- * Retrieves the branch monitor entry for the Directory Server.
- * @param dn to get.
- * @return The branch monitor entry for the Directory Server.
- */
- public Entry getBranchMonitorEntry(DN dn) {
- HashMap<ObjectClass,String> monitorClasses =
- new LinkedHashMap<ObjectClass,String>(3);
+
+ /**
+ * Retrieves the branch monitor entry for the Directory Server.
+ *
+ * @param dn
+ * to get.
+ * @return The branch monitor entry for the Directory Server.
+ */
+ private Entry getBranchMonitorEntry(final DN dn)
+ {
+
+ final HashMap<ObjectClass, String> monitorClasses =
+ new LinkedHashMap<ObjectClass, String>(3);
monitorClasses.putAll(monitorObjectClasses);
- ObjectClass monitorOC = DirectoryServer.getObjectClass(OC_MONITOR_BRANCH,
- true);
+ final ObjectClass monitorOC = DirectoryServer.getObjectClass(
+ OC_MONITOR_BRANCH, true);
monitorClasses.put(monitorOC, OC_MONITOR_BRANCH);
- HashMap<AttributeType,List<Attribute>> monitorUserAttrs =
- new LinkedHashMap<AttributeType,List<Attribute>>();
+ final HashMap<AttributeType, List<Attribute>> monitorUserAttrs =
+ new LinkedHashMap<AttributeType, List<Attribute>>();
- RDN rdn = dn.getRDN();
+ final RDN rdn = dn.getRDN();
if (rdn != null)
{
// Add the RDN values
- for (int i=0; i<rdn.getNumValues(); i++)
+ for (int i = 0; i < rdn.getNumValues(); i++)
{
- AttributeType attributeType = rdn.getAttributeType(i);
- AttributeValue value = rdn.getAttributeValue(attributeType);
- Attribute attr = Attributes.create(attributeType, value);
- List<Attribute> attrList = new ArrayList<Attribute>(1);
+ final AttributeType attributeType = rdn.getAttributeType(i);
+ final AttributeValue value = rdn.getAttributeValue(attributeType);
+ final Attribute attr = Attributes.create(attributeType, value);
+ final List<Attribute> attrList = new ArrayList<Attribute>(1);
attrList.add(attr);
monitorUserAttrs.put(attributeType, attrList);
}
}
// Construct and return the entry.
- Entry e = new Entry(dn, monitorClasses, monitorUserAttrs, null);
+ final Entry e = new Entry(dn, monitorClasses, monitorUserAttrs, null);
e.processVirtualAttributes();
return e;
}
+
+
/**
- * Generates and returns a monitor entry based on the contents of the
- * provided monitor provider.
+ * Returns a map containing records for each DN in the monitor backend's DIT.
+ * Each record maps the entry DN to the associated monitor provider, or
+ * {@code null} if the entry is a glue (branch) entry.
*
- * @param entryDN The DN to use for the entry.
- * @param monitorProvider The monitor provider to use to obtain the
- * information for the entry.
- *
- * @return The monitor entry generated from the information in the provided
- * monitor provider.
+ * @return A map containing records for each DN in the monitor backend's DIT.
*/
- private Entry getMonitorEntry(DN entryDN,
- MonitorProvider<? extends MonitorProviderCfg>
- monitorProvider)
+ private NavigableMap<DN, MonitorProvider<?>> getDIT()
{
- HashMap<ObjectClass,String> monitorClasses =
- new LinkedHashMap<ObjectClass,String>(3);
+ final NavigableMap<DN, MonitorProvider<?>> dit =
+ new TreeMap<DN, MonitorProvider<?>>();
+ for (final MonitorProvider<?> monitorProvider : DirectoryServer
+ .getMonitorProviders().values())
+ {
+ DN dn = DirectoryServer.getMonitorProviderDN(monitorProvider);
+ dit.put(dn, monitorProvider);
+
+ // Added glue records.
+ for (dn = dn.getParent(); dn != null; dn = dn.getParent())
+ {
+ if (dit.containsKey(dn))
+ {
+ break;
+ }
+ else
+ {
+ dit.put(dn, null);
+ }
+ }
+ }
+ return dit;
+ }
+
+
+
+ /**
+ * Creates the monitor entry having the specified DN.
+ *
+ * @param entryDN
+ * The name of the monitor entry.
+ * @param dit
+ * The monitor DIT.
+ * @return Returns the monitor entry having the specified DN.
+ */
+ private Entry getEntry(final DN entryDN,
+ final Map<DN, MonitorProvider<?>> dit)
+ {
+ // Get the monitor provider.
+ final MonitorProvider<?> monitorProvider = dit.get(entryDN);
+ if (monitorProvider != null)
+ {
+ return getMonitorEntry(entryDN, monitorProvider);
+ }
+ else if (entryDN.equals(baseMonitorDN))
+ {
+ // The monitor base entry needs special treatment.
+ return getBaseMonitorEntry();
+ }
+ else
+ {
+ // Create a generic glue branch entry.
+ return getBranchMonitorEntry(entryDN);
+ }
+ }
+
+
+
+ /**
+ * Generates and returns a monitor entry based on the contents of the provided
+ * monitor provider.
+ *
+ * @param entryDN
+ * The DN to use for the entry.
+ * @param monitorProvider
+ * The monitor provider to use to obtain the information for the
+ * entry.
+ * @return The monitor entry generated from the information in the provided
+ * monitor provider.
+ */
+ private Entry getMonitorEntry(final DN entryDN,
+ final MonitorProvider<?> monitorProvider)
+ {
+ final HashMap<ObjectClass, String> monitorClasses =
+ new LinkedHashMap<ObjectClass, String>(
+ 3);
monitorClasses.putAll(monitorObjectClasses);
- ObjectClass monitorOC = monitorProvider.getMonitorObjectClass();
+ final ObjectClass monitorOC = monitorProvider.getMonitorObjectClass();
monitorClasses.put(monitorOC, monitorOC.getPrimaryName());
- List<Attribute> monitorAttrs = monitorProvider.getMonitorData();
- HashMap<AttributeType,List<Attribute>> attrMap =
- new LinkedHashMap<AttributeType,List<Attribute>>(
- monitorAttrs.size()+1);
-
+ final List<Attribute> monitorAttrs = monitorProvider.getMonitorData();
+ final HashMap<AttributeType, List<Attribute>> attrMap =
+ new LinkedHashMap<AttributeType, List<Attribute>>(
+ monitorAttrs.size() + 1);
// Make sure to include the RDN attribute.
- RDN entryRDN = entryDN.getRDN();
- AttributeType rdnType = entryRDN.getAttributeType(0);
- AttributeValue rdnValue = entryRDN.getAttributeValue(0);
+ final RDN entryRDN = entryDN.getRDN();
+ final AttributeType rdnType = entryRDN.getAttributeType(0);
+ final AttributeValue rdnValue = entryRDN.getAttributeValue(0);
- Attribute rdnAttr = Attributes.create(rdnType, rdnValue);
- ArrayList<Attribute> rdnList = new ArrayList<Attribute>(1);
+ final Attribute rdnAttr = Attributes.create(rdnType, rdnValue);
+ final ArrayList<Attribute> rdnList = new ArrayList<Attribute>(1);
rdnList.add(rdnAttr);
attrMap.put(rdnType, rdnList);
-
// Take the rest of the information from the monitor data.
- for (Attribute a : monitorAttrs)
+ for (final Attribute a : monitorAttrs)
{
- AttributeType type = a.getAttributeType();
+ final AttributeType type = a.getAttributeType();
List<Attribute> attrs = attrMap.get(type);
if (attrs == null)
@@ -755,575 +1190,37 @@
}
}
- Entry e = new Entry(entryDN, monitorClasses, attrMap,
- new HashMap<AttributeType,List<Attribute>>(0));
+ final Entry e = new Entry(entryDN, monitorClasses, attrMap,
+ new HashMap<AttributeType, List<Attribute>>(0));
e.processVirtualAttributes();
return e;
}
-
-
/**
- * {@inheritDoc}
- */
- @Override()
- public void addEntry(Entry entry, AddOperation addOperation)
- throws DirectoryException
- {
- Message message =
- ERR_MONITOR_ADD_NOT_SUPPORTED.get(String.valueOf(entry.getDN()));
- throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public void deleteEntry(DN entryDN, DeleteOperation deleteOperation)
- throws DirectoryException
- {
- Message message =
- ERR_MONITOR_DELETE_NOT_SUPPORTED.get(String.valueOf(entryDN));
- throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public void replaceEntry(Entry oldEntry, Entry newEntry,
- ModifyOperation modifyOperation) throws DirectoryException
- {
- Message message = ERR_MONITOR_MODIFY_NOT_SUPPORTED.get(
- String.valueOf(newEntry.getDN()), String.valueOf(configEntryDN));
- throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public void renameEntry(DN currentDN, Entry entry,
- ModifyDNOperation modifyDNOperation)
- throws DirectoryException
- {
- Message message =
- ERR_MONITOR_MODIFY_DN_NOT_SUPPORTED.get(String.valueOf(currentDN));
- throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public synchronized void search(SearchOperation searchOperation)
- throws DirectoryException
- {
-
- // Get the base DN, scope, and filter for the search.
- DN baseDN = searchOperation.getBaseDN();
- SearchScope scope = searchOperation.getScope();
- SearchFilter filter = searchOperation.getFilter();
-
-
- // Make sure the base entry exists if it's supposed to be in this backend.
- this.initEntryMaps();
- Entry baseEntry = entryMap.get(baseDN);
- if ((baseEntry == null) && handlesEntry(baseDN))
- {
- DN matchedDN = baseDN.getParentDNInSuffix();
- while (matchedDN != null)
- {
- if (entryMap.containsKey(matchedDN))
- {
- break;
- }
-
- matchedDN = matchedDN.getParentDNInSuffix();
- }
-
- Message message =
- ERR_MEMORYBACKEND_ENTRY_DOESNT_EXIST.get(String.valueOf(baseDN));
- throw new DirectoryException(
- ResultCode.NO_SUCH_OBJECT, message, matchedDN, null);
- }
-
- if (baseEntry != null)
- {
- baseEntry = baseEntry.duplicate(true);
- }
-
-
- // If it's a base-level search, then just get that entry and return it if it
- // matches the filter.
- if (scope == SearchScope.BASE_OBJECT)
- {
- if (filter.matchesEntry(baseEntry))
- {
- searchOperation.returnEntry(baseEntry, null);
- }
- }
- else
- {
- // Walk through all entries and send the ones that match.
- for (Entry e : entryMap.values()) {
- boolean matched = filter.matchesEntry(e);
- if (matched) {
- if (e.matchesBaseAndScope(baseDN, scope)==true) {
- searchOperation.returnEntry(e, null);
- }
- }
- }
- }
- }
-
- // Build the internal monitor tree (entries, and children)
- private synchronized void initEntryMaps() {
- this.entryMap.clear();
- this.childDNs.clear();
- for (MonitorProvider<? extends MonitorProviderCfg> monitorProvider :
- DirectoryServer.getMonitorProviders().values()) {
- try {
- DN providerdn =
- DirectoryServer.getMonitorProviderDN(monitorProvider);
- if (!entryMap.containsKey(providerdn)) {
- getAndAddParentInMaps(providerdn);
- Entry entry = getEntry(providerdn);
- entryMap.put(providerdn, entry);
- }
- } catch (Exception ex) {
- if (debugEnabled()) {
- TRACER.debugCaught(DebugLogLevel.ERROR, ex);
- }
- }
- }
- }
-
- /**
- * Recursively builds the entryMap and the childDN Map.
- */
- private void getAndAddParentInMaps(DN providerDN)
- {
- try
- {
- DN parentdn = providerDN.getParentDNInSuffix();
- DN child = providerDN;
-
- if ((parentdn != null) && (!entryMap.containsKey(parentdn)))
- {
- getAndAddParentInMaps(parentdn);
- entryMap.put(parentdn, getEntry(parentdn));
- }
-
- if (childDNs.containsKey(parentdn))
- {
- HashSet<DN> children = childDNs.get(parentdn);
- children.add(child);
- childDNs.put(parentdn, children);
- }
- else
- {
- HashSet<DN> children = new HashSet<DN>();
- children.add(child);
- childDNs.put(parentdn, children);
- }
- } catch (Exception e) {
- if (debugEnabled()) {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public HashSet<String> getSupportedControls()
- {
- return supportedControls;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public HashSet<String> getSupportedFeatures()
- {
- return supportedFeatures;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public boolean supportsLDIFExport()
- {
- // We can export all the monitor entries as a point-in-time snapshot.
- // TODO implementation of export is incomplete
- // TODO export-ldif reports nonsense for upTime etc.
- return false;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public void exportLDIF(LDIFExportConfig exportConfig)
- throws DirectoryException
- {
- // TODO export-ldif reports nonsense for upTime etc.
-
- // Create the LDIF writer.
- LDIFWriter ldifWriter;
- try
- {
- ldifWriter = new LDIFWriter(exportConfig);
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
-
- Message message = ERR_ROOTDSE_UNABLE_TO_CREATE_LDIF_WRITER.get(
- stackTraceToSingleLineString(e));
- throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
- message);
- }
-
-
- // Write the base monitor entry to the LDIF.
- try
- {
- ldifWriter.writeEntry(getBaseMonitorEntry());
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
-
- try
- {
- ldifWriter.close();
- }
- catch (Exception e2)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e2);
- }
- }
-
- Message message = ERR_MONITOR_UNABLE_TO_EXPORT_BASE.get(
- stackTraceToSingleLineString(e));
- throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
- message);
- }
-
-
- // Get all the monitor providers, convert them to entries, and write them to
- // LDIF.
- for (MonitorProvider<?> monitorProvider :
- DirectoryServer.getMonitorProviders().values())
- {
- try
- {
- // TODO implementation of export is incomplete
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
-
- try
- {
- ldifWriter.close();
- }
- catch (Exception e2)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e2);
- }
- }
-
- Message message = ERR_MONITOR_UNABLE_TO_EXPORT_PROVIDER_ENTRY.
- get(monitorProvider.getMonitorInstanceName(),
- stackTraceToSingleLineString(e));
- throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
- message);
- }
- }
-
-
- // Close the monitor provider and return.
- try
- {
- ldifWriter.close();
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
- }
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public boolean supportsLDIFImport()
- {
- // This backend does not support LDIF imports.
- return false;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public LDIFImportResult importLDIF(LDIFImportConfig importConfig)
- throws DirectoryException
- {
- // This backend does not support LDIF imports.
- Message message = ERR_MONITOR_IMPORT_NOT_SUPPORTED.get();
- throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public boolean supportsBackup()
- {
- // This backend does not provide a backup/restore mechanism.
- return false;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public boolean supportsBackup(BackupConfig backupConfig,
- StringBuilder unsupportedReason)
- {
- // This backend does not provide a backup/restore mechanism.
- return false;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public void createBackup(BackupConfig backupConfig)
- throws DirectoryException
- {
- // This backend does not provide a backup/restore mechanism.
- Message message = ERR_MONITOR_BACKUP_AND_RESTORE_NOT_SUPPORTED.get();
- throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public void removeBackup(BackupDirectory backupDirectory,
- String backupID)
- throws DirectoryException
- {
- // This backend does not provide a backup/restore mechanism.
- Message message = ERR_MONITOR_BACKUP_AND_RESTORE_NOT_SUPPORTED.get();
- throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public boolean supportsRestore()
- {
- // This backend does not provide a backup/restore mechanism.
- return false;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public void restoreBackup(RestoreConfig restoreConfig)
- throws DirectoryException
- {
- // This backend does not provide a backup/restore mechanism.
- Message message = ERR_MONITOR_BACKUP_AND_RESTORE_NOT_SUPPORTED.get();
- throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public boolean isConfigurationChangeAcceptable(
- MonitorBackendCfg backendCfg,
- List<Message> unacceptableReasons)
- {
- // We'll pretty much accept anything here as long as it isn't one of our
- // private attributes.
- return true;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public ConfigChangeResult applyConfigurationChange(
- MonitorBackendCfg backendCfg)
- {
- ResultCode resultCode = ResultCode.SUCCESS;
- boolean adminActionRequired = false;
- ArrayList<Message> messages = new ArrayList<Message>();
-
-
- // Check to see if there is a new set of user-defined attributes.
- ArrayList<Attribute> userAttrs = new ArrayList<Attribute>();
- try
- {
- ConfigEntry configEntry = DirectoryServer.getConfigEntry(configEntryDN);
- for (List<Attribute> attrs :
- configEntry.getEntry().getUserAttributes().values())
- {
- for (Attribute a : attrs)
- {
- if (! isMonitorConfigAttribute(a))
- {
- userAttrs.add(a);
- }
- }
- }
- for (List<Attribute> attrs :
- configEntry.getEntry().getOperationalAttributes().values())
- {
- for (Attribute a : attrs)
- {
- if (! isMonitorConfigAttribute(a))
- {
- userAttrs.add(a);
- }
- }
- }
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
-
-
- messages.add(ERR_CONFIG_BACKEND_ERROR_INTERACTING_WITH_BACKEND_ENTRY.get(
- String.valueOf(configEntryDN),
- stackTraceToSingleLineString(e)));
- resultCode = DirectoryServer.getServerErrorResultCode();
- }
-
-
- userDefinedAttributes = userAttrs;
-
- Message message = INFO_MONITOR_USING_NEW_USER_ATTRS.get();
- messages.add(message);
-
-
- currentConfig = backendCfg;
- return new ConfigChangeResult(resultCode, adminActionRequired, messages);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void preloadEntryCache() throws UnsupportedOperationException {
- throw new UnsupportedOperationException("Operation not supported.");
- }
-
- // Private Methods
- private boolean isATreeNode(DN dn) {
- boolean found=false;
-
- if (dn.equals(baseMonitorDN)) {
- return true;
- }
- for (MonitorProvider<? extends MonitorProviderCfg> monitorProvider :
- DirectoryServer.getMonitorProviders().values()) {
- DN providerDN = DirectoryServer.getMonitorProviderDN(monitorProvider);
- if ((dn.isAncestorOf(providerDN)) ||
- (dn.equals(providerDN))) {
- found=true;
- return (found);
- }
- }
- return (found);
- }
-
- private String getRdns(DN dn) {
- int index = dn.toString().lastIndexOf(",");
- return dn.toString().substring(3, index);
- }
-
- /**
- * Creates an attribute for a monitor entry with the following criteria.
+ * Indicates whether the provided attribute is one that is used in the
+ * configuration of this backend.
*
- * @param name The name for the attribute.
- * @param lowerName The name for the attribute formatted in all lowercase
- * characters.
- * @param value The value to use for the attribute.
- *
- * @return The constructed attribute.
+ * @param attribute
+ * The attribute for which to make the determination.
+ * @return <CODE>true</CODE> if the provided attribute is one that is used in
+ * the configuration of this backend, <CODE>false</CODE> if not.
*/
- private Attribute createAttribute(String name, String lowerName,
- String value) {
- return Attributes.create(name, value);
+ private boolean isMonitorConfigAttribute(final Attribute attribute)
+ {
+ final AttributeType attrType = attribute.getAttributeType();
+ if (attrType.hasName(ATTR_COMMON_NAME)
+ || attrType.hasName(ATTR_BACKEND_ENABLED.toLowerCase())
+ || attrType.hasName(ATTR_BACKEND_CLASS.toLowerCase())
+ || attrType.hasName(ATTR_BACKEND_BASE_DN.toLowerCase())
+ || attrType.hasName(ATTR_BACKEND_ID.toLowerCase())
+ || attrType.hasName(ATTR_BACKEND_WRITABILITY_MODE.toLowerCase()))
+ {
+ return true;
+ }
+
+ return false;
}
}
--
Gitblit v1.10.0