use of org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.LedgerMetadataListener in project bookkeeper by apache.
the class AbstractZkLedgerManagerTest method testLedgerMetadataListener.
@Test
public void testLedgerMetadataListener() throws Exception {
long ledgerId = System.currentTimeMillis();
String ledgerStr = String.valueOf(ledgerId);
LinkedBlockingQueue<LedgerMetadata> changes = new LinkedBlockingQueue<>();
LedgerMetadataListener listener = (ledgerId1, metadata) -> changes.add(metadata);
metadata.setVersion(new LongVersion(1234L));
Stat stat = mock(Stat.class);
when(stat.getVersion()).thenReturn(1234);
when(stat.getCtime()).thenReturn(metadata.getCtime());
mockZkGetData(ledgerStr, true, KeeperException.Code.OK.intValue(), metadata.serialize(), stat);
ledgerManager.registerLedgerMetadataListener(ledgerId, listener);
// the listener will be notified with first get
LedgerMetadata change1 = changes.take();
assertEquals(metadata, change1);
verify(mockZk, times(1)).getData(anyString(), any(Watcher.class), any(DataCallback.class), any());
// the watcher is registered for receiving watched event
assertTrue(watchers.containsKey(ledgerStr));
Set<Watcher> watcherSet1 = watchers.get(ledgerStr);
assertEquals(1, watcherSet1.size());
Watcher registeredWatcher1 = watcherSet1.stream().findFirst().get();
// mock get data to return an updated metadata
metadata.setVersion(new LongVersion(1235L));
when(stat.getVersion()).thenReturn(1235);
mockZkGetData(ledgerStr, true, KeeperException.Code.OK.intValue(), metadata.serialize(), stat);
// notify the watcher event
notifyWatchedEvent(EventType.NodeDataChanged, KeeperState.SyncConnected, ledgerStr);
// the listener should receive an updated metadata
LedgerMetadata change2 = changes.take();
assertEquals(metadata, change2);
verify(mockZk, times(2)).getData(anyString(), any(Watcher.class), any(DataCallback.class), any());
// after the listener receive an updated metadata, a new watcher should be registered
// for subsequent changes again.
assertTrue(watchers.containsKey(ledgerStr));
Set<Watcher> watcherSet2 = watchers.get(ledgerStr);
assertEquals(1, watcherSet2.size());
Watcher registeredWatcher2 = watcherSet2.stream().findFirst().get();
// zookeeper watchers are same, since there is only one giant watcher per ledger manager.
assertSame(registeredWatcher1, registeredWatcher2);
// verify scheduler
verify(scheduler, times(2)).submit(any(Runnable.class));
verify(scheduler, times(0)).schedule(any(Runnable.class), anyLong(), any(TimeUnit.class));
}
use of org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.LedgerMetadataListener in project bookkeeper by apache.
the class AbstractZkLedgerManagerTest method testUnregisterLedgerMetadataListener.
@Test
public void testUnregisterLedgerMetadataListener() throws Exception {
long ledgerId = System.currentTimeMillis();
String ledgerStr = String.valueOf(ledgerId);
LinkedBlockingQueue<LedgerMetadata> changes = new LinkedBlockingQueue<>();
LedgerMetadataListener listener = (ledgerId1, metadata) -> changes.add(metadata);
metadata.setVersion(new LongVersion(1234L));
Stat stat = mock(Stat.class);
when(stat.getVersion()).thenReturn(1234);
when(stat.getCtime()).thenReturn(metadata.getCtime());
mockZkGetData(ledgerStr, true, KeeperException.Code.OK.intValue(), metadata.serialize(), stat);
ledgerManager.registerLedgerMetadataListener(ledgerId, listener);
assertTrue(ledgerManager.listeners.containsKey(ledgerId));
// the listener will be notified with first get
LedgerMetadata change1 = changes.take();
assertEquals(metadata, change1);
verify(mockZk, times(1)).getData(anyString(), any(Watcher.class), any(DataCallback.class), any());
// the watcher is registered for receiving watched event
assertTrue(watchers.containsKey(ledgerStr));
Set<Watcher> watcherSet1 = watchers.get(ledgerStr);
assertEquals(1, watcherSet1.size());
Watcher registeredWatcher1 = watcherSet1.stream().findFirst().get();
// mock get data to return an updated metadata
metadata.setVersion(new LongVersion(1235L));
when(stat.getVersion()).thenReturn(1235);
mockZkGetData(ledgerStr, true, KeeperException.Code.OK.intValue(), metadata.serialize(), stat);
// unregister the listener
ledgerManager.unregisterLedgerMetadataListener(ledgerId, listener);
assertFalse(ledgerManager.listeners.containsKey(ledgerId));
// notify the watcher event
notifyWatchedEvent(EventType.NodeDataChanged, KeeperState.SyncConnected, ledgerStr);
// since listener is already unregistered so no more `getData` is issued.
assertNull(changes.poll());
verify(mockZk, times(1)).getData(anyString(), any(Watcher.class), any(DataCallback.class), any());
}
use of org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.LedgerMetadataListener in project bookkeeper by apache.
the class AbstractZkLedgerManagerTest method testLedgerMetadataListenerOnRetries.
@Test
public void testLedgerMetadataListenerOnRetries() throws Exception {
long ledgerId = System.currentTimeMillis();
String ledgerStr = String.valueOf(ledgerId);
LinkedBlockingQueue<LedgerMetadata> changes = new LinkedBlockingQueue<>();
LedgerMetadataListener listener = (ledgerId1, metadata) -> changes.add(metadata);
metadata.setVersion(new LongVersion(1234L));
Stat stat = mock(Stat.class);
when(stat.getVersion()).thenReturn(1234);
when(stat.getCtime()).thenReturn(metadata.getCtime());
// fail the first get, so the ledger manager will retry get data again.
mockZkGetData(ledgerStr, true, KeeperException.Code.SESSIONEXPIRED.intValue(), null, null);
ledgerManager.registerLedgerMetadataListener(ledgerId, listener);
assertTrue(ledgerManager.listeners.containsKey(ledgerId));
// the listener will not be notified with any updates
assertNull(changes.poll());
// an retry task is scheduled
verify(scheduler, times(1)).schedule(any(Runnable.class), anyLong(), any(TimeUnit.class));
// zookeeper is called once
verify(mockZk, times(1)).getData(anyString(), any(Watcher.class), any(DataCallback.class), any());
// watcher is not registered since getData call is failed
assertFalse(watchers.containsKey(ledgerStr));
// mock get data to return a valid response
mockZkGetData(ledgerStr, true, KeeperException.Code.OK.intValue(), metadata.serialize(), stat);
schedulerController.advance(Duration.ofMillis(ZK_CONNECT_BACKOFF_MS));
// the listener will be notified with first get
LedgerMetadata change = changes.take();
assertEquals(metadata, change);
verify(mockZk, times(2)).getData(anyString(), any(Watcher.class), any(DataCallback.class), any());
// watcher is registered after successfully `getData`
assertTrue(watchers.containsKey(ledgerStr));
}
use of org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.LedgerMetadataListener in project bookkeeper by apache.
the class TestWatchEnsembleChange method testWatchMetadataRemoval.
private void testWatchMetadataRemoval(LedgerManagerFactory factory) throws Exception {
@Cleanup final LedgerManager manager = factory.newLedgerManager();
@Cleanup LedgerIdGenerator idGenerator = factory.newLedgerIdGenerator();
final ByteBuffer bbLedgerId = ByteBuffer.allocate(8);
final CountDownLatch createLatch = new CountDownLatch(1);
final CountDownLatch removeLatch = new CountDownLatch(1);
idGenerator.generateLedgerId(new GenericCallback<Long>() {
@Override
public void operationComplete(int rc, final Long lid) {
manager.createLedgerMetadata(lid, new LedgerMetadata(4, 2, 2, digestType, "fpj was here".getBytes()), new BookkeeperInternalCallbacks.GenericCallback<Void>() {
@Override
public void operationComplete(int rc, Void result) {
bbLedgerId.putLong(lid);
bbLedgerId.flip();
createLatch.countDown();
}
});
}
});
assertTrue(createLatch.await(2000, TimeUnit.MILLISECONDS));
final long createdLid = bbLedgerId.getLong();
manager.registerLedgerMetadataListener(createdLid, new LedgerMetadataListener() {
@Override
public void onChanged(long ledgerId, LedgerMetadata metadata) {
assertEquals(ledgerId, createdLid);
assertEquals(metadata, null);
removeLatch.countDown();
}
});
manager.removeLedgerMetadata(createdLid, Version.ANY, new BookkeeperInternalCallbacks.GenericCallback<Void>() {
@Override
public void operationComplete(int rc, Void result) {
assertEquals(rc, BKException.Code.OK);
}
});
assertTrue(removeLatch.await(2000, TimeUnit.MILLISECONDS));
}
use of org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.LedgerMetadataListener in project bookkeeper by apache.
the class AbstractZkLedgerManager method process.
@Override
public void process(WatchedEvent event) {
LOG.debug("Received watched event {} from zookeeper based ledger manager.", event);
if (Event.EventType.None == event.getType()) {
if (Event.KeeperState.Expired == event.getState()) {
LOG.info("ZooKeeper client expired on ledger manager.");
Set<Long> keySet = new HashSet<Long>(listeners.keySet());
for (Long lid : keySet) {
scheduler.submit(new ReadLedgerMetadataTask(lid));
LOG.info("Re-read ledger metadata for {} after zookeeper session expired.", lid);
}
}
return;
}
String path = event.getPath();
if (null == path) {
return;
}
final long ledgerId;
try {
ledgerId = getLedgerId(event.getPath());
} catch (IOException ioe) {
LOG.info("Received invalid ledger path {} : ", event.getPath(), ioe);
return;
}
switch(event.getType()) {
case NodeDeleted:
Set<LedgerMetadataListener> listenerSet = listeners.get(ledgerId);
if (null != listenerSet) {
synchronized (listenerSet) {
if (LOG.isDebugEnabled()) {
LOG.debug("Removed ledger metadata listeners on ledger {} : {}", ledgerId, listenerSet);
}
for (LedgerMetadataListener l : listenerSet) {
l.onChanged(ledgerId, null);
}
listeners.remove(ledgerId, listenerSet);
}
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("No ledger metadata listeners to remove from ledger {} after it's deleted.", ledgerId);
}
}
break;
case NodeDataChanged:
new ReadLedgerMetadataTask(ledgerId).run();
break;
default:
if (LOG.isDebugEnabled()) {
LOG.debug("Received event {} on {}.", event.getType(), event.getPath());
}
break;
}
}
Aggregations