From 56ead8581a49db146704134595571d1a43a20ec8 Mon Sep 17 00:00:00 2001 From: vraulji567 Date: Wed, 3 Dec 2025 12:27:07 -0500 Subject: [PATCH 1/2] Update readledger command to read all the entries from a bookie when first and last entry ids are not provided --- .../tools/cli/commands/bookie/ReadLedgerCommand.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/ReadLedgerCommand.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/ReadLedgerCommand.java index 20b4232e314..0e034b08acd 100644 --- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/ReadLedgerCommand.java +++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/ReadLedgerCommand.java @@ -189,7 +189,13 @@ private boolean readledger(ServerConfiguration serverConf, ReadLedgerFlags flags executor, scheduler, NullStatsLogger.INSTANCE, bk.getBookieAddressResolver()); - LongStream.range(flags.firstEntryId, lastEntry).forEach(entryId -> { + // Determine the last ledger entry from ledger metadata if its is not provided + if (flags.lastEntryId == -1 && !flags.forceRecovery) { + LedgerHandle lh = bk.openLedgerNoRecovery(flags.ledgerId); + lastEntry = lh.getLastAddConfirmed(); + } + + LongStream.rangeClosed(flags.firstEntryId, lastEntry).forEach(entryId -> { CompletableFuture future = new CompletableFuture<>(); bookieClient.readEntry(bookie, flags.ledgerId, entryId, From c07bce018bef9f7d4f3b03769ce64263140ef29e Mon Sep 17 00:00:00 2001 From: vraulji567 Date: Wed, 24 Dec 2025 15:03:22 -0500 Subject: [PATCH 2/2] Fix Test in ReadLedgerCommandTest --- .../commands/bookie/ReadLedgerCommandTest.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tools/ledger/src/test/java/org/apache/bookkeeper/tools/cli/commands/bookie/ReadLedgerCommandTest.java b/tools/ledger/src/test/java/org/apache/bookkeeper/tools/cli/commands/bookie/ReadLedgerCommandTest.java index 3f80d31dba1..73adf204ace 100644 --- a/tools/ledger/src/test/java/org/apache/bookkeeper/tools/cli/commands/bookie/ReadLedgerCommandTest.java +++ b/tools/ledger/src/test/java/org/apache/bookkeeper/tools/cli/commands/bookie/ReadLedgerCommandTest.java @@ -22,6 +22,7 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -35,6 +36,7 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.function.Consumer; import lombok.SneakyThrows; +import org.apache.bookkeeper.client.BKException; import org.apache.bookkeeper.client.BookKeeperAdmin; import org.apache.bookkeeper.client.LedgerEntry; import org.apache.bookkeeper.client.LedgerHandle; @@ -42,6 +44,7 @@ import org.apache.bookkeeper.net.BookieId; import org.apache.bookkeeper.net.BookieSocketAddress; import org.apache.bookkeeper.proto.BookieClientImpl; +import org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.ReadEntryCallback; import org.apache.bookkeeper.tools.cli.helpers.BookieCommandTestBase; import org.junit.Assert; import org.junit.Test; @@ -89,6 +92,7 @@ public void accept(BookKeeperAdmin bookKeeperAdmin) { when(bookKeeperAdmin.getBookieAddressResolver()) .thenReturn(BookieSocketAddress.LEGACY_BOOKIEID_RESOLVER); when(bookKeeperAdmin.openLedger(anyLong())).thenReturn(ledgerHandle); + when(bookKeeperAdmin.openLedgerNoRecovery(anyLong())).thenReturn(ledgerHandle); when(bookKeeperAdmin.readEntries(anyLong(), anyLong(), anyLong())).thenReturn(entries); } }); @@ -110,7 +114,18 @@ public void accept(BookKeeperAdmin bookKeeperAdmin) { .newSingleThreadScheduledExecutor(any(DefaultThreadFactory.class))) .thenReturn(scheduledExecutorService); - mockConstruction(BookieClientImpl.class); + mockConstruction(BookieClientImpl.class, (mock, contest) -> { + doAnswer(invocation -> { + ReadEntryCallback callback = invocation.getArgument(3); + callback.readEntryComplete(BKException.Code.OK, + invocation.getArgument(1), // ledgerId + invocation.getArgument(2), // entryId + null, // buffer + invocation.getArgument(4)); // ctx + return null; + }).when(mock).readEntry(any(), anyLong(), anyLong(), any(), any(), anyInt()); + + }); }