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

Valery Kharseko
11 hours ago 429a25b92b7036e6387c58edc26099a7cb68978e
[#1134] Give a VLV row of backendstat show-index-status its Confidential cell, so that its record count lands under Record Count (#1139)
2 files modified
191 ■■■■■ changed files
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/BackendStat.java 104 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/PluggableBackendImplTestCase.java 87 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/BackendStat.java
@@ -314,6 +314,7 @@
   */
  public static int main(String[] args, OutputStream outStream, OutputStream errStream)
  {
    JDKLogging.disableLogging();
    BackendStat app = new BackendStat(outStream, errStream);
    return app.run(args);
  }
@@ -328,7 +329,6 @@
  {
    this.out = NullOutputStream.wrapOrNullStream(out);
    this.err = NullOutputStream.wrapOrNullStream(err);
    JDKLogging.disableLogging();
    LocalizableMessage toolDescription = INFO_DESCRIPTION_BACKEND_TOOL.get();
    this.parser = new SubCommandArgumentParser(getClass().getName(), toolDescription, false);
@@ -1022,58 +1022,16 @@
    try
    {
      // Create a table of their properties.
      TableBuilder builder = new TableBuilder();
      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_STATUS.get());
      builder.appendHeading(INFO_LABEL_BACKEND_DEBUG_INDEX_CONFIDENTIAL.get());
      builder.appendHeading(INFO_LABEL_BACKEND_DEBUG_RECORD_COUNT.get());
      builder.appendHeading(INFO_LABEL_BACKEND_TOOL_INDEX_UNDEFINED_RECORD_COUNT.get());
      builder.appendHeading(LocalizableMessage.raw("95%"));
      builder.appendHeading(LocalizableMessage.raw("90%"));
      builder.appendHeading(LocalizableMessage.raw("85%"));
      EntryContainer ec = rc.getEntryContainer(base);
      if (ec == null)
      {
        return printEntryContainerError(backend, base);
      }
      // Create a table of their properties.
      TableBuilder builder = new TableBuilder();
      Map<Index, StringBuilder> undefinedKeys = new HashMap<>();
      for (AttributeIndex attrIndex : ec.getAttributeIndexes())
      {
        for (AttributeIndex.MatchingRuleIndex index : attrIndex.getNameToIndexes().values())
        {
          builder.startRow();
          builder.appendCell(index.getName().getIndexId());
          builder.appendCell(index.getName());
          builder.appendCell(index.isTrusted());
          builder.appendCell(index.isEncrypted());
          if (index.isTrusted())
          {
            appendIndexStats(builder, ec, index, undefinedKeys);
          }
          else
          {
            appendStatsNoData(builder, 5);
          }
          count++;
        }
      }
      for (VLVIndex vlvIndex : ec.getVLVIndexes())
      {
        builder.startRow();
        builder.appendCell(vlvIndex.getName().getIndexId());
        builder.appendCell(vlvIndex.getName());
        builder.appendCell(vlvIndex.isTrusted());
        builder.appendCell(getTreeRecordCount(ec, vlvIndex));
        appendStatsNoData(builder, 4);
        count++;
      }
      int count = appendIndexStatusTable(builder, ec, undefinedKeys);
      builder.print(new TextTablePrinter(out));
      out.print(INFO_LABEL_BACKEND_TOOL_TOTAL.get(count).toString());
@@ -1091,6 +1049,60 @@
    }
  }
  /**
   * Fills the table {@code show-index-status} prints for the indexes of an entry container, a row
   * per index, and returns the number of its rows. The keys of an index that are over its entry
   * limit are collected into {@code undefinedKeys}.
   */
  int appendIndexStatusTable(TableBuilder builder, EntryContainer ec, Map<Index, StringBuilder> undefinedKeys)
  {
    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_STATUS.get());
    builder.appendHeading(INFO_LABEL_BACKEND_DEBUG_INDEX_CONFIDENTIAL.get());
    builder.appendHeading(INFO_LABEL_BACKEND_DEBUG_RECORD_COUNT.get());
    builder.appendHeading(INFO_LABEL_BACKEND_TOOL_INDEX_UNDEFINED_RECORD_COUNT.get());
    builder.appendHeading(LocalizableMessage.raw("95%"));
    builder.appendHeading(LocalizableMessage.raw("90%"));
    builder.appendHeading(LocalizableMessage.raw("85%"));
    int count = 0;
    for (AttributeIndex attrIndex : ec.getAttributeIndexes())
    {
      for (AttributeIndex.MatchingRuleIndex index : attrIndex.getNameToIndexes().values())
      {
        builder.startRow();
        builder.appendCell(index.getName().getIndexId());
        builder.appendCell(index.getName());
        builder.appendCell(index.isTrusted());
        builder.appendCell(index.isEncrypted());
        if (index.isTrusted())
        {
          appendIndexStats(builder, ec, index, undefinedKeys);
        }
        else
        {
          appendStatsNoData(builder, 5);
        }
        count++;
      }
    }
    for (VLVIndex vlvIndex : ec.getVLVIndexes())
    {
      builder.startRow();
      builder.appendCell(vlvIndex.getName().getIndexId());
      builder.appendCell(vlvIndex.getName());
      builder.appendCell(vlvIndex.isTrusted());
      // A VLV index has no confidentiality setting, but its row still needs the cell of that column
      appendStatsNoData(builder, 1);
      builder.appendCell(getTreeRecordCount(ec, vlvIndex));
      appendStatsNoData(builder, 4);
      count++;
    }
    return count;
  }
  private void appendStatsNoData(TableBuilder builder, int columns)
  {
    while (columns > 0)
opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/PluggableBackendImplTestCase.java
@@ -18,6 +18,8 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.forgerock.opendj.ldap.ModificationType.*;
import static org.opends.messages.ToolMessages.INFO_LABEL_BACKEND_DEBUG_INDEX_CONFIDENTIAL;
import static org.opends.messages.ToolMessages.INFO_LABEL_BACKEND_DEBUG_RECORD_COUNT;
import static org.mockito.Mockito.*;
import static org.opends.server.protocols.internal.InternalClientConnection.getRootConnection;
import static org.opends.server.protocols.internal.Requests.newSearchRequest;
@@ -39,6 +41,9 @@
import java.util.concurrent.atomic.AtomicBoolean;
import com.google.common.io.Resources;
import com.forgerock.opendj.cli.TableBuilder;
import com.forgerock.opendj.cli.TablePrinter;
import com.forgerock.opendj.cli.TableSerializer;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.schema.AttributeType;
import org.forgerock.opendj.ldap.schema.CoreSchema;
@@ -1178,6 +1183,88 @@
    assertThat(backend.verifyBackend(config)).isEqualTo(0);
  }
  /**
   * Every row {@code backendstat show-index-status} prints has a cell under each of its headings.
   * A VLV index, which has no confidentiality, shows {@code -} under Confidential, so that its
   * record count lands under Record Count; the key counts that follow are {@code -} as well.
   */
  @Test
  public void testShowIndexStatusPutsEachCellOfAVlvRowUnderItsHeading() throws Exception
  {
    final EntryContainer ec = backend.getRootContainer().getEntryContainer(testBaseDN);
    final VLVIndex vlvIndex = ec.getVLVIndexes().iterator().next();
    final long recordCount = backend.getRootContainer().getStorage().read(new ReadOperation<Long>()
    {
      @Override
      public Long run(ReadableTransaction txn) throws Exception
      {
        return vlvIndex.getRecordCount(txn);
      }
    });
    final ByteArrayOutputStream err = new ByteArrayOutputStream();
    final TableBuilder builder = new TableBuilder();
    final int count =
        new BackendStat(null, err).appendIndexStatusTable(builder, ec, new HashMap<Index, StringBuilder>());
    final CapturedTable table = new CapturedTable();
    builder.print(table);
    assertThat(err.toString()).as("errors").isEmpty();
    assertThat(table.rows).hasSize(count);
    for (List<String> row : table.rows)
    {
      assertThat(row).as("the cells of " + row.get(0) + " under " + table.headings).doesNotContain("");
    }
    List<String> vlvRow = null;
    for (List<String> row : table.rows)
    {
      if (row.get(0).equals(vlvIndex.getName().getIndexId()))
      {
        vlvRow = row;
      }
    }
    assertThat(vlvRow).as("the row of " + vlvIndex.getName()).isNotNull();
    final int confidential = table.headings.indexOf(INFO_LABEL_BACKEND_DEBUG_INDEX_CONFIDENTIAL.get().toString());
    final int recordCountColumn = table.headings.indexOf(INFO_LABEL_BACKEND_DEBUG_RECORD_COUNT.get().toString());
    assertThat(vlvRow.get(confidential)).as(table.headings.get(confidential)).isEqualTo("-");
    assertThat(vlvRow.get(recordCountColumn)).as(table.headings.get(recordCountColumn))
        .isEqualTo(String.valueOf(recordCount));
    assertThat(vlvRow.subList(recordCountColumn + 1, vlvRow.size())).containsExactly("-", "-", "-", "-");
  }
  /** The headings and the cells of a table, as a table printer is handed them. */
  private static final class CapturedTable extends TablePrinter
  {
    private final List<String> headings = new ArrayList<>();
    private final List<List<String>> rows = new ArrayList<>();
    @Override
    protected TableSerializer getSerializer()
    {
      return new TableSerializer()
      {
        @Override
        public void addHeading(String s)
        {
          headings.add(s);
        }
        @Override
        public void startRow()
        {
          rows.add(new ArrayList<String>());
        }
        @Override
        public void addCell(String s)
        {
          rows.get(rows.size() - 1).add(s);
        }
      };
    }
  }
  @Test
  public void testRebuildDegradedIndex() throws Exception
  {