Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ public static void main(String[] args)
*/
public static int main(String[] args, OutputStream outStream, OutputStream errStream)
{
JDKLogging.disableLogging();
BackendStat app = new BackendStat(outStream, errStream);
return app.run(args);
}
Expand All @@ -328,7 +329,6 @@ public BackendStat(OutputStream out, OutputStream err)
{
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);
Expand Down Expand Up @@ -1022,58 +1022,16 @@ private int showIndexStatus(RootContainer rc, BackendImpl<?> backend, Argument b

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());
Expand All @@ -1091,6 +1049,60 @@ private int showIndexStatus(RootContainer rc, BackendImpl<?> backend, Argument b
}
}

/**
* 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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -1178,6 +1183,88 @@ public void run(WriteableTransaction txn) throws Exception
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
{
Expand Down
Loading