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

Matthew Swift
28.28.2015 fda423b1444815ac01dd9b3adeb0061cb5236a81
OPENDJ-2343: minor usability improvements to backendstat tool

Renamed sub-commands to use terminology which is more familiar to end-
users:

High-level sub-commands:

* list-backends - lists pluggable backends
* list-base-dns - lists base DNs of a pluggable backend
* list-indexes - lists all indexes within a backend/baseDN
* show-index-status - shows summary of attribute indexes within
a backend/baseDN
* dump-index - dumps an index and decodes key/values

Low-level sub-commands:

* list-raw-dbs - lists underlying databases within a backend
* dump-raw-db - dumps raw hex content of a database.

In addition, command line options have been updated to avoid terms like
"storage", "tree", "entry container", and "root container".
4 files modified
175 ■■■■ changed files
opendj-server-legacy/src/main/docbkx/man-pages/backendstat-examples.xml 2 ●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/docbkx/man-pages/variablelist-backendstat-index-status.xml 6 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/BackendStat.java 126 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/messages/org/opends/messages/tool.properties 41 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/docbkx/man-pages/backendstat-examples.xml
@@ -36,7 +36,7 @@
 </para>
 <screen>
$ <userinput>bin/backendstat dump-tree  -n userRoot -b dc=example,dc=com -t id2childrencount </userinput>
$ <userinput>bin/backendstat dump-index  -n userRoot -b dc=example,dc=com -i id2childrencount </userinput>
<computeroutput>
    Key (len 2): 1#52
    Value (len 8): 1
opendj-server-legacy/src/main/docbkx/man-pages/variablelist-backendstat-index-status.xml
@@ -31,7 +31,7 @@
                                  http://docbook.org/xml/5.0/xsd/docbook.xsd'>
 <para>
  When you run the 'list-index-status' command, the result is a table, followed by a "Total",
  When you run the 'show-index-status' command, the result is a table, followed by a "Total",
  which is the total number of indexes, followed by a list of indexes with "Over index-entry-limit keys" to
  show the values for which the number of entries exceeded the index entry limit.
  The table has the following columns.
@@ -53,10 +53,10 @@
 </varlistentry>
 <varlistentry>
  <term>Tree Name</term>
  <term>Raw DB Name</term>
  <listitem>
   <para>
    Name of the backend tree, which reflects how OpenDJ directory server organizes the data in the database.
    The internal name of the database within the storage which OpenDJ directory server is using for the index.
   </para>
   <para>
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/BackendStat.java
@@ -240,13 +240,15 @@
  private static final Option<Integer> DUMP_MAX_DATA_SIZE = Option.of(Integer.class, Integer.MAX_VALUE);
  private static final Option<Integer> DUMP_INDENT = Option.of(Integer.class, 4);
  private static final String LIST_STORAGE_TREES = "list-storage-trees";
  private static final String DUMP_STORAGE_TREE = "dump-storage-tree";
  private static final String LIST_BACKEND_TREES = "list-trees";
  private static final String DUMP_TREE = "dump-tree";
  private static final String LIST_ROOT_CONTAINERS = "list-root-containers";
  private static final String LIST_ENTRY_CONTAINERS = "list-entry-containers";
  private static final String LIST_INDEX_STATUS = "list-index-status";
  // Sub-command names.
  private static final String LIST_BACKENDS = "list-backends";
  private static final String LIST_BASE_DNS = "list-base-dns";
  private static final String LIST_INDEXES = "list-indexes";
  private static final String SHOW_INDEX_STATUS = "show-index-status";
  private static final String DUMP_INDEX = "dump-index";
  private static final String LIST_RAW_DBS = "list-raw-dbs";
  private static final String DUMP_RAW_DB = "dump-raw-db";
  private static final String BACKENDID_NAME = "backendid";
  private static final String BACKENDID = "backendID";
  private static final String BASEDN_NAME = "basedn";
@@ -269,8 +271,10 @@
  private static final String SKIPDECODE = "skipDecode";
  private static final String STATSONLY_NAME = "statsonly";
  private static final String STATSONLY = "statsOnly";
  private static final String TREENAME_NAME = "treename";
  private static final String TREENAME = "treeName";
  private static final String INDEXNAME_NAME = "indexname";
  private static final String INDEXNAME = "indexName";
  private static final String DBNAME_NAME = "dbname";
  private static final String DBNAME = "dbName";
  private static final String SINGLELINE_NAME = "singleline";
  private static final String SINGLELINE = "singleLine";
@@ -390,41 +394,52 @@
  {
    if (!subCommandsInitialized)
    {
      SubCommand sub;
      // list-backends
      new SubCommand(parser, LIST_BACKENDS,
                           INFO_DESCRIPTION_BACKEND_TOOL_SUBCMD_LIST_BACKENDS.get());
      sub = new SubCommand(parser, LIST_ROOT_CONTAINERS,
          INFO_DESCRIPTION_BACKEND_TOOL_SUBCMD_LIST_ROOT_CONTAINERS.get());
      sub = new SubCommand(parser, LIST_ENTRY_CONTAINERS,
          INFO_DESCRIPTION_BACKEND_DEBUG_SUBCMD_LIST_ENTRY_CONTAINERS.get());
      // list-base-dns
      SubCommand sub = new SubCommand(parser, LIST_BASE_DNS,
                                      INFO_DESCRIPTION_BACKEND_DEBUG_SUBCMD_LIST_ENTRY_CONTAINERS.get());
      addBackendArgument(sub);
      sub = new SubCommand(parser, LIST_STORAGE_TREES, INFO_DESCRIPTION_BACKEND_TOOL_SUBCMD_LIST_STORAGE_TREES.get());
      addBackendArgument(sub);
      BooleanArgument useSIUnits =
          new BooleanArgument(USESIUNITS_NAME, 'u', USESIUNITS, INFO_DESCRIPTION_BACKEND_TOOL_USE_SI_UNITS.get());
      sub.addArgument(useSIUnits);
      sub = new SubCommand(parser, LIST_BACKEND_TREES, INFO_DESCRIPTION_BACKEND_TOOL_SUBCMD_LIST_TREES.get());
      // list-indexes
      sub = new SubCommand(parser, LIST_INDEXES, INFO_DESCRIPTION_BACKEND_TOOL_SUBCMD_LIST_INDEXES.get());
      addBackendBaseDNArguments(sub, false, false, true);
      sub = new SubCommand(parser, DUMP_STORAGE_TREE, INFO_DESCRIPTION_BACKEND_TOOL_SUBCMD_DUMP_STORAGE_TREE.get());
      addBackendArgument(sub);
      addDumpSubCommandArguments(sub);
      BooleanArgument singleLine =
          new BooleanArgument(SINGLELINE_NAME, 'l', SINGLELINE, INFO_DESCRIPTION_BACKEND_TOOL_SUBCMD_SINGLE_LINE.get());
      sub.addArgument(singleLine);
      // show-index-status
      sub = new SubCommand(parser, SHOW_INDEX_STATUS, INFO_DESCRIPTION_BACKEND_DEBUG_SUBCMD_LIST_INDEX_STATUS.get());
      sub.setDocDescriptionSupplement(SUPPLEMENT_DESCRIPTION_BACKEND_TOOL_SUBCMD_LIST_INDEX_STATUS.get());
      addBackendBaseDNArguments(sub, true, true, true);
      sub = new SubCommand(parser, DUMP_TREE, INFO_DESCRIPTION_BACKEND_TOOL_SUBCMD_DUMP_TREE.get());
      // dump-index
      sub = new SubCommand(parser, DUMP_INDEX, INFO_DESCRIPTION_BACKEND_TOOL_SUBCMD_DUMP_INDEX.get());
      addBackendBaseDNArguments(sub, true, false, true);
      sub.addArgument(new StringArgument(INDEXNAME_NAME, 'i', INDEXNAME, true, false, true,
                                         INFO_INDEX_NAME_PLACEHOLDER.get(), null, null,
                                         INFO_DESCRIPTION_BACKEND_DEBUG_INDEX_NAME.get()));
      addDumpSubCommandArguments(sub);
      BooleanArgument skipDecode =
          new BooleanArgument(SKIPDECODE_NAME, 'p', SKIPDECODE, INFO_DESCRIPTION_BACKEND_DEBUG_SKIP_DECODE.get());
      sub.addArgument(skipDecode);
      sub = new SubCommand(parser, LIST_INDEX_STATUS, INFO_DESCRIPTION_BACKEND_DEBUG_SUBCMD_LIST_INDEX_STATUS.get());
      sub.setDocDescriptionSupplement(SUPPLEMENT_DESCRIPTION_BACKEND_TOOL_SUBCMD_LIST_INDEX_STATUS.get());
      addBackendBaseDNArguments(sub, true, true, true);
      // list-raw-dbs
      sub = new SubCommand(parser, LIST_RAW_DBS, INFO_DESCRIPTION_BACKEND_TOOL_SUBCMD_LIST_RAW_DBS.get());
      addBackendArgument(sub);
      BooleanArgument useSIUnits =
          new BooleanArgument(USESIUNITS_NAME, 'u', USESIUNITS, INFO_DESCRIPTION_BACKEND_TOOL_USE_SI_UNITS.get());
      sub.addArgument(useSIUnits);
      // dump-raw-db
      sub = new SubCommand(parser, DUMP_RAW_DB, INFO_DESCRIPTION_BACKEND_TOOL_SUBCMD_DUMP_RAW_DB.get());
      addBackendArgument(sub);
      sub.addArgument(new StringArgument(DBNAME_NAME, 'd', DBNAME, true, false, true,
                                         INFO_DATABASE_NAME_PLACEHOLDER.get(), null, null,
                                         INFO_DESCRIPTION_BACKEND_DEBUG_RAW_DB_NAME.get()));
      addDumpSubCommandArguments(sub);
      BooleanArgument singleLine =
          new BooleanArgument(SINGLELINE_NAME, 'l', SINGLELINE, INFO_DESCRIPTION_BACKEND_TOOL_SUBCMD_SINGLE_LINE.get());
      sub.addArgument(singleLine);
      subCommandsInitialized = true;
    }
@@ -447,9 +462,6 @@
  private void addDumpSubCommandArguments(SubCommand sub) throws ArgumentException
  {
    sub.addArgument(
        new StringArgument(TREENAME_NAME, 't', TREENAME, true, false, true, INFO_DATABASE_NAME_PLACEHOLDER.get(), null,
            null, INFO_DESCRIPTION_BACKEND_DEBUG_INDEX_NAME.get()));
    sub.addArgument(new BooleanArgument(STATSONLY_NAME, 'q', STATSONLY,
        INFO_DESCRIPTION_BACKEND_DEBUG_STATS_ONLY.get()));
    sub.addArgument(newMaxKeyValueArg());
@@ -585,7 +597,7 @@
    }
    SubCommand subCommand = parser.getSubCommand();
    if (LIST_ROOT_CONTAINERS.equals(subCommand.getName()))
    if (LIST_BACKENDS.equals(subCommand.getName()))
    {
      return listRootContainers();
    }
@@ -603,18 +615,18 @@
    {
      switch (subCommand.getName())
      {
      case LIST_ENTRY_CONTAINERS:
        return listEntryContainers(rootContainer);
      case LIST_STORAGE_TREES:
        return listStorageTrees(rootContainer, subCommand.getArgument(USESIUNITS_NAME));
      case LIST_BACKEND_TREES:
        return listBackendTrees(rootContainer, backend, subCommand.getArgument(BASEDN_NAME));
      case DUMP_STORAGE_TREE:
      case LIST_BASE_DNS:
        return listBaseDNs(rootContainer);
      case LIST_RAW_DBS:
        return listRawDBs(rootContainer, subCommand.getArgument(USESIUNITS_NAME));
      case LIST_INDEXES:
        return listIndexes(rootContainer, backend, subCommand.getArgument(BASEDN_NAME));
      case DUMP_RAW_DB:
        return dumpTree(rootContainer, backend, subCommand, false);
      case DUMP_TREE:
      case DUMP_INDEX:
        return dumpTree(rootContainer, backend, subCommand, true);
      case LIST_INDEX_STATUS:
        return listIndexStatus(rootContainer, backend, subCommand.getArgument(BASEDN_NAME));
      case SHOW_INDEX_STATUS:
        return showIndexStatus(rootContainer, backend, subCommand.getArgument(BASEDN_NAME));
      default:
        return 1;
      }
@@ -651,10 +663,10 @@
    }
    if (isBackendTree)
    {
      return dumpBackendTree(rc, backend, subCommand.getArgument(BASEDN_NAME), subCommand.getArgument(TREENAME_NAME),
      return dumpBackendTree(rc, backend, subCommand.getArgument(BASEDN_NAME), subCommand.getArgument(INDEXNAME_NAME),
          options);
    }
    return dumpStorageTree(rc, backend, subCommand.getArgument(TREENAME_NAME), options);
    return dumpStorageTree(rc, backend, subCommand.getArgument(DBNAME_NAME), options);
  }
  private boolean setDumpTreeOptionArguments(SubCommand subCommand, Options options) throws ArgumentException
@@ -737,7 +749,7 @@
    return 0;
  }
  private int listEntryContainers(RootContainer rc)
  private int listBaseDNs(RootContainer rc)
  {
    try
    {
@@ -757,18 +769,18 @@
    }
    catch (StorageRuntimeException de)
    {
      printWrappedText(err, ERR_BACKEND_TOOL_ERROR_READING_ENTRY_CONTAINERS.get(stackTraceToSingleLineString(de)));
      printWrappedText(err, ERR_BACKEND_TOOL_ERROR_LISTING_BASE_DNS.get(stackTraceToSingleLineString(de)));
      return 1;
    }
  }
  private int listStorageTrees(RootContainer rc, Argument useSIUnits)
  private int listRawDBs(RootContainer rc, Argument useSIUnits)
  {
    try
    {
      TableBuilder builder = new TableBuilder();
      builder.appendHeading(INFO_LABEL_BACKEND_TOOL_STORAGE_TREE_NAME.get());
      builder.appendHeading(INFO_LABEL_BACKEND_TOOL_RAW_DB_NAME.get());
      builder.appendHeading(INFO_LABEL_BACKEND_TOOL_TOTAL_KEYS.get());
      builder.appendHeading(INFO_LABEL_BACKEND_TOOL_KEYS_SIZE.get());
      builder.appendHeading(INFO_LABEL_BACKEND_TOOL_VALUES_SIZE.get());
@@ -830,7 +842,7 @@
    }
  }
  private int listBackendTrees(RootContainer rc, BackendImpl backend, Argument baseDNArg) throws DirectoryException
  private int listIndexes(RootContainer rc, BackendImpl backend, Argument baseDNArg) throws DirectoryException
  {
    DN base = null;
    if (baseDNArg.isPresent())
@@ -844,9 +856,9 @@
      int count = 0;
      builder.appendHeading(INFO_LABEL_BACKEND_DEBUG_INDEX_NAME.get());
      builder.appendHeading(INFO_LABEL_BACKEND_TOOL_RAW_DB_NAME.get());
      builder.appendHeading(INFO_LABEL_BACKEND_DEBUG_INDEX_TYPE.get());
      builder.appendHeading(INFO_LABEL_BACKEND_DEBUG_RECORD_COUNT.get());
      builder.appendHeading(INFO_LABEL_BACKEND_TOOL_BACKEND_TREE_NAME.get());
      if (base != null)
      {
@@ -936,9 +948,9 @@
    {
      builder.startRow();
      builder.appendCell(tree.getName().getIndexId());
      builder.appendCell(tree.getName());
      builder.appendCell(tree.getClass().getSimpleName());
      builder.appendCell(getTreeRecordCount(ec, tree));
      builder.appendCell(tree.getName());
      count++;
    }
    return count;
@@ -1021,7 +1033,7 @@
    return null;
  }
  private int listIndexStatus(RootContainer rc, BackendImpl backend, Argument baseDNArg) throws DirectoryException
  private int showIndexStatus(RootContainer rc, BackendImpl backend, Argument baseDNArg) throws DirectoryException
  {
    DN base = getBaseDNFromArg(baseDNArg);
@@ -1032,7 +1044,7 @@
      int count = 0;
      builder.appendHeading(INFO_LABEL_BACKEND_DEBUG_INDEX_NAME.get());
      builder.appendHeading(INFO_LABEL_BACKEND_TOOL_BACKEND_TREE_NAME.get());
      builder.appendHeading(INFO_LABEL_BACKEND_TOOL_RAW_DB_NAME.get());
      builder.appendHeading(INFO_LABEL_BACKEND_DEBUG_INDEX_STATUS.get());
      builder.appendHeading(INFO_LABEL_BACKEND_DEBUG_RECORD_COUNT.get());
      builder.appendHeading(INFO_LABEL_BACKEND_TOOL_INDEX_UNDEFINED_RECORD_COUNT.get());
opendj-server-legacy/src/messages/org/opends/messages/tool.properties
@@ -1847,19 +1847,18 @@
INFO_DESCRIPTION_DBTEST_TOOL_1327=This utility can be used to debug the JE database
INFO_DESCRIPTION_DBTEST_SUBCMD_LIST_ROOT_CONTAINERS_1328=List the root \
  containers used by all JE backends
INFO_DESCRIPTION_BACKEND_DEBUG_SUBCMD_LIST_ENTRY_CONTAINERS_1329=List the entry \
  containers for a root container
INFO_DESCRIPTION_BACKEND_DEBUG_SUBCMD_LIST_ENTRY_CONTAINERS_1329=List the base DNs in a backend
INFO_DESCRIPTION_DBTEST_SUBCMD_DUMP_DATABASE_CONTAINER_1330=Dump records from \
  a database container. Depending on database size, \
  this subcommand can generate lots of output
INFO_DESCRIPTION_BACKEND_DEBUG_BACKEND_ID_1331=The backend ID of the backend to debug
INFO_DESCRIPTION_BACKEND_DEBUG_BASE_DN_1332=The base DN of the entry container to debug
INFO_DESCRIPTION_BACKEND_DEBUG_INDEX_NAME_1333=The name of the index to debug
INFO_DESCRIPTION_BACKEND_DEBUG_BACKEND_ID_1331=The backend ID of the backend
INFO_DESCRIPTION_BACKEND_DEBUG_BASE_DN_1332=The base DN within the backend
INFO_DESCRIPTION_BACKEND_DEBUG_INDEX_NAME_1333=The name of the index
INFO_DESCRIPTION_BACKEND_DEBUG_SKIP_DECODE_1334=Do not try to decode backend data to \
  their appropriate types
ERR_DBTEST_DECODE_FAIL_1335=An error occurred while decoding data: %s
INFO_DESCRIPTION_BACKEND_DEBUG_SUBCMD_LIST_INDEX_STATUS_1336=List the status of \
  indexes in an entry container. \
INFO_DESCRIPTION_BACKEND_DEBUG_SUBCMD_LIST_INDEX_STATUS_1336=Shows the status of \
  indexes for a backend base DN. \
  This subcommand can take a long time to complete, as it reads all indexes for all backends
INFO_DESCRIPTION_BACKEND_DEBUG_MAX_KEY_VALUE_1337=Only show records with keys that \
  should be ordered before the provided value using the comparator for the \
@@ -2566,24 +2565,25 @@
'%s' to avoid compatibility issues
ERR_UPGRADE_DSJAVAPROPERTIES_FAILED_1853=The dsjavaproperties tool failed to run. \
Please rerun dsjavaproperties manually
INFO_DESCRIPTION_BACKEND_TOOL_SUBCMD_LIST_ROOT_CONTAINERS_1854=List the root containers used by all backends
INFO_DESCRIPTION_BACKEND_TOOL_SUBCMD_LIST_STORAGE_TREES_1855=List indexes for a root container storage. \
INFO_DESCRIPTION_BACKEND_TOOL_SUBCMD_LIST_BACKENDS_1854=List the pluggable backends
INFO_DESCRIPTION_BACKEND_TOOL_SUBCMD_LIST_RAW_DBS_1855=List the low-level databases within a pluggable backend's \
  storage engine. This subcommand may take a long time to complete depending on the size of the backend
INFO_DESCRIPTION_BACKEND_TOOL_SUBCMD_LIST_INDEXES_1866=List the indexes associated with a pluggable backend. \
  This subcommand may take a long time to complete depending on the size of the backend
INFO_DESCRIPTION_BACKEND_TOOL_SUBCMD_DUMP_INDEX_1857=Dump records from an index, decoding keys and values. \
  Depending on index size, this subcommand can generate lots of output
INFO_DESCRIPTION_BACKEND_TOOL_SUBCMD_LIST_TREES_1866=List indexes for an entry container \
  This subcommand may take a long time to complete, as it reads all data for all indexes
INFO_DESCRIPTION_BACKEND_TOOL_SUBCMD_DUMP_TREE_1857=Dump records from an index decoding keys and values. \
  Depending on index size, this subcommand can generate lots of output
INFO_DESCRIPTION_BACKEND_TOOL_SUBCMD_DUMP_STORAGE_TREE_1858=Dump records in hexadecimal format from an index using \
  the storage engine. Depending on index size, this subcommand can generate lots of output
INFO_LABEL_BACKEND_TOOL_STORAGE_TREE_NAME_1861=Index Storage Name
ERR_BACKEND_TOOL_ERROR_READING_ENTRY_CONTAINERS_1863=An error occurred while gathering entry containers: %s
INFO_DESCRIPTION_BACKEND_TOOL_SUBCMD_DUMP_RAW_DB_1858=Dump the raw records in hexadecimal format for a low-level \
  database within the pluggable backend's storage engine. Depending on index size, this subcommand can generate lots \
  of output
INFO_LABEL_BACKEND_TOOL_RAW_DB_NAME_1861=Raw DB Name
ERR_BACKEND_TOOL_ERROR_LISTING_BASE_DNS_1863=An error occurred while listing the base DNs: %s
ERR_BACKEND_TOOL_ERROR_LISTING_TREES_1864=An error occurred while listing indexes: %s
ERR_BACKEND_TOOL_ERROR_INITIALIZING_BACKEND_1865=An unexpected error occurred \
  while attempting to initialize the backend %s: %s
  while attempting to initialize the backend '%s': %s
ERR_BACKEND_TOOL_ERROR_READING_TREE_1866=An unexpected error occurred \
  while attempting to read and/or decode records from an index: %s
INFO_LABEL_BACKEND_TOOL_INDEX_UNDEFINED_RECORD_COUNT_1867=Over Entry Limit
ERR_BACKEND_TOOL_NO_TREE_FOR_NAME_1868=No index exists with the requested name %s in entry container %s and backend %s
ERR_BACKEND_TOOL_NO_TREE_FOR_NAME_1868=No index exists with the requested name '%s' in base DN '%s' and backend '%s'
ERR_BACKEND_TOOL_ONLY_ONE_MIN_KEY_1869=Cannot specify a minimum key both as a string and as an hexadecimal string
ERR_BACKEND_TOOL_ONLY_ONE_MAX_KEY_1870=Cannot specify a maximum key both as a string and as an hexadecimal string
ERR_BACKEND_TOOL_PROCESSING_ARGUMENT_1871=An error occurred while processing arguments: %s
@@ -2607,8 +2607,9 @@
INFO_LABEL_BACKEND_TOOL_VALUE_FORMAT_1889=Value (len %d):
ERR_BACKEND_TOOL_DECODER_NOT_AVAILABLE_1890=Data decoder for printing is not available, should use hex dump
ERR_BACKEND_TOOL_NO_TREE_FOR_NAME_IN_STORAGE_1891=No storage index exists with the requested name %s in backend %s
INFO_LABEL_BACKEND_TOOL_BACKEND_TREE_NAME_1892=Index Backend Name
INFO_DESCRIPTION_BACKEND_TOOL_1893=This utility can be used to debug a backend
INFO_INDEX_NAME_PLACEHOLDER_1894={indexName}
INFO_DESCRIPTION_BACKEND_DEBUG_RAW_DB_NAME_1895=The raw database name
# Upgrade tasks
INFO_UPGRADE_TASK_6869_SUMMARY_10000=Fixing de-DE collation matching rule OID