mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

jvergara
23.16.2007 6bc9517c206b0b8d7cfec7ea4abb7f9dfad535ac
Fix for issue 2505 (Provide monitoring information about the number of entries on a given base DN)

The following changes are aimed to include a new attribute in the backend monitor entry to provide the number or entries per base DN. This information is used by the status, status-panel, dsreplication and graphical setup to be able to display the number of entries under a given base DN even when there are several base DNs defined in the same database.

The way the new attribute appears in the monitoring entry is:

ldapsearch -w s -p 1389 -b cn=monitor ds-backend-id=userRoot ds-base-dn-entry-countdn: cn=userRoot Backend,cn=monitor
ds-base-dn-entry-count: 0 dc=ta
ds-base-dn-entry-count: 1 dc=ti
ds-base-dn-entry-count: 1 dc=to

I prefer this approach because in my opinion having the number of entries is more important that the suffix. Anyway I think the discussion around the structure of the value is not crucial as long as the value is easy to parse (which is the case).

The new attribute is defined in the schema and the new OID assigned to it is 1.3.6.1.4.1.26027.1.1.434.

In order to have a minimum impact on performances, the method backend.numSubordinates is only called when there are several base DNs defined in the database.



9 files modified
234 ■■■■ changed files
opends/resource/schema/02-config.ldif 6 ●●●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/ServerDescriptor.java 57 ●●●● patch | view | raw | blame | history
opends/src/guitools/org/opends/guitools/statuspanel/BaseDNDescriptor.java 24 ●●●●● patch | view | raw | blame | history
opends/src/guitools/org/opends/guitools/statuspanel/ConfigFromFile.java 2 ●●● patch | view | raw | blame | history
opends/src/guitools/org/opends/guitools/statuspanel/ConfigFromLDAP.java 62 ●●●●● patch | view | raw | blame | history
opends/src/guitools/org/opends/guitools/statuspanel/ui/DatabasesTableModel.java 22 ●●●● patch | view | raw | blame | history
opends/src/messages/messages/admin_tool.properties 1 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/monitors/BackendMonitor.java 54 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/util/ServerConstants.java 6 ●●●●● patch | view | raw | blame | history
opends/resource/schema/02-config.ldif
@@ -2128,6 +2128,11 @@
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
  SINGLE-VALUE
  X-ORIGIN 'OpenDS Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.26027.1.1.434
  NAME 'ds-base-dn-entry-count'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
  SINGLE-VALUE
  X-ORIGIN 'OpenDS Directory Server' )
objectClasses: ( 1.3.6.1.4.1.26027.1.2.1
  NAME 'ds-cfg-access-control-handler'
  SUP top
@@ -2900,6 +2905,7 @@
  MAY ( ds-backend-id $
        ds-backend-base-dn $
        ds-backend-entry-count $
        ds-base-dn-entry-count $
        ds-backend-writability-mode $
        ds-backend-is-private )
  X-ORIGIN 'OpenDS Directory Server' )
opends/src/ads/org/opends/admin/ads/ServerDescriptor.java
@@ -681,7 +681,7 @@
      {
        Set<String> baseDns = getValues(sr, "ds-cfg-base-dn");
        int nEntries = getEntryCount(ctx, id);
        Set<String> entries = getBaseDNEntryCount(ctx, id);
        Set<ReplicaDescriptor> replicas = desc.getReplicas();
        for (String baseDn : baseDns)
@@ -695,16 +695,29 @@
          r.add(replica);
          suffix.setReplicas(r);
          replica.setSuffix(suffix);
          if (baseDns.size() == 1)
          int nEntries = -1;
          for (String s : entries)
          {
            int index = s.indexOf(" ");
            if (index != -1)
            {
              String dn = s.substring(index + 1);
              if (Utils.areDnsEqual(baseDn, dn))
              {
                try
                {
                  nEntries = Integer.parseInt(s.substring(0, index));
                }
                catch (Throwable t)
                {
                  /* Ignore */
                }
                break;
              }
            }
          }
            replica.setEntries(nEntries);
          }
          else
          {
            /* Cannot know how many entries correspond to this replica */
            replica.setEntries(-1);
          }
        }
        desc.setReplicas(replicas);
      }
    }
@@ -1031,23 +1044,22 @@
  }
  /**
   * Returns the number of entries in a given backend using the provided
   * InitialLdapContext.
   * Returns the values of the ds-base-dn-entry count attributes for the given
   * backend monitor entry using the provided InitialLdapContext.
   * @param ctx the InitialLdapContext to use to update the configuration.
   * @param backendID the id of the backend.
   * @return the number of entries in the backend.
   * @return the values of the ds-base-dn-entry count attribute.
   * @throws NamingException if there was an error.
   */
  private static int getEntryCount(InitialLdapContext ctx, String backendID)
  throws NamingException
  private static Set<String> getBaseDNEntryCount(InitialLdapContext ctx,
      String backendID) throws NamingException
  {
    int nEntries = -1;
    String v = null;
    LinkedHashSet<String> v = new LinkedHashSet<String>();
    SearchControls ctls = new SearchControls();
    ctls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
    ctls.setReturningAttributes(
        new String[] {
            "ds-backend-entry-count"
            "ds-base-dn-entry-count"
        });
    String filter = "(ds-backend-id="+backendID+")";
@@ -1058,18 +1070,9 @@
    {
      SearchResult sr = (SearchResult)listeners.next();
      v = getFirstValue(sr, "ds-backend-entry-count");
      v.addAll(getValues(sr, "ds-base-dn-entry-count"));
    }
    try
    {
      nEntries = Integer.parseInt(v);
    }
    catch (Exception ex)
    {
      /* ignore */
    }
    return nEntries;
    return v;
  }
  /*
opends/src/guitools/org/opends/guitools/statuspanel/BaseDNDescriptor.java
@@ -56,6 +56,7 @@
    REPLICATED
  };
  private int nEntries;
  private int missingChanges;
  private DatabaseDescriptor db;
  private int ageOfOldestMissingChange;
@@ -71,15 +72,17 @@
   * @param type the type of replication.
   * @param baseDn the base DN associated with the Replication.
   * @param db the database containing this base DN.
   * @param nEntries the number of entries for the base DN.
   * @param ageOfOldestMissingChange the number of missing changes.
   * @param missingChanges the number of missing changes.
   */
  public BaseDNDescriptor(Type type, String baseDn, DatabaseDescriptor db,
      int ageOfOldestMissingChange, int missingChanges)
      int nEntries, int ageOfOldestMissingChange, int missingChanges)
  {
    this.baseDn = baseDn;
    this.db = db;
    this.type = type;
    this.nEntries = nEntries;
    this.ageOfOldestMissingChange = ageOfOldestMissingChange;
    this.missingChanges = missingChanges;
    try
@@ -130,7 +133,7 @@
        (getMissingChanges() == desc.getMissingChanges()) &&
        getDatabase().getBackendID().equals(
            desc.getDatabase().getBackendID()) &&
        (getDatabase().getEntries() == desc.getDatabase().getEntries());
        (getEntries() == desc.getEntries());
      }
    }
    else
@@ -162,6 +165,14 @@
    return returnValue;
  }
  /**
   * Returns the number of entries in the database for this base DN.
   * @return the number of entries in the database for this base DN.
   */
  public int getEntries()
  {
    return nEntries;
  }
  /**
   * Returns the number of missing changes in the replication topology for
@@ -221,6 +232,15 @@
    this.db = db;
  }
  /**
   * Sets the number of entries for this base DN in this database.
   * @param nEntries the number of entries.
   */
  void setEntries(int nEntries)
  {
    this.nEntries = nEntries;
  }
  private String unescapeUtf8(String v) throws UnsupportedEncodingException
  {
    byte[] stringBytes = v.getBytes("UTF-8");
opends/src/guitools/org/opends/guitools/statuspanel/ConfigFromFile.java
@@ -730,6 +730,6 @@
  private BaseDNDescriptor getBaseDNDescriptor(Entry entry, String baseDn)
  {
    return new BaseDNDescriptor(BaseDNDescriptor.Type.NOT_REPLICATED,
        baseDn, null, -1, -1);
        baseDn, null, -1, -1, -1);
  }
}
opends/src/guitools/org/opends/guitools/statuspanel/ConfigFromLDAP.java
@@ -29,6 +29,7 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;
@@ -43,6 +44,7 @@
import javax.naming.ldap.LdapName;
import org.opends.admin.ads.util.ApplicationTrustManager;
import org.opends.admin.ads.util.ConnectionUtils;
import org.opends.quicksetup.util.Utils;
import org.opends.messages.Message;
@@ -798,8 +800,8 @@
      type = BaseDNDescriptor.Type.NOT_REPLICATED;
    }
    return new BaseDNDescriptor(type, baseDn, null, ageOfOldestMissingChange,
      missingChanges);
    return new BaseDNDescriptor(type, baseDn, null, -1,
        ageOfOldestMissingChange, missingChanges);
  }
  /**
@@ -932,13 +934,35 @@
      Set<String> baseDns = getValues(entry, "ds-cfg-base-dn");
      TreeSet<BaseDNDescriptor> replicas = new TreeSet<BaseDNDescriptor>();
      int nEntries = getEntryCount(ctx, id);
      Set<String> baseDnEntries = getBaseDNEntryCount(ctx, id);
      DatabaseDescriptor db = new DatabaseDescriptor(id, replicas, nEntries);
      for (String baseDn : baseDns)
      {
        BaseDNDescriptor rep = getBaseDNDescriptor(ctx, baseDn);
        rep.setDatabase(db);
        nEntries = -1;
        for (String s : baseDnEntries)
        {
          int index = s.indexOf(" ");
          if (index != -1)
          {
            String dn = s.substring(index +1);
            if (Utils.areDnsEqual(baseDn, dn))
            {
              try
              {
                nEntries = Integer.parseInt(s.substring(0, index));
              }
              catch (Throwable t)
              {
                /* Ignore */
              }
              break;
            }
          }
        }
        rep.setEntries(nEntries);
        db.getBaseDns().add(rep);
      }
@@ -1019,4 +1043,36 @@
  {
    return ConfigFromFile.isConfigBackend(id);
  }
  /**
   * Returns the values of the ds-base-dn-entry count attributes for the given
   * backend monitor entry using the provided InitialLdapContext.
   * @param ctx the InitialLdapContext to use to update the configuration.
   * @param backendID the id of the backend.
   * @return the values of the ds-base-dn-entry count attribute.
   * @throws NamingException if there was an error.
   */
  private static Set<String> getBaseDNEntryCount(InitialLdapContext ctx,
      String backendID) throws NamingException
  {
    LinkedHashSet<String> v = new LinkedHashSet<String>();
    SearchControls ctls = new SearchControls();
    ctls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
    ctls.setReturningAttributes(
        new String[] {
            "ds-base-dn-entry-count"
        });
    String filter = "(ds-backend-id="+backendID+")";
    LdapName jndiName = new LdapName("cn=monitor");
    NamingEnumeration listeners = ctx.search(jndiName, filter, ctls);
    while(listeners.hasMore())
    {
      SearchResult sr = (SearchResult)listeners.next();
      v.addAll(ConnectionUtils.getValues(sr, "ds-base-dn-entry-count"));
    }
    return v;
  }
}
opends/src/guitools/org/opends/guitools/statuspanel/ui/DatabasesTableModel.java
@@ -413,8 +413,8 @@
  private int compareEntries(BaseDNDescriptor desc1, BaseDNDescriptor desc2)
  {
    int n1 = desc1.getDatabase().getEntries();
    int n2 = desc2.getDatabase().getEntries();
    int n1 = desc1.getEntries();
    int n2 = desc2.getEntries();
    return compareIntegers(n1, n2);
  }
@@ -458,27 +458,13 @@
  /**
   * Returns the Object describing the number of entries of a given Base DN.
   * The Object will be an Integer unless the database of the Base DN contains
   * several Base DNs.  In this case we return a String.
   * The Object will be an Integer.
   * @param rep the Base DN object to handle.
   * @return the Object describing the number of entries of a given Base DN.
   */
  private Object getValueForEntries(BaseDNDescriptor rep)
  {
    Object v;
    int nEntries = rep.getDatabase().getEntries();
    if ((rep.getDatabase().getBaseDns().size() > 1) &&
      (nEntries >= 0))
    {
      v = INFO_NUMBER_ENTRIES_MULTIPLE_SUFFIXES_IN_DB.get(
              String.valueOf(nEntries),
              rep.getDatabase().getBackendID());
    }
    else
    {
      v = new Integer(nEntries);
    }
    return v;
    return rep.getEntries();
  }
  /**
opends/src/messages/messages/admin_tool.properties
@@ -257,7 +257,6 @@
INFO_NOTHING_SELECTED_TO_UNINSTALL=You must select something to be \
 uninstalled.
INFO_NUMBER_ENTRIES_COLUMN=Entries
INFO_NUMBER_ENTRIES_MULTIPLE_SUFFIXES_IN_DB=%s (for all base DNs in %s)
INFO_OPENDS_VERSION_LABEL=OpenDS Version:
INFO_PROGRESS_REMOVING_REFERENCES=Removing references on %s
INFO_PROTOCOL_COLUMN=Protocol
opends/src/server/org/opends/server/monitors/BackendMonitor.java
@@ -35,15 +35,19 @@
import org.opends.server.admin.std.server.MonitorProviderCfg;
import org.opends.server.api.Backend;
import org.opends.server.api.MonitorProvider;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.schema.BooleanSyntax;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.ByteStringFactory;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DirectoryConfig;
import org.opends.server.types.DN;
import org.opends.server.types.ObjectClass;
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.*;
@@ -65,6 +69,10 @@
  // The attribute type that will be used to report the number of entries.
  private AttributeType entryCountType;
  // The attribute type that will be used to report the number of entries per
  // base DN.
  private AttributeType baseDNEntryCountType;
  // The attribute type that will be used to indicate if a backend is private.
  private AttributeType isPrivateType;
@@ -77,7 +85,10 @@
  // The name for this monitor.
  private String monitorName;
  /**
   * The tracer object for the debug logger.
   */
  private static final DebugTracer TRACER = getTracer();
  /**
   * Creates a new instance of this backend monitor provider that will work with
@@ -113,6 +124,10 @@
         DirectoryConfig.getAttributeType(ATTR_MONITOR_BACKEND_ENTRY_COUNT,
                                          true);
    baseDNEntryCountType =
         DirectoryConfig.getAttributeType(ATTR_MONITOR_BASE_DN_ENTRY_COUNT,
                                          true);
    isPrivateType =
         DirectoryConfig.getAttributeType(ATTR_MONITOR_BACKEND_IS_PRIVATE,
                                          true);
@@ -196,12 +211,47 @@
                            values));
    values = new LinkedHashSet<AttributeValue>();
    long backendCount = backend.getEntryCount();
    values.add(new AttributeValue(entryCountType,
         ByteStringFactory.create(String.valueOf(backend.getEntryCount()))));
         ByteStringFactory.create(String.valueOf(backendCount))));
    attrs.add(new Attribute(entryCountType, ATTR_MONITOR_BACKEND_ENTRY_COUNT,
                            values));
    values = new LinkedHashSet<AttributeValue>();
    if (baseDNs.length != 1)
    {
      for (DN dn : baseDNs)
      {
        long entryCount = -1;
        try
        {
          entryCount = backend.numSubordinates(dn, true) + 1;
        }
        catch (Exception ex)
        {
          if (debugEnabled())
          {
            TRACER.debugCaught(DebugLogLevel.ERROR, ex);
          }
        }
        String s = entryCount + " " + dn.toString();
        values.add(new AttributeValue(baseDNEntryCountType,
            ByteStringFactory.create(s)));
      }
    }
    else
    {
      // This is done to avoid recalculating the number of entries using the
      // hasNumSubordinates method in the case where the backend has a single
      // base DN.
      String s = backendCount + " " + baseDNs[0].toString();
      values.add(new AttributeValue(baseDNEntryCountType,
          ByteStringFactory.create(s)));
    }
    attrs.add(new Attribute(baseDNEntryCountType,
        ATTR_MONITOR_BASE_DN_ENTRY_COUNT, values));
    values = new LinkedHashSet<AttributeValue>();
    values.add(new AttributeValue(writabilityModeType,
         ByteStringFactory.create(
              String.valueOf(backend.getWritabilityMode()))));
opends/src/server/org/opends/server/util/ServerConstants.java
@@ -255,6 +255,12 @@
       "ds-backend-entry-count";
  /**
   * The name of the monitor attribute that is used to hold the base DN entry
   * count.
   */
  public static final String ATTR_MONITOR_BASE_DN_ENTRY_COUNT =
       "ds-base-dn-entry-count";
  /**
   * The name of the monitor attribute that is used to hold the backend