cn.hippo4j.config.springboot.starter.refresher.ZookeeperRefresherHandler Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.config.springboot.starter.refresher;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import cn.hippo4j.core.executor.manage.GlobalNotifyAlarmManage;
import cn.hippo4j.message.service.ThreadPoolNotifyAlarm;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.api.CuratorListener;
import org.apache.curator.framework.api.GetChildrenBuilder;
import org.apache.curator.framework.api.GetDataBuilder;
import org.apache.curator.framework.state.ConnectionState;
import org.apache.curator.framework.state.ConnectionStateListener;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.utils.ZKPaths;
import org.apache.zookeeper.WatchedEvent;
/**
* Zookeeper refresher handler.
*/
@Slf4j
public class ZookeeperRefresherHandler extends AbstractConfigThreadPoolDynamicRefresh {
static final String ZK_CONNECT_STR = "zk-connect-str";
static final String ROOT_NODE = "root-node";
static final String CONFIG_VERSION = "config-version";
static final String NODE = "node";
private CuratorFramework curatorFramework;
@Override
public String getProperties() {
Map zkConfigs = bootstrapConfigProperties.getZookeeper();
String nodePath = ZKPaths.makePath(ZKPaths.makePath(zkConfigs.get(ROOT_NODE),
zkConfigs.get(CONFIG_VERSION)), zkConfigs.get(NODE));
return nodePathResolver(nodePath);
}
@Override
public void afterPropertiesSet() {
Map zkConfigs = bootstrapConfigProperties.getZookeeper();
curatorFramework = CuratorFrameworkFactory.newClient(zkConfigs.get(ZK_CONNECT_STR),
new ExponentialBackoffRetry(1000, 3));
String nodePath = ZKPaths.makePath(ZKPaths.makePath(zkConfigs.get(ROOT_NODE),
zkConfigs.get(CONFIG_VERSION)), zkConfigs.get(NODE));
final ConnectionStateListener connectionStateListener = (client, newState) -> {
if (newState == ConnectionState.CONNECTED) {
loadNode(nodePath);
} else if (newState == ConnectionState.RECONNECTED) {
loadNode(nodePath);
}
};
final CuratorListener curatorListener = (client, curatorEvent) -> {
final WatchedEvent watchedEvent = curatorEvent.getWatchedEvent();
if (null != watchedEvent) {
switch (watchedEvent.getType()) {
case NodeChildrenChanged:
case NodeDataChanged:
loadNode(nodePath);
break;
default:
break;
}
}
};
curatorFramework.getConnectionStateListenable().addListener(connectionStateListener);
curatorFramework.getCuratorListenable().addListener(curatorListener);
curatorFramework.start();
}
/**
* Load config info and refresh.
*
* @param nodePath zk config node path.
*/
public void loadNode(String nodePath) {
String content = nodePathResolver(nodePath);
if (content != null) {
dynamicRefresh(content);
registerNotifyAlarmManage();
}
}
/**
* resolver for zk config
*
* @param nodePath zk config node path
* @return resolver result
*/
private String nodePathResolver(String nodePath) {
try {
final GetChildrenBuilder childrenBuilder = curatorFramework.getChildren();
final List children = childrenBuilder.watched().forPath(nodePath);
StringBuilder content = new StringBuilder();
children.forEach(c -> {
String n = ZKPaths.makePath(nodePath, c);
final String nodeName = ZKPaths.getNodeFromPath(n);
final GetDataBuilder data = curatorFramework.getData();
String value = "";
try {
value = new String(data.watched().forPath(n), StandardCharsets.UTF_8);
} catch (Exception ex) {
log.error("Load zookeeper node error", ex);
}
content.append(nodeName).append("=").append(value).append("\n");
});
return content.toString();
} catch (Exception ex) {
log.error("Load zookeeper node error, nodePath is: {}", nodePath, ex);
return null;
}
}
/**
* Register notify alarm manage.
*/
public void registerNotifyAlarmManage() {
bootstrapConfigProperties.getExecutors().forEach(executorProperties -> {
ThreadPoolNotifyAlarm threadPoolNotifyAlarm = new ThreadPoolNotifyAlarm(
executorProperties.getAlarm(),
executorProperties.getCapacityAlarm(),
executorProperties.getActiveAlarm());
threadPoolNotifyAlarm.setInterval(executorProperties.getNotify().getInterval());
threadPoolNotifyAlarm.setReceives(executorProperties.getNotify().getReceives());
GlobalNotifyAlarmManage.put(executorProperties.getThreadPoolId(), threadPoolNotifyAlarm);
});
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy