package com.alipay.bluewhale.core.zk;
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.data.Stat;
import org.apache.zookeeper.server.NIOServerCnxnFactory;
import org.apache.zookeeper.server.ServerCnxnFactory;
import org.apache.zookeeper.server.ZooKeeperServer;
import backtype.storm.utils.Utils;
import com.alipay.bluewhale.core.utils.PathUtils;
import com.alipay.bluewhale.core.utils.StormUtils;
import com.netflix.curator.framework.CuratorFramework;
import com.netflix.curator.framework.api.CuratorEvent;
import com.netflix.curator.framework.api.CuratorEventType;
import com.netflix.curator.framework.api.CuratorListener;
import com.netflix.curator.framework.api.UnhandledErrorListener;
/**
* zk�����ļ�װ
*
* @author yannian
*
*/
public class Zookeeper {
private static Logger LOG = Logger.getLogger(Zookeeper.class);
public CuratorFramework mkClient(Map conf, List<String> servers,
Object port, String root) {
return mkClient(conf, servers, port, root, new DefaultWatcherCallBack());
}
/**
* ����ZK ע��WATCHED �¼� ע�������¼�
*
* @return
*/
public CuratorFramework mkClient(Map conf, List<String> servers,
Object port, String root, final WatcherCallBack watcher) {
CuratorFramework fk = Utils.newCurator(conf, servers, port, root);
fk.getCuratorListenable().addListener(new CuratorListener() {
@Override
public void eventReceived(CuratorFramework _fk, CuratorEvent e)
throws Exception {
if (e.getType().equals(CuratorEventType.WATCHED)) {
WatchedEvent event = e.getWatchedEvent();
watcher.execute(event.getState(), event.getType(),
event.getPath());
}
}
});
fk.getUnhandledErrorListenable().addListener(
new UnhandledErrorListener() {
@Override
public void unhandledError(String msg, Throwable error) {
String errmsg = "Unrecoverable Zookeeper error, halting process: "
+ msg;
LOG.error(errmsg, error);
StormUtils.halt_process(1,
"Unrecoverable Zookeeper error");
}
});
fk.start();
return fk;
}
public String createNode(CuratorFramework zk, String path, byte[] data,
org.apache.zookeeper.CreateMode mode) throws Exception {
String npath = PathUtils.normalize_path(path);
return zk.create().withMode(mode).withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE)
.forPath(npath, data);
}
public String createNode(CuratorFramework zk, String path, byte[] data)
throws Exception {
return createNode(zk, path, data,
org.apache.zookeeper.CreateMode.PERSISTENT);
}
public boolean existsNode(CuratorFramework zk, String path, boolean watch)
throws Exception {
Stat stat = null;
if (watch) {
stat = zk.checkExists().watched()
.forPath(PathUtils.normalize_path(path));
} else {
stat = zk.checkExists().forPath(PathUtils.normalize_path(path));
}
return stat != null;
}
public void deleteNode(CuratorFramework zk, String path) throws Exception {
zk.delete().forPath(PathUtils.normalize_path(path));
}
public void mkdirs(CuratorFramework zk, String path) throws Exception {
String npath = PathUtils.normalize_path(path);
// the node is "/"
if (npath.equals("/")) {
return;
}
// the node exist
if (existsNode(zk, npath, false)) {
return;
}
mkdirs(zk, PathUtils.parent_path(npath));
try {
createNode(zk, npath, StormUtils.barr((byte) 7),
org.apache.zookeeper.CreateMode.PERSISTENT);
} catch (KeeperException e) {
;// this can happen when multiple clients doing mkdir at same
// time
LOG.warn("zookeeper mkdirs for path" + path, e);
}
}
public byte[] getData(CuratorFramework zk, String path, boolean watch)
throws Exception {
String npath = PathUtils.normalize_path(path);
try {
if (existsNode(zk, npath, watch)) {
if (watch) {
return zk.getData().watched().forPath(npath);
} else {
return zk.getData().forPath(npath);
}
}
} catch (KeeperException e) {
LOG.error("zookeeper getdata for path" + path, e);
}
return null;
}
public List<String> getChildren(CuratorFramework zk, String path,
boolean watch) throws Exception {
String npath = PathUtils.normalize_path(path);
if (watch) {
return zk.getChildren().watched().forPath(npath);
} else {
return zk.getChildren().forPath(npath);
}
}
public Stat setData(CuratorFramework zk, String path, byte[] data)
throws Exception {
String npath = PathUtils.normalize_path(path);
return zk.setData().forPath(npath, data);
}
public boolean exists(CuratorFramework zk, String path, boolean watch)
throws Exception {
return existsNode(zk, path, watch);
}
public void deletereRcursive(CuratorFramework zk, String path)
throws Exception {
String npath = PathUtils.normalize_path(path);
if (existsNode(zk, npath, false)) {
List<String> childs = getChildren(zk, npath, false);
for (String child : childs) {
String childFullPath = PathUtils.full_path(npath, child);
deletereRcursive(zk, childFullPath);
}
deleteNode(zk, npath);
}
}
public ServerCnxnFactory mkInprocessZookeeper(String localdir, int port)
throws IOException, InterruptedException {
LOG.info("Starting inprocess zookeeper at port " + port + " and dir "
+ localdir);
File localfile = new File(localdir);
ZooKeeperServer zk = new ZooKeeperServer(localfile, localfile, 2000);
ServerCnxnFactory factory =NIOServerCnxnFactory.createFactory(
new InetSocketAddress(port),60);
factory.startup(zk);
return factory;
}
public void shutdownInprocessZookeeper(ServerCnxnFactory handle) {
handle.shutdown();
}
}