ISSUE #2274: The 'metaformat' command does not delete 'idgen' znode

Descriptions of the changes in this PR:

### Motivation

After `metaformat`, ledgerId does not count from 0 becauseļ¼Œthe `metaformat` command does not delete `idgen` znode.

### Changes

In the `AbstractZkLedgerManagerFactory` avoid skipping the igen and idgen-long nodes

Master Issue: #2274

Reviewers: Enrico Olivelli <eolivelli@gmail.com>, Sijie Guo <None>

This closes #2315 from mino181295/leadger-metaformat, closes #2274
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/meta/AbstractZkLedgerManager.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/meta/AbstractZkLedgerManager.java
index fa64ada..808cf89 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/meta/AbstractZkLedgerManager.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/meta/AbstractZkLedgerManager.java
@@ -580,7 +580,11 @@
             || BookKeeperConstants.LAYOUT_ZNODE.equals(znode)
             || BookKeeperConstants.INSTANCEID.equals(znode)
             || BookKeeperConstants.UNDER_REPLICATION_NODE.equals(znode)
-            || LegacyHierarchicalLedgerManager.IDGEN_ZNODE.equals(znode)
+            || isLeadgerIdGeneratorZnode(znode);
+    }
+
+    public static boolean isLeadgerIdGeneratorZnode(String znode) {
+        return LegacyHierarchicalLedgerManager.IDGEN_ZNODE.equals(znode)
             || LongHierarchicalLedgerManager.IDGEN_ZNODE.equals(znode)
             || znode.startsWith(ZkLedgerIdGenerator.LEDGER_ID_GEN_PREFIX);
     }
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/meta/AbstractZkLedgerManagerFactory.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/meta/AbstractZkLedgerManagerFactory.java
index 72bc3e8..eef608d 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/meta/AbstractZkLedgerManagerFactory.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/meta/AbstractZkLedgerManagerFactory.java
@@ -17,6 +17,8 @@
  */
 package org.apache.bookkeeper.meta;
 
+import static org.apache.bookkeeper.meta.AbstractZkLedgerManager.isLeadgerIdGeneratorZnode;
+import static org.apache.bookkeeper.meta.AbstractZkLedgerManager.isSpecialZnode;
 import java.io.IOException;
 import java.net.URI;
 import java.util.List;
@@ -48,7 +50,10 @@
             String ledgersRootPath = ZKMetadataDriverBase.resolveZkLedgersRootPath(conf);
             List<String> children = zk.getChildren(ledgersRootPath, false);
             for (String child : children) {
-                if (!AbstractZkLedgerManager.isSpecialZnode(child) && ledgerManager.isLedgerParentNode(child)) {
+                boolean lParentNode = !isSpecialZnode(child) && ledgerManager.isLedgerParentNode(child);
+                boolean lIdGenerator = isLeadgerIdGeneratorZnode(child);
+
+                if (lParentNode || lIdGenerator) {
                     ZKUtil.deleteRecursive(zk, ledgersRootPath + "/" + child);
                 }
             }
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 0bbe0f1..daafc74 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
@@ -32,9 +32,11 @@
 import java.io.File;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Random;
+import java.util.Set;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutionException;
@@ -612,4 +614,40 @@
         assertTrue("expected areEntriesOfLedgerStoredInTheBookie to return true for bookie2",
                 BookKeeperAdmin.areEntriesOfLedgerStoredInTheBookie(ledgerId, bookie2, meta));
     }
+
+    @Test
+    public void testBookkeeperAdminFormatResetsLedgerIds() throws Exception {
+        ClientConfiguration conf = new ClientConfiguration();
+        conf.setMetadataServiceUri(zkUtil.getMetadataServiceUri());
+
+        /*
+         * in this testsuite there are going to be 2 (numOfBookies) ledgers
+         * written and when formatting the BookieAdmin i expect that the
+         * ledger ids restart from 0
+         */
+        int numOfLedgers = 2;
+        try (BookKeeper bkc = new BookKeeper(conf)) {
+            Set<Long> ledgerIds = new HashSet<>();
+            for (int n = 0; n < numOfLedgers; n++) {
+                try (LedgerHandle lh = bkc.createLedger(numOfBookies, numOfBookies, digestType, "L".getBytes())) {
+                    ledgerIds.add(lh.getId());
+                    lh.addEntry("000".getBytes());
+                }
+            }
+
+            try (BookKeeperAdmin bkAdmin = new BookKeeperAdmin(zkUtil.getZooKeeperConnectString())) {
+                bkAdmin.format(baseConf, false, true);
+            }
+
+            /**
+             * ledgers created after format produce the same ids
+             */
+            for (int n = 0; n < numOfLedgers; n++) {
+                try (LedgerHandle lh = bkc.createLedger(numOfBookies, numOfBookies, digestType, "L".getBytes())) {
+                    lh.addEntry("000".getBytes());
+                    assertTrue(ledgerIds.contains(lh.getId()));
+                }
+            }
+        }
+    }
 }