From 429a25b92b7036e6387c58edc26099a7cb68978e Mon Sep 17 00:00:00 2001
From: Valery Kharseko <vharseko@3a-systems.ru>
Date: Thu, 01 Oct 2026 10:19:15 +0000
Subject: [PATCH] [#1134] Give a VLV row of backendstat show-index-status its Confidential cell, so that its record count lands under Record Count (#1139)
---
opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/PluggableBackendImplTestCase.java | 87 +++++++++++++++++++++
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/BackendStat.java | 104 ++++++++++++++-----------
2 files changed, 145 insertions(+), 46 deletions(-)
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/BackendStat.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/BackendStat.java
index 4ee981c..200c1b1 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/BackendStat.java
+++ b/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)
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/PluggableBackendImplTestCase.java b/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/PluggableBackendImplTestCase.java
index 475a64e..f902196 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/PluggableBackendImplTestCase.java
+++ b/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
{
--
Gitblit v1.10.0