All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.dangdang.config.service.zookeeper.ZookeeperConfigGroup Maven / Gradle / Ivy

/**
 * Copyright 1999-2014 dangdang.com.
 * 

* Licensed 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 com.dangdang.config.service.zookeeper; import com.dangdang.config.service.ConfigGroup; import com.dangdang.config.service.GeneralConfigGroup; import com.dangdang.config.service.util.Tuple; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.framework.api.CuratorEvent; 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.utils.ZKPaths; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.annotation.PreDestroy; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.CountDownLatch; /** * 配置组节点 * * @author Yuxuan Wang */ public class ZookeeperConfigGroup extends GeneralConfigGroup { private static final long serialVersionUID = 1L; private ZookeeperConfigProfile configProfile; /** * 节点名字 */ private String node; private CuratorFramework client; private ConfigLocalCache configLocalCache; static final Logger LOGGER = LoggerFactory.getLogger(ZookeeperConfigGroup.class); public ZookeeperConfigGroup(ZookeeperConfigProfile configProfile, String node, boolean enumerable) { this(configProfile, node); super.enumerable = enumerable; } public ZookeeperConfigGroup(ZookeeperConfigProfile configProfile, String node) { this(null, configProfile, node); } public ZookeeperConfigGroup(ConfigGroup internalConfigGroup, ZookeeperConfigProfile configProfile, String node) { super(internalConfigGroup); this.configProfile = configProfile; this.node = node; if (configProfile.isOpenLocalCache()) { configLocalCache = new ConfigLocalCache(System.getProperty("user.home") + "/.config-toolkit", configProfile.getRootNode()); } initConfigs(); } /** * 初始化节点 */ private void initConfigs() { client = CuratorFrameworkFactory.newClient(configProfile.getConnectStr(), configProfile.getRetryPolicy()); client.start(); client.getCuratorListenable().addListener(new CuratorListener() { @Override public void eventReceived(CuratorFramework client, CuratorEvent event) throws Exception { LOGGER.info("Event: {}", event); final WatchedEvent watchedEvent = event.getWatchedEvent(); if (watchedEvent != null) { LOGGER.debug("Watched event: {}", watchedEvent); if (watchedEvent.getState() == Watcher.Event.KeeperState.SyncConnected) { switch (watchedEvent.getType()) { case NodeChildrenChanged: loadNode(); break; case NodeDataChanged: reloadKey(watchedEvent.getPath()); break; default: break; } } } } }); final CountDownLatch countDownLatch = new CountDownLatch(1); client.getConnectionStateListenable().addListener(new ConnectionStateListener() { @Override public void stateChanged(CuratorFramework client, ConnectionState newState) { LOGGER.info("Connection state change: {}", newState); if (newState == ConnectionState.CONNECTED) { LOGGER.debug("Loading properties for node: {}", node); loadNode(); countDownLatch.countDown(); } else if (newState == ConnectionState.RECONNECTED) { loadNode(); } } }); try { countDownLatch.await(); } catch (InterruptedException e) { LOGGER.error(e.getMessage(), e); throw new RuntimeException("Config Load error.", e); } // Update local cache if (configLocalCache != null) { configLocalCache.saveLocalCache(this, node); } } /** * 加载节点并监听节点变化 */ void loadNode() { final String nodePath = ZKPaths.makePath(configProfile.getVersionedRootNode(), node); final GetChildrenBuilder childrenBuilder = client.getChildren(); try { final List children = childrenBuilder.watched().forPath(nodePath); if (children != null) { final Map configs = new HashMap<>(); for (String child : children) { final Tuple keyValue = loadKey(ZKPaths.makePath(nodePath, child)); if (keyValue != null) { configs.put(keyValue.getFirst(), keyValue.getSecond()); } } cleanAndPutAll(configs); } } catch (Exception e) { throw new RuntimeException(e); } if (getConfigLocalCache() != null) { getConfigLocalCache().saveLocalCache(this, getNode()); } } void reloadKey(final String nodePath) { try { final Tuple keyValue = loadKey(nodePath); if (keyValue != null) { super.put(keyValue.getFirst(), keyValue.getSecond()); } } catch (Exception e) { throw new RuntimeException(e); } if (getConfigLocalCache() != null) { getConfigLocalCache().saveLocalCache(this, getNode()); } } private Tuple loadKey(final String nodePath) throws Exception { final String nodeName = ZKPaths.getNodeFromPath(nodePath); final Set keysSpecified = configProfile.getKeysSpecified(); switch (configProfile.getKeyLoadingMode()) { case INCLUDE: if (keysSpecified == null || !keysSpecified.contains(nodeName)) { return null; } break; case EXCLUDE: if (keysSpecified.contains(nodeName)) { return null; } break; case ALL: break; default: break; } final GetDataBuilder data = client.getData(); final String value = new String(data.watched().forPath(nodePath), "UTF-8"); return new Tuple<>(nodeName, value); } public String getNode() { return node; } public ConfigLocalCache getConfigLocalCache() { return configLocalCache; } /** * 导出属性列表 * * @return */ public Map exportProperties() { return new HashMap(this); } @PreDestroy @Override public void close() { if (client != null) { client.close(); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy