This is an automated email from the ASF dual-hosted git repository.
ddanielr pushed a commit to branch 2.1
in repository https://gitbox.apache.org/repos/asf/accumulo.git
The following commit(s) were added to refs/heads/2.1 by this push:
new 65acb18db2 Correctly render null bytes in ListCompactions (#5955)
65acb18db2 is described below
commit 65acb18db20fdd94afdbd8a1cc189d1aa2932968
Author: Dom G. <[email protected]>
AuthorDate: Mon Nov 10 12:06:57 2025 -0500
Correctly render null bytes in ListCompactions (#5955)
---
.../shell/commands/ActiveCompactionHelper.java | 55 +++++++++++++++++++++-
.../apache/accumulo/test/shell/ShellServerIT.java | 8 +++-
2 files changed, 60 insertions(+), 3 deletions(-)
diff --git
a/shell/src/main/java/org/apache/accumulo/shell/commands/ActiveCompactionHelper.java
b/shell/src/main/java/org/apache/accumulo/shell/commands/ActiveCompactionHelper.java
index 62dd93f269..fa93483d24 100644
---
a/shell/src/main/java/org/apache/accumulo/shell/commands/ActiveCompactionHelper.java
+++
b/shell/src/main/java/org/apache/accumulo/shell/commands/ActiveCompactionHelper.java
@@ -31,8 +31,11 @@ import org.apache.accumulo.core.client.IteratorSetting;
import org.apache.accumulo.core.client.TableNotFoundException;
import org.apache.accumulo.core.client.admin.ActiveCompaction;
import org.apache.accumulo.core.client.admin.InstanceOperations;
+import org.apache.accumulo.core.data.TabletId;
import org.apache.accumulo.core.util.DurationFormat;
+import org.apache.accumulo.core.util.TextUtil;
import org.apache.accumulo.shell.Shell;
+import org.apache.hadoop.io.Text;
class ActiveCompactionHelper {
@@ -96,13 +99,63 @@ class ActiveCompactionHelper {
return String.format(
"%21s | %9s | %5s | %6s | %5s | %5s | %15s | %-40s | %5s | %35s |
%9s | %s", host, dur,
ac.getType(), ac.getReason(), shortenCount(ac.getEntriesRead()),
- shortenCount(ac.getEntriesWritten()), ac.getTable(), ac.getTablet(),
+ shortenCount(ac.getEntriesWritten()), ac.getTable(),
formatTablet(ac.getTablet()),
ac.getInputFiles().size(), output, iterList, iterOpts);
} catch (TableNotFoundException e) {
return "ERROR " + e.getMessage();
}
}
+ private static String formatTablet(TabletId tabletId) {
+ if (tabletId == null) {
+ return "";
+ }
+ StringBuilder sb = new StringBuilder();
+ appendEscapedTableId(sb, tabletId.getTable().canonical());
+ appendTabletRow(sb, tabletId.getEndRow());
+ appendTabletRow(sb, tabletId.getPrevEndRow());
+ return sb.toString();
+ }
+
+ private static void appendEscapedTableId(StringBuilder sb, String tableId) {
+ for (int i = 0; i < tableId.length(); i++) {
+ char c = tableId.charAt(i);
+ if (c == '\\') {
+ sb.append("\\\\");
+ } else if (c == ';') {
+ sb.append("\\;");
+ } else {
+ sb.append(c);
+ }
+ }
+ }
+
+ private static void appendTabletRow(StringBuilder sb, Text row) {
+ if (row == null) {
+ sb.append("<");
+ return;
+ }
+ sb.append(';');
+ Text truncated = TextUtil.truncate(row);
+ byte[] bytes = TextUtil.getBytes(truncated);
+ appendEscapedBytes(sb, bytes);
+ }
+
+ private static void appendEscapedBytes(StringBuilder sb, byte[] bytes) {
+ for (byte b : bytes) {
+ int c = b & 0xFF;
+ if (c == '\\') {
+ sb.append("\\\\");
+ } else if (c == ';') {
+ sb.append("\\;");
+ } else if (c >= 32 && c <= 126) {
+ sb.append((char) c);
+ } else {
+ sb.append("\\x").append(String.format("%02X", c));
+ }
+ }
+ }
+
public static Stream<String> appendHeader(Stream<String> stream) {
Stream<String> header = Stream.of(String.format(
" %-21s| %-9s | %-5s | %-6s | %-5s | %-5s | %-15s | %-40s | %-5s |
%-35s | %-9s | %s",
diff --git
a/test/src/main/java/org/apache/accumulo/test/shell/ShellServerIT.java
b/test/src/main/java/org/apache/accumulo/test/shell/ShellServerIT.java
index c275558186..00e7cfdc03 100644
--- a/test/src/main/java/org/apache/accumulo/test/shell/ShellServerIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/shell/ShellServerIT.java
@@ -1447,6 +1447,7 @@ public class ShellServerIT extends SharedMiniClusterBase {
final String table = getUniqueNames(1)[0];
ts.exec("createtable " + table, true);
+ ts.exec("addsplits -t " + table + " a\0test", true);
ts.exec(
"config -t " + table
+ " -s
table.iterator.minc.slow=30,org.apache.accumulo.test.functional.SlowIterator",
@@ -1460,8 +1461,11 @@ public class ShellServerIT extends SharedMiniClusterBase
{
ts.exec("sleep 0.2", true);
ts.exec("listcompactions", true, "default_tablet");
String[] lines = ts.output.get().split("\n");
- String last = lines[lines.length - 1];
- String[] parts = last.split("\\|");
+ String compaction = Arrays.stream(lines).filter(line ->
line.contains("default_tablet"))
+ .findFirst().orElseThrow();
+ assertTrue(compaction.contains("\\x00"),
+ "Expected tablet to display \\x00 for null byte: " + compaction);
+ String[] parts = compaction.split("\\|");
assertEquals(12, parts.length);
ts.exec("deletetable -f " + table, true);
}