use of org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.WriteCallback in project bookkeeper by apache.
the class LedgerCloseTest method startUnauthorizedBookie.
private void startUnauthorizedBookie(ServerConfiguration conf, final CountDownLatch latch) throws Exception {
Bookie sBookie = new Bookie(conf) {
@Override
public void addEntry(ByteBuf entry, boolean ackBeforeSync, WriteCallback cb, Object ctx, byte[] masterKey) throws IOException, BookieException {
try {
latch.await();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
throw BookieException.create(BookieException.Code.UnauthorizedAccessException);
}
@Override
public void recoveryAddEntry(ByteBuf entry, WriteCallback cb, Object ctx, byte[] masterKey) throws IOException, BookieException {
throw new IOException("Dead bookie for recovery adds.");
}
};
bsConfs.add(conf);
bs.add(startBookie(conf, sBookie));
}
use of org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.WriteCallback in project bookkeeper by apache.
the class LedgerRecoveryTest method testBookieFailureDuringRecovery.
/**
* {@link https://issues.apache.org/jira/browse/BOOKKEEPER-355}
* Verify that if a recovery happens with 1 replica missing, and it's replaced
* with a faulty bookie, it doesn't break future recovery from happening.
* 1. Ledger is created with quorum size as 2, and entries are written
* 2. Now first bookie is in the ensemble is brought down.
* 3. Another client fence and trying to recover the same ledger
* 4. During this time ensemble change will happen
* and new bookie will be added. But this bookie is not able to write.
* 5. This recovery will fail.
* 7. A new non-faulty bookie comes up
* 8. Another client trying to recover the same ledger.
*/
@Test
public void testBookieFailureDuringRecovery() throws Exception {
LedgerHandle lhbefore = bkc.createLedger(numBookies, 2, digestType, "".getBytes());
for (int i = 0; i < (numBookies * 3) + 1; i++) {
lhbefore.addEntry("data".getBytes());
}
// Add a dead bookie to the cluster
ServerConfiguration conf = newServerConfiguration();
Bookie deadBookie1 = new Bookie(conf) {
@Override
public void recoveryAddEntry(ByteBuf entry, WriteCallback cb, Object ctx, byte[] masterKey) throws IOException, BookieException {
// drop request to simulate a slow and failed bookie
throw new IOException("Couldn't write for some reason");
}
};
bsConfs.add(conf);
bs.add(startBookie(conf, deadBookie1));
// kill first bookie server
BookieSocketAddress bookie1 = lhbefore.getLedgerMetadata().currentEnsemble.get(0);
killBookie(bookie1);
// ensemble in the ensemble, and another bookie is available in zk but not writtable
try {
bkc.openLedger(lhbefore.getId(), digestType, "".getBytes());
fail("Shouldn't be able to open ledger, there should be entries missing");
} catch (BKException.BKLedgerRecoveryException e) {
// expected
}
// start a new good server
startNewBookie();
LedgerHandle lhafter = bkc.openLedger(lhbefore.getId(), digestType, "".getBytes());
assertEquals("Fenced ledger should have correct lastAddConfirmed", lhbefore.getLastAddConfirmed(), lhafter.getLastAddConfirmed());
}
use of org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.WriteCallback in project bookkeeper by apache.
the class LedgerRecoveryTest method startDeadBookie.
private void startDeadBookie(ServerConfiguration conf) throws Exception {
Bookie rBookie = new Bookie(conf) {
@Override
public void recoveryAddEntry(ByteBuf entry, WriteCallback cb, Object ctx, byte[] masterKey) throws IOException, BookieException {
// drop request to simulate a dead bookie
throw new IOException("Couldn't write entries for some reason");
}
};
bsConfs.add(conf);
bs.add(startBookie(conf, rBookie));
}
use of org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.WriteCallback in project bookkeeper by apache.
the class BookieJournalForceTest method testAckBeforeSyncWithJournalBufferedEntriesThreshold.
@Test
public void testAckBeforeSyncWithJournalBufferedEntriesThreshold() throws Exception {
File journalDir = tempDir.newFolder();
Bookie.checkDirectoryStructure(Bookie.getCurrentDirectory(journalDir));
final int journalBufferedEntriesThreshold = 10;
// sending a burst of entries, more than journalBufferedEntriesThreshold
final int numEntries = journalBufferedEntriesThreshold + 50;
ServerConfiguration conf = TestBKConfiguration.newServerConfiguration();
conf.setJournalDirName(journalDir.getPath()).setJournalBufferedEntriesThreshold(journalBufferedEntriesThreshold).setZkServers(null);
JournalChannel jc = spy(new JournalChannel(journalDir, 1));
whenNew(JournalChannel.class).withAnyArguments().thenReturn(jc);
LedgerDirsManager ledgerDirsManager = mock(LedgerDirsManager.class);
Journal journal = new Journal(0, journalDir, conf, ledgerDirsManager);
// machinery to suspend ForceWriteThread
CountDownLatch forceWriteThreadSuspendedLatch = new CountDownLatch(1);
enableForceWriteThreadSuspension(forceWriteThreadSuspendedLatch, journal);
TestStatsProvider testStatsProvider = new TestStatsProvider();
Counter flushMaxOutstandingBytesCounter = testStatsProvider.getStatsLogger("test").getCounter("flushMaxOutstandingBytesCounter");
Whitebox.setInternalState(journal, "flushMaxOutstandingBytesCounter", flushMaxOutstandingBytesCounter);
journal.start();
LogMark lastLogMarkBeforeWrite = journal.getLastLogMark().markLog().getCurMark();
CountDownLatch latch = new CountDownLatch(numEntries);
long ledgerId = 1;
for (long entryId = 0; entryId < numEntries; entryId++) {
journal.logAddEntry(ledgerId, entryId, DATA, true, /* ackBeforeSync */
new WriteCallback() {
@Override
public void writeComplete(int rc, long ledgerId, long entryId, BookieSocketAddress addr, Object ctx) {
latch.countDown();
}
}, null);
}
// logAddEntry should complete even if ForceWriteThread is suspended
latch.await(20, TimeUnit.SECONDS);
// in constructor of JournalChannel we are calling forceWrite(true) but it is not tracked by PowerMock
// because the 'spy' is applied only on return from the constructor
verify(jc, times(0)).forceWrite(true);
// anyway we are never calling forceWrite
verify(jc, times(0)).forceWrite(false);
// verify that log marker did not advance
LastLogMark lastLogMarkAfterForceWrite = journal.getLastLogMark();
assertEquals(0, lastLogMarkAfterForceWrite.getCurMark().compare(lastLogMarkBeforeWrite));
// let the forceWriteThread exit
forceWriteThreadSuspendedLatch.countDown();
assertTrue(flushMaxOutstandingBytesCounter.get() > 1);
journal.shutdown();
}
use of org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.WriteCallback in project bookkeeper by apache.
the class BookieJournalForceTest method testInterleavedRequests.
@Test
public void testInterleavedRequests() throws Exception {
File journalDir = tempDir.newFolder();
Bookie.checkDirectoryStructure(Bookie.getCurrentDirectory(journalDir));
ServerConfiguration conf = TestBKConfiguration.newServerConfiguration();
conf.setJournalDirName(journalDir.getPath()).setZkServers(null);
JournalChannel jc = spy(new JournalChannel(journalDir, 1));
whenNew(JournalChannel.class).withAnyArguments().thenReturn(jc);
LedgerDirsManager ledgerDirsManager = mock(LedgerDirsManager.class);
Journal journal = new Journal(0, journalDir, conf, ledgerDirsManager);
journal.start();
final int numEntries = 100;
CountDownLatch latchAckBeforeSynch = new CountDownLatch(numEntries);
CountDownLatch latchAckAfterSynch = new CountDownLatch(numEntries);
long ledgerIdAckBeforeSync = 1;
long ledgerIdAckAfterSync = 2;
for (long entryId = 0; entryId < numEntries; entryId++) {
journal.logAddEntry(ledgerIdAckBeforeSync, entryId, DATA, true, new WriteCallback() {
@Override
public void writeComplete(int rc, long ledgerId, long entryId, BookieSocketAddress addr, Object ctx) {
latchAckBeforeSynch.countDown();
}
}, null);
journal.logAddEntry(ledgerIdAckAfterSync, entryId, DATA, false, new WriteCallback() {
@Override
public void writeComplete(int rc, long ledgerId, long entryId, BookieSocketAddress addr, Object ctx) {
latchAckAfterSynch.countDown();
}
}, null);
}
assertTrue(latchAckBeforeSynch.await(20, TimeUnit.SECONDS));
assertTrue(latchAckAfterSynch.await(20, TimeUnit.SECONDS));
// in constructor of JournalChannel we are calling forceWrite(true) but it is not tracked by PowerMock
// because the 'spy' is applied only on return from the constructor
verify(jc, times(0)).forceWrite(true);
verify(jc, atLeast(1)).forceWrite(false);
journal.shutdown();
}
Aggregations