Closed
Description
BUG REPORT
Describe the bug
When I call batchReadEntries with an invalid startEntry, I get a java.util.NoSuchElementException. This happens with both WireProtocol V2 and V3.
To Reproduce
I wrote two simple tests based on the existing tests in BookKeeperTest.java
package org.apache.bookkeeper.client;
import org.apache.bookkeeper.conf.ClientConfiguration;
import org.apache.bookkeeper.test.BookKeeperClusterTestCase;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.Enumeration;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
public class LedgerHandleReadBatchEntriesTest extends BookKeeperClusterTestCase {
private static final Logger LOG = LoggerFactory.getLogger(LedgerHandleReadBatchEntriesTest.class);
public LedgerHandleReadBatchEntriesTest() {
super(5, 3, 30);
}
@Test
public void testBatchReadEntriesV2() {
ClientConfiguration conf = new ClientConfiguration().setUseV2WireProtocol(true);
conf.setBatchReadEnabled(true);
conf.setMetadataServiceUri(zkUtil.getMetadataServiceUri());
try (BookKeeper bkc = new BookKeeper(conf)) {
long ledgerId;
try (LedgerHandle lh = bkc.createLedger(3, 3, BookKeeper.DigestType.DUMMY, "password".getBytes())) {
ledgerId = lh.getId();
// Aggiungi 5 entry al ledger con ID da 0 a 4
for (int i = 0; i < 5; i++) {
lh.addEntry(("Entry " + i).getBytes(), 0, ("Entry " + i).getBytes().length);
}
} catch (BKException | InterruptedException e) {
fail("LedgerHandle inti failed: " + e.getMessage());
return;
}
try (LedgerHandle lh = bkc.openLedger(ledgerId, BookKeeper.DigestType.DUMMY, "password".getBytes())) {
Enumeration<LedgerEntry> entries = lh.batchReadEntries(-1, 5, 5 * 1024 * 1024);
int count = 0;
while (entries.hasMoreElements()) {
LedgerEntry entry = entries.nextElement();
assertArrayEquals(("Entry " + (count - 1)).getBytes(), entry.getEntry());
count++;
}
assertEquals(5, count);
} catch (BKException | InterruptedException e) {
LOG.info(e.getMessage(), e);
}
} catch (BKException | InterruptedException | IOException e) {
fail("BookKeeper client init failed: " + e.getMessage());
}
}
@Test
public void testBatchReadEntriesV3() {
ClientConfiguration conf = new ClientConfiguration();
conf.setBatchReadEnabled(false);
conf.setMetadataServiceUri(zkUtil.getMetadataServiceUri());
try (BookKeeper bkc = new BookKeeper(conf)) {
long ledgerId;
try (LedgerHandle lh = bkc.createLedger(3, 3, BookKeeper.DigestType.DUMMY, "password".getBytes())) {
ledgerId = lh.getId();
// Aggiungi 5 entry al ledger con ID da 0 a 4
for (int i = 0; i < 5; i++) {
lh.addEntry(("Entry " + i).getBytes(), 0, ("Entry " + i).getBytes().length);
}
} catch (BKException | InterruptedException e) {
fail("LedgerHandle inti failed: " + e.getMessage());
return;
}
try (LedgerHandle lh = bkc.openLedger(ledgerId, BookKeeper.DigestType.DUMMY, "password".getBytes())) {
Enumeration<LedgerEntry> entries = lh.batchReadEntries(-1, 5, 5 * 1024 * 1024);
int count = 0;
while (entries.hasMoreElements()) {
LedgerEntry entry = entries.nextElement();
assertArrayEquals(("Entry " + (count - 1)).getBytes(), entry.getEntry());
count++;
}
assertEquals(5, count);
} catch (BKException | InterruptedException e) {
LOG.info(e.getMessage(), e);
}
} catch (BKException | InterruptedException | IOException e) {
fail("BookKeeper client init failed: " + e.getMessage());
}
}
}
Expected behavior
It is not clear from the method description, but the other reader methods raise a BKException.BKIncorrectParameterException when provided with an invalid entry ID.