All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.foreveross.springboot.dubbo.autoconfigure.SystemPolicyCurator Maven / Gradle / Ivy
package com.foreveross.springboot.dubbo.autoconfigure;
import org.I0Itec.zkclient.IZkChildListener;
import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Id;
import org.apache.zookeeper.server.auth.DigestAuthenticationProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* author:wzq
* date:16-6-28
* project:ab-system
* description: 配置管理建设者
*/
@Component
@Profile("prod")
public class SystemPolicyCurator {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
// 需要从配置文件中读取 并做修改
// "104.236.154.96:2181,198.199.108.10:2181,159.203.221.126:2181";
@Value("${zookeeper.address}")
private String zkAddress = "localhost:2181";
@Value("${zookeeper.path:/system_policy}")
private String sysConfig;
@Value("${zookeeper.acl.admin}")
private String zkacl_admin; // 需要从配置文件中读取 并做修改
@Value("${zookeeper.acl.reader}")
private String zkacl_read; // 需要从配置文件中读取 并做修改
private String digest = "digest"; // 加密方式,不用修改
@Value("${app.name}")
private String type;
private boolean isSystem = "ab-system".equals(this.type); // is system
private String watchPath;
// 有2中路径 /{sysConfig} /{sysConfig}/{type},对应不同的权限控制
private List aclSysConfig;
private List aclType;
private static boolean enableAcl = true;
private ZkClient zkClient;
private List serviceTypes; // 存储types
private ConfigChangeListener listener;
public SystemPolicyCurator() {
if (isSystem) {
aclSysConfig = new ArrayList();
aclType = new ArrayList();
try {
// admin 有所有权限 read 有create权限
aclSysConfig.add(new ACL(ZooDefs.Perms.ALL, new Id(digest, DigestAuthenticationProvider.generateDigest(zkacl_admin))));
aclSysConfig.add(new ACL(ZooDefs.Perms.CREATE, new Id(digest, DigestAuthenticationProvider.generateDigest(zkacl_read))));
// admin 有所有权限 read 有read权限
aclType.add(new ACL(ZooDefs.Perms.ALL, new Id(digest, DigestAuthenticationProvider.generateDigest(zkacl_admin))));
aclType.add(new ACL(ZooDefs.Perms.READ, new Id(digest, DigestAuthenticationProvider.generateDigest(zkacl_read))));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
zkClient = new ZkClient(zkAddress);
if (enableAcl) zkClient.addAuthInfo(digest, zkacl_admin.getBytes());
start();
} else {
this.watchPath = sysConfig + "/" + type;
this.zkClient = new ZkClient(zkAddress);
// System.out.println("type=" + type);
// System.out.println("watchPath=" + this.watchPath);
// ZkClient zkClient = new ZkClient(zkAddress);
if (enableAcl) zkClient.addAuthInfo(digest, zkacl_read.getBytes()); // acl
// create config if need
if (!zkClient.exists(sysConfig)) {
zkClient.createPersistent(sysConfig);
}
if (!zkClient.exists(watchPath)) {
zkClient.createPersistent(watchPath);
}
// listen watchPath
zkClient.subscribeDataChanges(this.watchPath, new IZkDataListener() {
public void handleDataChange(String s, Object o) throws Exception {
System.out.println("handleDataChange, path=" + s + "Object=" + o.toString());
}
public void handleDataDeleted(String s) throws Exception {
System.out.println("handleDataDeleted");
System.out.println("path=" + s);
}
});
}
// testWrite(); // test
}
/**
* 外部实现, 比如mq-demo需要实现配置节点改变和删除的操作
*/
public interface ConfigChangeListener {
void onConfigChange(String newCfg); // 改变配置数据, e.g. mq-demo接收事件
void onConfigDelete(); // 删除配置节点, e.g. mq-demo接收事件, mq-demo恢复默认值
}
public void registerListener(ConfigChangeListener listener) {
this.listener = listener;
}
public void start() {
final SystemPolicyCurator self = this;
// create config if need
if (!zkClient.exists(sysConfig)) {
logger.debug("create " + sysConfig);
zkClient.createPersistent(sysConfig);
}
// {sysConfig}管理权限
if (enableAcl) zkClient.setAcl(sysConfig, aclSysConfig);
// 开始监听 sysConfig 节点
zkClient.subscribeDataChanges(sysConfig, new IZkDataListener() {
public void handleDataChange(String s, Object o) throws Exception {
logger.debug("subscribeDataChanges handleDataChange, path=" + s + "Object=" + o.toString());
if (self.listener != null) self.listener.onConfigChange((String) o);
}
public void handleDataDeleted(String s) throws Exception {
logger.debug("subscribeDataChanges handleDataDeleted");
logger.debug("path=" + s);
if (self.listener != null) self.listener.onConfigDelete();
}
});
// 开始监听 sysConfig 节点
// zkClient.subscribeStateChanges(new IZkStateListener() {
// public void handleStateChanged(Watcher.Event.KeeperState keeperState) throws Exception {
// logger.debug("subscribeStateChanges handleStateChanged");
// logger.debug("keeperState=" + keeperState);
// }
// public void handleNewSession() throws Exception {
// logger.debug("subscribeStateChanges handleStateChanged");
// }
// public void handleSessionEstablishmentError(Throwable throwable) throws Exception {
// logger.debug("subscribeStateChanges handleSessionEstablishmentError");
// }
// });
// 开始监听 sysConfig 节点
zkClient.subscribeChildChanges(sysConfig, new IZkChildListener() {
@Override
public void handleChildChange(String s, List list) throws Exception {
logger.debug("subscribeChildChanges handleChildChange" + "path=" + s + ",list=" + list.toString());
self.serviceTypes = list;
self.childAcl();
}
});
// 测试结果 @ 监听 /sysConfig
// 添加节点 /sysConfig/rabbit-mq --------------subscribeChildChanges 收到监听事件
// 删除 /sysConfig/rabbit-mq------------------subscribeChildChanges 收到监听事件
// 删除 /sysConfig----------------------------subscribeDataChanges 收到监听事件
initChildNodes();
}
private void initChildNodes() {
// get direct child
serviceTypes = zkClient.getChildren(sysConfig);
childAcl();
}
/**
* 获取 所有 types
*
* @return List String
*/
public List getServiceTypes() {
return Collections.unmodifiableList(serviceTypes);
}
/**
* 设在某个 type 的配置(结点的值)
*
* @param type service type
* @param cfg new config String
*/
public void setTypeCfg(String type, String cfg) {
String path = getTypePath(type);
if (!zkClient.exists(path)) {
zkClient.createPersistent(path, cfg);
} else {
zkClient.writeData(path, cfg);
}
}
/**
* 读取某个 type对应的配置(结点的值)
*
* @param type service type
* @return String new config String
*/
public String getTypeCfg(String type) {
String path = getTypePath(type);
if (!zkClient.exists(path)) {
return null;
}
return zkClient.readData(path);
}
private String getTypePath(String type) {
return sysConfig + "/" + type;
}
/**
* 对每个child 进行权限控制
* 规则: system 模块有admin权限
* 其他每个 type模块 对自己有 read权限
* TODO 应该只对 "变化" node 做权限修改,而非全部, 提高性能
*/
private void childAcl() {
if (!enableAcl) return;
for (int i = 0; i < serviceTypes.size(); i++) {
String type = serviceTypes.get(i);
String thePath = getTypePath(type);
zkClient.setAcl(thePath, aclType);
}
}
// // 测试 admin write
// private void testWrite() {
// while (true) {
// try {
// Thread.sleep(2000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// if (serviceTypes.size() > 0) {
// String aType = serviceTypes.get(0);
// String path = sysConfig + "/" + aType;
// String value = Math.random() + "";
// logger.debug("write " + path + ", value=" + value);
// zkClient.writeData(path, value);
// }
// }
// }
}