/**
* 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 org.apache.zookeeper.inspector.manager;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.KeeperException.NoNodeException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooDefs.Perms;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.ZooKeeper.States;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Stat;
import org.apache.zookeeper.inspector.encryption.BasicDataEncryptionManager;
import org.apache.zookeeper.inspector.encryption.DataEncryptionManager;
import org.apache.zookeeper.inspector.logger.LoggerFactory;
import org.apache.zookeeper.inspector.manager.ZooInspectorManagerCache.Item;
import org.apache.zookeeper.retry.ZooKeeperRetry;
/**
* A default implementation of {@link ZooInspectorManager} for connecting to zookeeper
* instances
*/
public class ZooInspectorManagerImpl implements ZooInspectorManager
{
private static final String A_VERSION = "ACL Version";
private static final String C_TIME = "Creation Time";
private static final String C_VERSION = "Children Version";
private static final String CZXID = "Creation ID";
private static final String DATA_LENGTH = "Data Length";
private static final String EPHEMERAL_OWNER = "Ephemeral Owner";
private static final String M_TIME = "Last Modified Time";
private static final String MZXID = "Modified ID";
private static final String NUM_CHILDREN = "Number of Children";
private static final String PZXID = "Node ID";
private static final String VERSION = "Data Version";
private static final String ACL_PERMS = "Permissions";
private static final String ACL_SCHEME = "Scheme";
private static final String ACL_ID = "Id";
private static final String SESSION_STATE = "Session State";
private static final String SESSION_ID = "Session ID";
/**
* The key used for the connect string in the connection properties file
*/
public static final String CONNECT_STRING = "hosts";
/**
* The key used for the session timeout in the connection properties file
*/
public static final String SESSION_TIMEOUT = "timeout";
/**
* The key used for the data encryption manager in the connection properties file
*/
public static final String DATA_ENCRYPTION_MANAGER = "encryptionManager";
private static final String homeDir = System.getProperty("user.home");
private static final File defaultNodeViewersFile =
new File(homeDir + "/.zooinspector/defaultNodeVeiwers.cfg");
private static final File defaultConnectionFile =
new File(homeDir + "/.zooinspector/defaultConnectionSettings.cfg");
// private static final File defaultNodeViewersFile =
// new File("./config/defaultNodeVeiwers.cfg");
// private static final File defaultConnectionFile =
// new File("./config/defaultConnectionSettings.cfg");
private DataEncryptionManager encryptionManager;
private String connectString;
private int sessionTimeout;
private ZooKeeper zooKeeper;
// private
final Map<String, NodeWatcher> watchers = new HashMap<String, NodeWatcher>();
protected boolean connected = true;
private Properties lastConnectionProps;
private String defaultEncryptionManager;
private String defaultTimeout;
private String defaultHosts;
private List<String> defaultHostsList;
private final int defaultHostsListSize = 10;
// zk cache that updates when:
// - refresh button is clicked
// - treeExpansion event fired
// - selectPth event fired
ZooInspectorManagerCache cache;
/**
* @throws IOException
* - thrown if the default connection settings cannot be loaded
*
*/
public ZooInspectorManagerImpl() throws IOException
{
loadDefaultConnectionFile();
}
/*
* (non-Javadoc)
*
* @see org.apache.zookeeper.inspector.manager.ZooInspectorManager#connect(java
* .util.Properties)
*/
@Override
public boolean connect(Properties connectionProps)
{
connected = false;
try
{
if (this.zooKeeper == null)
{
String connectString = connectionProps.getProperty(CONNECT_STRING);
String sessionTimeout = connectionProps.getProperty(SESSION_TIMEOUT);
String encryptionManager = connectionProps.getProperty(DATA_ENCRYPTION_MANAGER);
if (connectString == null || sessionTimeout == null)
{
throw new IllegalArgumentException("Both connect string and session timeout are required.");
}
if (encryptionManager == null)
{
this.encryptionManager = new BasicDataEncryptionManager();
}
else
{
Class<?> clazz = Class.forName(encryptionManager);
if (Arrays.asList(clazz.getInterfaces()).contains(DataEncryptionManager.class))
{
this.encryptionManager =
(DataEncryptionManager) Class.forName(encryptionManager).newInstance();
}
else
{
throw new IllegalArgumentException("Data encryption manager must implement DataEncryptionManager interface");
}
}
this.connectString = connectString;
this.sessionTimeout = Integer.valueOf(sessionTimeout);
// long start = System.currentTimeMillis();
// System.out.println("[START] connecting...");
this.zooKeeper =
new ZooKeeperRetry(connectString,
Integer.valueOf(sessionTimeout),
new Watcher()
{
@Override
public void process(WatchedEvent event)
{
if (event.getState() == KeeperState.Expired)
{
connected = false;
}
}
});
((ZooKeeperRetry) this.zooKeeper).setRetryLimit(10);
// System.out.println("[START] connected took: " + (System.currentTimeMillis() - start));
connected = ((ZooKeeperRetry) this.zooKeeper).testConnection();
}
}
catch (Exception e)
{
e.printStackTrace();
}
// connected = false;
// do initial cache refresh on all childs of "/"
if (connected == true)
{
cache = new ZooInspectorManagerCache(this);
try
{
cache.refresh(Arrays.asList("/"), 1);
}
catch (KeeperException e)
{
// TODO Auto-generated catch block
disconnect();
e.printStackTrace();
}
}
else
{
disconnect();
}
return connected;
}
/*
* (non-Javadoc)
*
* @see org.apache.zookeeper.inspector.manager.ZooInspectorManager#disconnect()
*/
@Override
public boolean disconnect()
{
try
{
if (this.zooKeeper != null)
{
this.zooKeeper.close();
this.zooKeeper = null;
connected = false;
removeWatchers(this.watchers.keySet());
return true;
}
}
catch (Exception e)
{
LoggerFactory.getLogger()
.error("Error occurred while disconnecting from ZooKeeper server", e);
}
return false;
}
/*
* (non-Javadoc)
*
* @seeorg.apache.zookeeper.inspector.manager.ZooInspectorReadOnlyManager#
* getChildren(java.lang.String)
*/
@Override
public List<String> getChildren(String nodePath)
{
// System.out.println("ZooInspectorManagerImpl.getChildren(), nodePath: " + nodePath);
if (connected)
{
// try {
//
// return zooKeeper.getChildren(nodePath, false);
// } catch (Exception e) {
// LoggerFactory.getLogger().error(
// "Error occurred retrieving children of node: "
// + nodePath, e);
// }
return cache.getChildren(nodePath);
}
return null;
}
Item getChildrenAndStat(String nodePath) throws KeeperException
{
// System.out.println("getChildrenAndStat(), path: " + nodePath);
if (zooKeeper.getState() != States.CONNECTED)
{
throw KeeperException.create(KeeperException.Code.CONNECTIONLOSS, nodePath);
}
try
{
Stat stat = new Stat();
List<String> childs = zooKeeper.getChildren(nodePath, false, stat);
return new Item(childs, stat);
}
catch (NoNodeException e)
{
// OK to return null
}
catch (KeeperException e)
{
throw e;
}
catch (Exception e)
{
LoggerFactory.getLogger().error("Error occurred retrieving children of node: "
+ nodePath,
e);
}
return null;
}
// experiments show that multi-thread sync-read is faster than single-thread async-read
// let's try it
ExecutorService service = Executors.newFixedThreadPool(40);
Map<String, Item> getChildren(List<String> paths)
{
int n = paths.size();
if (n > 0)
{
// final List<Item> ret = new ArrayList<Item>();
final Map<String, Item> ret = new ConcurrentHashMap<String, ZooInspectorManagerCache.Item>();
final CountDownLatch cntDown = new CountDownLatch(n);
for (final String path : paths)
{
service.submit(new Callable<String>()
{
@Override
public String call() throws Exception
{
Stat stat = null;
List<String> childs = null;
try
{
stat = new Stat();
childs = zooKeeper.getChildren(path, false, stat);
} catch (Exception e) {
// System.out.println("exception: " + e);
}
finally
{
// ret.add(new Item(childs, stat));
ret.put(path, new Item(childs, stat));
cntDown.countDown();
}
return null;
}
});
}
try
{
cntDown.await();
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return ret;
}
return Collections.emptyMap();
}
/*
* (non-Javadoc)
*
* @see org.apache.zookeeper.inspector.manager.ZooInspectorReadOnlyManager#getData
* (java.lang.String)
*/
@Override
public String getData(String nodePath)
{
if (connected)
{
try
{
if (nodePath.length() == 0)
{
nodePath = "/";
}
Stat s = zooKeeper.exists(nodePath, false);
if (s != null)
{
return this.encryptionManager.decryptData(zooKeeper.getData(nodePath, false, s));
}
}
catch (Exception e)
{
LoggerFactory.getLogger().error("Error occurred getting data for node: "
+ nodePath,
e);
}
}
return null;
}
/*
* (non-Javadoc)
*
* @seeorg.apache.zookeeper.inspector.manager.ZooInspectorReadOnlyManager#
* getNodeChild(java.lang.String, int)
*/
@Override
public String getNodeChild(String nodePath, int childIndex)
{
long start = System.currentTimeMillis();
if (connected)
{
// try {
// Stat s = zooKeeper.exists(nodePath, false);
// if (s != null) {
//
// String string = this.zooKeeper.getChildren(nodePath, false).get(
// childIndex);
// long end = System.currentTimeMillis();
// System.out.println("getNodeChild(), path: " + nodePath + ", childIndex: " +
// childIndex + ", " + (end - start));
// return string;
// }
// } catch (Exception e) {
// LoggerFactory.getLogger().error(
// "Error occurred retrieving child " + childIndex
// + " of node: " + nodePath, e);
// }
String child = cache.getNodeChild(nodePath, childIndex);
long end = System.currentTimeMillis();
// System.out.println("getNodeChild(), path: " + nodePath + ", childIndex: " +
// childIndex + ", " + (end - start));
return child;
}
return null;
}
/*
* (non-Javadoc)
*
* @seeorg.apache.zookeeper.inspector.manager.ZooInspectorReadOnlyManager#
* getNodeIndex(java.lang.String)
*/
@Override
public int getNodeIndex(String nodePath)
{
if (connected)
{
int index = nodePath.lastIndexOf("/");
if (index == -1
|| (!nodePath.equals("/") && nodePath.charAt(nodePath.length() - 1) == '/'))
{
throw new IllegalArgumentException("Invalid node path: " + nodePath);
}
String parentPath = nodePath.substring(0, index);
String child = nodePath.substring(index + 1);
if (parentPath != null && parentPath.length() > 0)
{
List<String> children = this.getChildren(parentPath);
if (children != null)
{
return children.indexOf(child);
}
}
}
return -1;
}
/*
* (non-Javadoc)
*
* @see org.apache.zookeeper.inspector.manager.ZooInspectorReadOnlyManager#getACLs
* (java.lang.String)
*/
@Override
public List<Map<String, String>> getACLs(String nodePath)
{
List<Map<String, String>> returnACLs = new ArrayList<Map<String, String>>();
if (connected)
{
try
{
if (nodePath.length() == 0)
{
nodePath = "/";
}
Stat s = zooKeeper.exists(nodePath, false);
if (s != null)
{
List<ACL> acls = zooKeeper.getACL(nodePath, s);
for (ACL acl : acls)
{
Map<String, String> aclMap = new LinkedHashMap<String, String>();
aclMap.put(ACL_SCHEME, acl.getId().getScheme());
aclMap.put(ACL_ID, acl.getId().getId());
StringBuilder sb = new StringBuilder();
int perms = acl.getPerms();
boolean addedPerm = false;
if ((perms & Perms.READ) == Perms.READ)
{
sb.append("Read");
addedPerm = true;
}
if (addedPerm)
{
sb.append(", ");
}
if ((perms & Perms.WRITE) == Perms.WRITE)
{
sb.append("Write");
addedPerm = true;
}
if (addedPerm)
{
sb.append(", ");
}
if ((perms & Perms.CREATE) == Perms.CREATE)
{
sb.append("Create");
addedPerm = true;
}
if (addedPerm)
{
sb.append(", ");
}
if ((perms & Perms.DELETE) == Perms.DELETE)
{
sb.append("Delete");
addedPerm = true;
}
if (addedPerm)
{
sb.append(", ");
}
if ((perms & Perms.ADMIN) == Perms.ADMIN)
{
sb.append("Admin");
addedPerm = true;
}
aclMap.put(ACL_PERMS, sb.toString());
returnACLs.add(aclMap);
}
}
}
catch (InterruptedException e)
{
LoggerFactory.getLogger().error("Error occurred retrieving ACLs of node: "
+ nodePath,
e);
}
catch (KeeperException e)
{
LoggerFactory.getLogger().error("Error occurred retrieving ACLs of node: "
+ nodePath,
e);
}
}
return returnACLs;
}
/*
* (non-Javadoc)
*
* @seeorg.apache.zookeeper.inspector.manager.ZooInspectorReadOnlyManager#
* getNodeMeta(java.lang.String)
*/
@Override
public Map<String, String> getNodeMeta(String nodePath)
{
Map<String, String> nodeMeta = new LinkedHashMap<String, String>();
if (connected)
{
try
{
if (nodePath.length() == 0)
{
nodePath = "/";
}
Stat s = zooKeeper.exists(nodePath, false);
if (s != null)
{
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS z");
nodeMeta.put(A_VERSION, String.valueOf(s.getAversion()));
// nodeMeta.put(C_TIME, String.valueOf(s.getCtime()));
nodeMeta.put(C_TIME, format.format(new Date(s.getCtime())));
nodeMeta.put(C_VERSION, String.valueOf(s.getCversion()));
nodeMeta.put(CZXID, "0x" + Long.toHexString(s.getCzxid()));
nodeMeta.put(DATA_LENGTH, String.valueOf(s.getDataLength()));
nodeMeta.put(EPHEMERAL_OWNER, "0x" + Long.toHexString(s.getEphemeralOwner()));
// nodeMeta.put(M_TIME, String.valueOf(s.getMtime()));
nodeMeta.put(M_TIME, format.format(new Date(s.getMtime())));
nodeMeta.put(MZXID, "0x" + Long.toHexString(s.getMzxid()));
nodeMeta.put(NUM_CHILDREN, String.valueOf(s.getNumChildren()));
nodeMeta.put(PZXID, "0x" + Long.toHexString(s.getPzxid()));
nodeMeta.put(VERSION, String.valueOf(s.getVersion()));
}
}
catch (Exception e)
{
LoggerFactory.getLogger().error("Error occurred retrieving meta data for node: "
+ nodePath,
e);
}
}
return nodeMeta;
}
/*
* (non-Javadoc)
*
* @seeorg.apache.zookeeper.inspector.manager.ZooInspectorReadOnlyManager#
* getNumChildren(java.lang.String)
*/
@Override
public int getNumChildren(String nodePath)
{
long start = System.currentTimeMillis();
if (connected)
{
// try {
// Stat s = zooKeeper.exists(nodePath, false);
// if (s != null) {
// int numChildren = s.getNumChildren();
// long end = System.currentTimeMillis();
// System.out.println("getNumbChilds(), nodePath: " + nodePath + ", " +
// (end-start));
// return numChildren;
// }
// } catch (Exception e) {
// LoggerFactory.getLogger().error(
// "Error occurred getting the number of children of node: "
// + nodePath, e);
// }
int numChildren = cache.getNumChildren(nodePath);
long end = System.currentTimeMillis();
// System.out.println("getNumbChilds(), nodePath: " + nodePath + ", " +
// (end-start));
return numChildren;
}
return -1;
}
/*
* (non-Javadoc)
*
* @seeorg.apache.zookeeper.inspector.manager.ZooInspectorReadOnlyManager#
* hasChildren(java.lang.String)
*/
@Override
public boolean hasChildren(String nodePath)
{
return getNumChildren(nodePath) > 0;
}
/*
* (non-Javadoc)
*
* @seeorg.apache.zookeeper.inspector.manager.ZooInspectorReadOnlyManager#
* isAllowsChildren(java.lang.String)
*/
@Override
public boolean isAllowsChildren(String nodePath)
{
if (connected)
{
try
{
Stat s = zooKeeper.exists(nodePath, false);
if (s != null)
{
return s.getEphemeralOwner() == 0;
}
}
catch (Exception e)
{
LoggerFactory.getLogger()
.error("Error occurred determining whether node is allowed children: "
+ nodePath,
e);
}
}
return false;
}
/*
* (non-Javadoc)
*
* @seeorg.apache.zookeeper.inspector.manager.ZooInspectorReadOnlyManager#
* getSessionMeta()
*/
@Override
public Map<String, String> getSessionMeta()
{
Map<String, String> sessionMeta = new LinkedHashMap<String, String>();
try
{
if (zooKeeper != null)
{
sessionMeta.put(SESSION_ID, String.valueOf(zooKeeper.getSessionId()));
sessionMeta.put(SESSION_STATE, String.valueOf(zooKeeper.getState().toString()));
sessionMeta.put(CONNECT_STRING, this.connectString);
sessionMeta.put(SESSION_TIMEOUT, String.valueOf(this.sessionTimeout));
}
}
catch (Exception e)
{
LoggerFactory.getLogger().error("Error occurred retrieving session meta data.", e);
}
return sessionMeta;
}
/*
* (non-Javadoc)
*
* @see org.apache.zookeeper.inspector.manager.ZooInspectorNodeTreeManager#createNode
* (java.lang.String, java.lang.String)
*/
@Override
public boolean createNode(String parent, String nodeName)
{
if (zooKeeper.getState() == States.CONNECTED)
{
try
{
String[] nodeElements = nodeName.split("/");
for (String nodeElement : nodeElements)
{
String node = parent + "/" + nodeElement;
Stat s = zooKeeper.exists(node, false);
if (s == null)
{
zooKeeper.create(node,
this.encryptionManager.encryptData(null),
Ids.OPEN_ACL_UNSAFE,
CreateMode.PERSISTENT);
parent = node;
}
}
return true;
}
catch (Exception e)
{
LoggerFactory.getLogger().error("Error occurred creating node: " + parent + "/"
+ nodeName,
e);
}
}
return false;
}
/*
* (non-Javadoc)
*
* @see org.apache.zookeeper.inspector.manager.ZooInspectorNodeTreeManager#deleteNode
* (java.lang.String)
*/
@Override
public boolean deleteNode(String nodePath)
{
if (zooKeeper.getState() == States.CONNECTED)
{
try
{
// Stat s = zooKeeper.exists(nodePath, false);
// if (s != null) {
List<String> children = zooKeeper.getChildren(nodePath, false);
if (children != null)
{
for (String child : children)
{
String node = nodePath + "/" + child;
deleteNode(node);
}
}
zooKeeper.delete(nodePath, -1);
// }
return true;
}
catch (Exception e)
{
LoggerFactory.getLogger().error("Error occurred deleting node: " + nodePath, e);
}
}
return false;
}
/*
* (non-Javadoc)
*
* @see org.apache.zookeeper.inspector.manager.ZooInspectorNodeManager#setData
* (java.lang.String, java.lang.String)
*/
@Override
public boolean setData(String nodePath, String data)
{
if (connected)
{
try
{
zooKeeper.setData(nodePath, this.encryptionManager.encryptData(data), -1);
return true;
}
catch (Exception e)
{
LoggerFactory.getLogger().error("Error occurred setting data for node: "
+ nodePath,
e);
}
}
return false;
}
/*
* (non-Javadoc)
*
* @seeorg.apache.zookeeper.inspector.manager.ZooInspectorManager#
* getConnectionPropertiesTemplate()
*/
@Override
public Pair<Map<String, List<String>>, Map<String, String>> getConnectionPropertiesTemplate()
{
Map<String, List<String>> template = new LinkedHashMap<String, List<String>>();
// template.put(CONNECT_STRING, Arrays.asList(new String[] { defaultHosts }));
template.put(CONNECT_STRING, defaultHostsList);
template.put(SESSION_TIMEOUT, Arrays.asList(new String[] { defaultTimeout }));
template.put(DATA_ENCRYPTION_MANAGER,
Arrays.asList(new String[] { defaultEncryptionManager }));
Map<String, String> labels = new LinkedHashMap<String, String>();
labels.put(CONNECT_STRING, "Connect String");
labels.put(SESSION_TIMEOUT, "Session Timeout");
labels.put(DATA_ENCRYPTION_MANAGER, "Data Encryption Manager");
return new Pair<Map<String, List<String>>, Map<String, String>>(template, labels);
}
/*
* (non-Javadoc)
*
* @see org.apache.zookeeper.inspector.manager.ZooInspectorManager#addWatchers
* (java.util.Collection, org.apache.zookeeper.inspector.manager.NodeListener)
*/
@Override
public void addWatchers(Collection<String> selectedNodes, NodeListener nodeListener)
{
// add watcher for each node and add node to collection of
// watched nodes
if (connected)
{
for (String node : selectedNodes)
{
if (!watchers.containsKey(node))
{
try
{
watchers.put(node, new NodeWatcher(node, nodeListener, zooKeeper));
}
catch (Exception e)
{
LoggerFactory.getLogger()
.error("Error occured adding node watcher for node: " + node, e);
}
}
}
}
}
/*
* (non-Javadoc)
*
* @see org.apache.zookeeper.inspector.manager.ZooInspectorManager#removeWatchers
* (java.util.Collection)
*/
@Override
public void removeWatchers(Collection<String> selectedNodes)
{
// remove watcher for each node and remove node from
// collection of watched nodes
if (connected)
{
for (String node : selectedNodes)
{
if (watchers.containsKey(node))
{
NodeWatcher watcher = watchers.remove(node);
if (watcher != null)
{
watcher.stop();
}
}
}
}
}
/**
* A Watcher which will re-add itself every time an event is fired
*
*/
public class NodeWatcher implements Watcher
{
private final String nodePath;
private final NodeListener nodeListener;
private final ZooKeeper zookeeper;
private boolean closed = false;
// cache stat and children when event fires
private final Stat stat = new Stat();
private List<String> childs;
/**
* @param nodePath
* - the path to the node to watch
* @param nodeListener
* the {@link NodeListener} for this node
* @param zookeeper
* - a {@link ZooKeeper} to use to access zookeeper
* @throws InterruptedException
* @throws KeeperException
*/
public NodeWatcher(String nodePath, NodeListener nodeListener, ZooKeeper zookeeper)
throws KeeperException, InterruptedException
{
this.nodePath = nodePath;
this.nodeListener = nodeListener;
this.zookeeper = zookeeper;
Stat s = zooKeeper.exists(nodePath, this);
if (s != null)
{
childs = zookeeper.getChildren(nodePath, this, stat);
}
}
@Override
public void process(WatchedEvent event)
{
if (!closed)
{
try
{
if (event.getType() != EventType.NodeDeleted)
{
Stat s = zooKeeper.exists(nodePath, this);
if (s != null)
{
childs = zookeeper.getChildren(nodePath, this, s);
}
}
}
catch (Exception e)
{
LoggerFactory.getLogger().error("Error occured re-adding node watcherfor node "
+ nodePath,
e);
}
if (nodeListener != null)
{
nodeListener.processEvent(event.getPath(), event.getType().name(), null);
}
}
}
/**
*
*/
public void stop()
{
this.closed = true;
}
public List<String> getChilds()
{
return childs;
}
}
/*
* (non-Javadoc)
*
* @seeorg.apache.zookeeper.inspector.manager.ZooInspectorManager#
* loadNodeViewersFile(java.io.File)
*/
@Override
public List<String> loadNodeViewersFile(File selectedFile) throws IOException
{
// TODO read from src/main/resources/defaultNodeVeiwers.cfg
List<String> result = new ArrayList<String>();
if (defaultNodeViewersFile.exists())
{
FileReader reader = new FileReader(selectedFile);
try
{
BufferedReader buff = new BufferedReader(reader);
try
{
while (buff.ready())
{
String line = buff.readLine();
if (line != null && line.length() > 0)
{
result.add(line);
}
}
}
finally
{
buff.close();
}
}
finally
{
reader.close();
}
} else {
result.add("org.apache.zookeeper.inspector.gui.nodeviewer.NodeViewerData");
result.add("org.apache.zookeeper.inspector.gui.nodeviewer.NodeViewerMetaData");
result.add("org.apache.zookeeper.inspector.gui.nodeviewer.NodeViewerACL");
}
return result;
}
private void loadDefaultConnectionFile() throws IOException
{
if (defaultConnectionFile.exists())
{
Properties props = new Properties();
FileReader reader = new FileReader(defaultConnectionFile);
try
{
props.load(reader);
}
finally
{
reader.close();
}
defaultEncryptionManager =
props.getProperty(DATA_ENCRYPTION_MANAGER) == null
? "org.apache.zookeeper.inspector.encryption.BasicDataEncryptionManager"
: props.getProperty(DATA_ENCRYPTION_MANAGER);
defaultTimeout =
props.getProperty(SESSION_TIMEOUT) == null ? "30000"
: props.getProperty(SESSION_TIMEOUT);
defaultHosts =
props.getProperty(CONNECT_STRING) == null ? "localhost:2181"
: props.getProperty(CONNECT_STRING);
}
else
{
defaultEncryptionManager =
"org.apache.zookeeper.inspector.encryption.BasicDataEncryptionManager";
defaultTimeout = "30000";
defaultHosts = "localhost:2181";
}
defaultHostsList = new ArrayList<String>(Arrays.asList(defaultHosts.trim().split("\\s+")));
System.out.println("defaultHostsList: " + defaultHostsList);
// System.out.println("end");
}
/*
* (non-Javadoc)
*
* @seeorg.apache.zookeeper.inspector.manager.ZooInspectorManager#
* saveDefaultConnectionFile(java.util.Properties)
*/
@Override
public void saveDefaultConnectionFile(Properties props) throws IOException
{
File defaultDir = defaultConnectionFile.getParentFile();
if (!defaultDir.exists())
{
if (!defaultDir.mkdirs())
{
throw new IOException("Failed to create configuration directory: "
+ defaultDir.getAbsolutePath());
}
}
if (!defaultConnectionFile.exists())
{
if (!defaultConnectionFile.createNewFile())
{
throw new IOException("Failed to create default connection file: "
+ defaultConnectionFile.getAbsolutePath());
}
}
FileWriter writer = new FileWriter(defaultConnectionFile);
try
{
props.store(writer, "Default connection for ZooInspector");
}
finally
{
writer.close();
}
}
@Override
public void updateDefaultConnectionFile(Properties connectionProps) throws IOException
{
Properties properties = new Properties();
String connStr = connectionProps.getProperty(CONNECT_STRING);
defaultHostsList.remove(connStr);
while (defaultHostsList.size() > defaultHostsListSize) {
defaultHostsList.remove(defaultHostsList.size()-1);
}
defaultHostsList.add(0, connStr);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < defaultHostsList.size(); i++) {
String str = defaultHostsList.get(i);
if (i > 0) {
sb.append(" ");
}
sb.append(str);
}
System.out.println("updateDefaultConnectionFile#connectString: " + sb.toString());
properties.setProperty(CONNECT_STRING, sb.toString());
properties.setProperty(SESSION_TIMEOUT, defaultTimeout);
properties.getProperty(DATA_ENCRYPTION_MANAGER, defaultEncryptionManager);
saveDefaultConnectionFile(properties);
}
/*
* (non-Javadoc)
*
* @seeorg.apache.zookeeper.inspector.manager.ZooInspectorManager#
* saveNodeViewersFile(java.io.File, java.util.List)
*/
@Override
public void saveNodeViewersFile(File selectedFile, List<String> nodeViewersClassNames) throws IOException
{
if (!selectedFile.exists())
{
if (!selectedFile.createNewFile())
{
throw new IOException("Failed to create node viewers configuration file: "
+ selectedFile.getAbsolutePath());
}
}
FileWriter writer = new FileWriter(selectedFile);
try
{
BufferedWriter buff = new BufferedWriter(writer);
try
{
for (String nodeViewersClassName : nodeViewersClassNames)
{
buff.append(nodeViewersClassName);
buff.append("\n");
}
}
finally
{
buff.flush();
buff.close();
}
}
finally
{
writer.close();
}
}
/*
* (non-Javadoc)
*
* @seeorg.apache.zookeeper.inspector.manager.ZooInspectorManager#
* setDefaultNodeViewerConfiguration(java.io.File, java.util.List)
*/
@Override
public void setDefaultNodeViewerConfiguration(List<String> nodeViewersClassNames) throws IOException
{
File defaultDir = defaultNodeViewersFile.getParentFile();
if (!defaultDir.exists())
{
if (!defaultDir.mkdirs())
{
throw new IOException("Failed to create configuration directory: "
+ defaultDir.getAbsolutePath());
}
}
saveNodeViewersFile(defaultNodeViewersFile, nodeViewersClassNames);
}
@Override
public List<String> getDefaultNodeViewerConfiguration() throws IOException
{
return loadNodeViewersFile(defaultNodeViewersFile);
}
/*
* (non-Javadoc)
*
* @seeorg.apache.zookeeper.inspector.manager.ZooInspectorManager#
* getLastConnectionProps()
*/
@Override
public Properties getLastConnectionProps()
{
return this.lastConnectionProps;
}
/*
* (non-Javadoc)
*
* @seeorg.apache.zookeeper.inspector.manager.ZooInspectorManager#
* setLastConnectionProps(java.util.Properties)
*/
@Override
public void setLastConnectionProps(Properties connectionProps)
{
this.lastConnectionProps = connectionProps;
}
@Override
public ZooInspectorManagerCache getCache()
{
return cache;
}
@Override
public States getZookeeperStates()
{
if (zooKeeper == null)
{
return null;
}
return zooKeeper.getState();
}
}