You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bookkeeper.apache.org by ay...@apache.org on 2022/04/25 22:28:09 UTC

[bookkeeper] branch master updated: Fix read empty ledger exception using bookkeeper admin

This is an automated email from the ASF dual-hosted git repository.

ayegorov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/bookkeeper.git


The following commit(s) were added to refs/heads/master by this push:
     new 083e2e94d1 Fix read empty ledger exception using bookkeeper admin
083e2e94d1 is described below

commit 083e2e94d18edcd85a1d25deaf77ecad0e3de61d
Author: Hang Chen <ch...@apache.org>
AuthorDate: Tue Apr 26 06:28:04 2022 +0800

    Fix read empty ledger exception using bookkeeper admin
    
    ### Motivation
    Fix #3222
    
    The root cause is that BookKeeperAdmin use `asyncReadEntriesInternal` to read entries. However, the `asyncReadEntriesInternal` doesn't check the lastAddConfirm, which will lead to the exception list in issue 3222
    
    ### Changes
    
    Add lastAddConfirm check before call `asyncReadEntriesInternal`
    
    Reviewers: Yong Zhang <zh...@gmail.com>, Andrey Yegorov <None>
    
    This closes #3240 from hangc0276/chenhang/fix_BKBookieHandleNotAvailableException_for_empty_ledger
---
 .../org/apache/bookkeeper/client/BookKeeperAdmin.java   |  5 ++---
 .../apache/bookkeeper/client/BookKeeperAdminTest.java   | 17 +++++++++++++++++
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/BookKeeperAdmin.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/BookKeeperAdmin.java
index 1df80b1fd4..cb3057a503 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/BookKeeperAdmin.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/BookKeeperAdmin.java
@@ -432,12 +432,11 @@ public class BookKeeperAdmin implements AutoCloseable {
             if (currentEntry != null) {
                 return true;
             }
-            if (lastEntryId == -1 || nextEntryId <= lastEntryId) {
+            if ((lastEntryId == -1 || nextEntryId <= lastEntryId) && nextEntryId <= handle.getLastAddConfirmed()) {
                 try {
                     CompletableFuture<Enumeration<LedgerEntry>> result = new CompletableFuture<>();
-
                     handle.asyncReadEntriesInternal(nextEntryId, nextEntryId,
-                                                    new SyncReadCallback(result), null, false);
+                        new SyncReadCallback(result), null, false);
 
                     currentEntry = SyncCallbackUtils.waitForResult(result).nextElement();
 
diff --git a/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/BookKeeperAdminTest.java b/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/BookKeeperAdminTest.java
index 591761b114..4fdc05c1e2 100644
--- a/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/BookKeeperAdminTest.java
+++ b/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/BookKeeperAdminTest.java
@@ -490,6 +490,23 @@ public class BookKeeperAdminTest extends BookKeeperClusterTestCase {
         bkc.close();
     }
 
+    @Test
+    public void testGetEntriesFromEmptyLedger() throws Exception {
+        ClientConfiguration conf = new ClientConfiguration();
+        conf.setMetadataServiceUri(zkUtil.getMetadataServiceUri());
+        BookKeeper bkc = new BookKeeper(conf);
+        LedgerHandle lh = bkc.createLedger(numOfBookies, numOfBookies, digestType, "testPasswd".getBytes(UTF_8));
+        lh.close();
+        long ledgerId = lh.getId();
+
+        try (BookKeeperAdmin bkAdmin = new BookKeeperAdmin(zkUtil.getZooKeeperConnectString())) {
+            Iterator<LedgerEntry> iter = bkAdmin.readEntries(ledgerId, 0, 0).iterator();
+            assertFalse(iter.hasNext());
+        }
+
+        bkc.close();
+    }
+
     @Test
     public void testGetListOfEntriesOfLedgerWithJustOneBookieInWriteQuorum() throws Exception {
         ClientConfiguration conf = new ClientConfiguration();