/**
*
*/
package com.taobao.top.analysis.util;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.data.Stat;
/**
* zookeeper的一个工具类,当前的目录结构:
*
* beatles-
* groupId-
* master-
* runtime-
* epoch-
* jobName-
* taskId-
* slave-
* config-
*
*
* @author fangweng
* email: fangweng@taobao.com
* 下午1:22:11
*
*/
public class ZKUtil {
/**
* 创建某一个Group的配直节点
* @param zk
* @param groupId
* @throws KeeperException
* @throws InterruptedException
*/
public static void createGroupNodesIfNotExist(ZooKeeper zk,String groupId) throws KeeperException, InterruptedException
{
if (zk.exists(getGroupZKPath(groupId), false) == null)
{
createNodeIfNotExist(zk,AnalysisConstants.ZK_ROOT,new byte[0]);
createNodeIfNotExist(zk,getGroupZKPath(groupId), new byte[0]);
createNodeIfNotExist(zk,getGroupMasterZKPath(groupId), new byte[0]);
createNodeIfNotExist(zk,getGroupSlaveZKPath(groupId), new byte[0]);
createNodeIfNotExist(zk,getGroupConfigZKPath(groupId), new byte[0]);
}
}
/**
* 获得某一个group的zk节点
* @param groupId
* @return
*/
public static String getGroupZKPath(String groupId)
{
return new StringBuilder().append(AnalysisConstants.ZK_ROOT).append("/")
.append(groupId).toString();
}
/**
* 获得某一个group的master节点
* @param groupId
* @return
*/
public static String getGroupMasterZKPath(String groupId)
{
return new StringBuilder().append(getGroupZKPath(groupId)).append(AnalysisConstants.ZK_MASTER).toString();
}
/**
* 获得某一个group的slave节点
* @param groupId
* @return
*/
public static String getGroupSlaveZKPath(String groupId)
{
return new StringBuilder().append(getGroupZKPath(groupId)).append(AnalysisConstants.ZK_SLAVE).toString();
}
/**
* 获得某一个group的config节点
* @param groupId
* @return
*/
public static String getGroupConfigZKPath(String groupId)
{
return new StringBuilder().append(getGroupZKPath(groupId)).append(AnalysisConstants.ZK_CONFIG).toString();
}
/**
* 节点基础操作,根据路径判断是否存在该节点,不存在就创建,存在则不处理
* @param zk
* @param path
* @param data
* @throws KeeperException
* @throws InterruptedException
*/
public static void createNodeIfNotExist(ZooKeeper zk,String path,byte[] data) throws KeeperException, InterruptedException
{
Stat node = zk.exists(path, false);
if (node == null)
{
zk.create(path,data, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
}
/**
* 节点基础操作,根据路径判断节点是否存在,如果存在则更新数据,如果不存在则创建节点
* @param zk
* @param path
* @param data
* @throws KeeperException
* @throws InterruptedException
*/
public static void updateOrCreateNode(ZooKeeper zk,String path,byte[] data) throws KeeperException, InterruptedException
{
Stat node = zk.exists(path, false);
if (node == null)
{
createPath(zk,path);
zk.create(path,data,Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
else
{
//不管什么情况都覆盖已有的数据
zk.setData(path, data, -1);
}
//增加对于节点数据修改的监控
zk.getData(path, true, null);
}
/**
* 循环创建路径中不存在的节点
* @param zk
* @param path
* @throws InterruptedException
* @throws KeeperException
*/
public static void createPath(ZooKeeper zk,String path) throws KeeperException, InterruptedException
{
String[] paths = StringUtils.split(path, '/');
StringBuilder sp = new StringBuilder();
for(int i = 0 ; i < paths.length - 1; i++)
{
sp.append("/").append(paths[i]);
Stat node = zk.exists(sp.toString(), false);
if (node == null)
{
zk.create(sp.toString(),null,Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
}
}
/**
* 删除zk节点
* @param zk
* @param path
* @throws KeeperException
* @throws InterruptedException
*/
public static void deleteNode(ZooKeeper zk,String path)throws KeeperException, InterruptedException
{
Stat node = zk.exists(path, false);
if (node != null)
{
List<String> subPaths = null;
try
{
subPaths = zk.getChildren(path, false);
}
catch(Exception ex)
{
ex.printStackTrace();
}
if (subPaths == null || subPaths.size() == 0)
zk.delete(path, -1);
else
{
for(String s : subPaths)
{
deleteNode(zk,new StringBuilder().append(path).append("/").append(s).toString());
}
zk.delete(path, -1);
}
}
}
}