![JAR search and dependency download from the Maven repository](/logo.png)
com.github.ltsopensource.zookeeper.curator.CuratorZkClient Maven / Gradle / Ivy
package com.github.ltsopensource.zookeeper.curator;
import com.github.ltsopensource.core.cluster.Config;
import com.github.ltsopensource.core.registry.NodeRegistryUtils;
import com.github.ltsopensource.zookeeper.ChildListener;
import com.github.ltsopensource.zookeeper.DataListener;
import com.github.ltsopensource.zookeeper.StateListener;
import com.github.ltsopensource.zookeeper.lts.ZkException;
import com.github.ltsopensource.zookeeper.serializer.SerializableSerializer;
import com.github.ltsopensource.zookeeper.serializer.ZkSerializer;
import com.github.ltsopensource.zookeeper.support.AbstractZkClient;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.*;
import org.apache.curator.framework.state.ConnectionState;
import org.apache.curator.framework.state.ConnectionStateListener;
import org.apache.curator.retry.RetryNTimes;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import java.io.IOException;
import java.io.Serializable;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* @author Robert HG ([email protected]) on 5/16/15.
*/
public class CuratorZkClient extends AbstractZkClient {
private final CuratorFramework client;
private final ZkSerializer zkSerializer;
public CuratorZkClient(Config config) {
String registryAddress = NodeRegistryUtils.getRealRegistryAddress(config.getRegistryAddress());
CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder()
.connectString(registryAddress)
.retryPolicy(new RetryNTimes(Integer.MAX_VALUE, 1000))
.connectionTimeoutMs(5000);
client = builder.build();
client.getConnectionStateListenable().addListener(new ConnectionStateListener() {
public void stateChanged(CuratorFramework client, ConnectionState state) {
if (state == ConnectionState.LOST) {
CuratorZkClient.this.stateChanged(StateListener.DISCONNECTED);
} else if (state == ConnectionState.CONNECTED) {
CuratorZkClient.this.stateChanged(StateListener.CONNECTED);
} else if (state == ConnectionState.RECONNECTED) {
CuratorZkClient.this.stateChanged(StateListener.RECONNECTED);
} else if (state == ConnectionState.SUSPENDED) {
CuratorZkClient.this.stateChanged(StateListener.DISCONNECTED);
}
}
});
zkSerializer = new SerializableSerializer();
client.start();
}
@Override
protected String createPersistent(String path, boolean sequential) {
try {
if (sequential) {
return client.create().withMode(CreateMode.PERSISTENT_SEQUENTIAL).forPath(path);
} else {
return client.create().withMode(CreateMode.PERSISTENT).forPath(path);
}
} catch (KeeperException.NodeExistsException e) {
return path;
} catch (Exception e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
@Override
protected String createPersistent(String path, Object data, boolean sequential) {
try {
if (sequential) {
byte[] zkDataBytes;
if (data instanceof Serializable) {
zkDataBytes = zkSerializer.serialize(data);
} else {
zkDataBytes = (byte[]) data;
}
return client.create().withMode(CreateMode.PERSISTENT_SEQUENTIAL).forPath(path, zkDataBytes);
} else {
return client.create().withMode(CreateMode.PERSISTENT).forPath(path);
}
} catch (KeeperException.NodeExistsException e) {
return path;
} catch (Exception e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
@Override
protected String createEphemeral(String path, boolean sequential) {
try {
if (sequential) {
return client.create().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath(path);
} else {
return client.create().withMode(CreateMode.EPHEMERAL).forPath(path);
}
} catch (KeeperException.NodeExistsException e) {
return path;
} catch (Exception e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
@Override
protected String createEphemeral(String path, Object data, boolean sequential) {
try {
if (sequential) {
byte[] zkDataBytes;
if (data instanceof Serializable) {
zkDataBytes = zkSerializer.serialize(data);
} else {
zkDataBytes = (byte[]) data;
}
return client.create().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath(path, zkDataBytes);
} else {
return client.create().withMode(CreateMode.EPHEMERAL).forPath(path);
}
} catch (KeeperException.NodeExistsException e) {
return path;
} catch (Exception e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
protected PathChildrenListener createTargetChildListener(final String path, final ChildListener listener) {
return new PathChildrenListener(path, listener);
}
protected List addTargetChildListener(String path, PathChildrenListener listener) {
try {
listener.startListener();
return client.getChildren().forPath(path);
} catch (KeeperException.NoNodeException e) {
return null;
} catch (Exception e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
protected void removeTargetChildListener(String path, PathChildrenListener listener) {
listener.stopListener();
}
@Override
protected void addTargetDataListener(String path, NodeListener listener) {
listener.startListener();
}
@Override
protected NodeListener createTargetDataListener(String path, final DataListener listener) {
return new NodeListener(path, listener);
}
@Override
protected void removeTargetDataListener(String path, NodeListener listener) {
listener.stopListener();
}
@Override
public boolean delete(String path) {
try {
client.delete().forPath(path);
return true;
} catch (KeeperException.NoNodeException e) {
return true;
} catch (Exception e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
@Override
public boolean exists(String path) {
try {
return client.checkExists().forPath(path) != null;
} catch (Exception e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
@SuppressWarnings("unchecked")
@Override
public T getData(String path) {
try {
return (T) zkSerializer.deserialize(client.getData().forPath(path));
} catch (Exception e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
@Override
public void setData(String path, Object data) {
byte[] zkDataBytes;
if (data instanceof Serializable) {
zkDataBytes = zkSerializer.serialize(data);
} else {
zkDataBytes = (byte[]) data;
}
try {
client.setData().forPath(path, zkDataBytes);
} catch (Exception e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
@Override
public List getChildren(String path) {
try {
return client.getChildren().forPath(path);
} catch (KeeperException.NoNodeException e) {
return null;
} catch (Exception e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
@Override
public boolean isConnected() {
return client.getZookeeperClient().isConnected();
}
@Override
protected void doClose() {
client.close();
}
public class PathChildrenListener {
private PathChildrenCache childrenCache;
private PathChildrenCacheListener childrenCacheListener;
private AtomicBoolean start = new AtomicBoolean(false);
public PathChildrenListener(String path, final ChildListener listener) {
childrenCache = new PathChildrenCache(client, path, true);
childrenCacheListener = new PathChildrenCacheListener() {
@Override
public void childEvent(CuratorFramework c, PathChildrenCacheEvent event)
throws Exception {
switch (event.getType()) {
case CHILD_ADDED:
case CHILD_REMOVED:
case CHILD_UPDATED:
String childPath = event.getData().getPath();
String parentPath = childPath.substring(0, childPath.lastIndexOf("/"));
List children = client.getChildren().forPath(parentPath);
listener.childChanged(parentPath, children);
default:
break;
}
}
};
}
public void startListener() {
try {
if (start.compareAndSet(false, true)) {
childrenCache.start(PathChildrenCache.StartMode.POST_INITIALIZED_EVENT);
childrenCache.getListenable().addListener(childrenCacheListener);
}
} catch (Exception e) {
throw new ZkException(e);
}
}
public void stopListener() {
try {
if (start.compareAndSet(true, false)) {
childrenCache.getListenable().removeListener(childrenCacheListener);
childrenCache.clear();
childrenCache.close();
}
} catch (IOException e) {
throw new ZkException(e);
}
}
}
public class NodeListener {
private NodeCache nodeCache;
private NodeCacheListener nodeCacheListener;
private AtomicBoolean start = new AtomicBoolean(false);
public NodeListener(String path, final DataListener listener) {
nodeCache = new NodeCache(client, path, false);
nodeCacheListener = new NodeCacheListener() {
@Override
public void nodeChanged() throws Exception {
String path = nodeCache.getCurrentData().getPath();
Object data = nodeCache.getCurrentData().getData();
if (data == null) {
listener.dataDeleted(path);
} else {
listener.dataChange(path, data);
}
}
};
}
public void startListener() {
try {
if (start.compareAndSet(false, true)) {
nodeCache.start(true);
nodeCache.getListenable().addListener(nodeCacheListener);
}
} catch (Exception e) {
throw new ZkException(e);
}
}
public void stopListener() {
try {
if (start.compareAndSet(true, false)) {
nodeCache.getListenable().removeListener(nodeCacheListener);
nodeCache.close();
}
} catch (IOException e) {
throw new ZkException(e);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy