package org.zookeeper; import org.apache.zookeeper.AsyncCallback; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.data.Stat; import java.util.Arrays; /** * User: keyki */ public class DataMonitor implements Watcher, AsyncCallback.StatCallback { private ZooKeeper zooKeeper; private String zNode; private boolean dead; private DataMonitorListener listener; private byte prevData[]; public DataMonitor(ZooKeeper zooKeeper, String zNode, Executor executor) { this.zooKeeper = zooKeeper; this.zNode = zNode; this.listener = executor; zooKeeper.exists(zNode, true, this, null); } public boolean isDead() { return dead; } public interface DataMonitorListener { /** * The existence status of the node has changed. */ void exists(byte data[]); /** * The ZooKeeper session is no longer valid. * * @param rc the ZooKeeper reason code */ void closing(int rc); } public void process(WatchedEvent event) { String path = event.getPath(); if (event.getType() == Event.EventType.None) { // We are are being told that the state of the // connection has changed switch (event.getState()) { case SyncConnected: // In this particular example we don't need to do anything // here - watches are automatically re-registered with // server and any watches triggered while the client was // disconnected will be delivered (in order of course) break; case Expired: // It's all over dead = true; listener.closing(KeeperException.Code.SESSIONEXPIRED.intValue()); break; } } else { if (path != null && path.equals(zNode)) { zooKeeper.exists(zNode, true, this, null); } } } @Override public void processResult(int rc, String path, Object ctx, Stat stat) { boolean exists; switch (KeeperException.Code.get(rc)) { case OK: exists = true; break; case NONODE: exists = false; break; case SESSIONEXPIRED: case NOAUTH: dead = true; listener.closing(rc); return; default: // Retry errors zooKeeper.exists(zNode, true, this, null); return; } byte b[] = null; if (exists) { try { b = zooKeeper.getData(zNode, false, null); } catch (KeeperException e) { // We don't need to worry about recovering now. The watch // callbacks will kick off any exception handling e.printStackTrace(); } catch (InterruptedException e) { return; } } if ((b == null && b != prevData) || (b != null && !Arrays.equals(prevData, b))) { listener.exists(b); prevData = b; } } }