Package io.fathom.cloud.zookeeper

Source Code of io.fathom.cloud.zookeeper.ZookeeperClient

package io.fathom.cloud.zookeeper;

import java.io.IOException;
import java.util.List;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.KeeperException.Code;
import org.apache.zookeeper.KeeperException.NoNodeException;
import org.apache.zookeeper.KeeperException.NodeExistsException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.CharMatcher;
import com.google.common.util.concurrent.SettableFuture;

public class ZookeeperClient {
    private static final Logger log = LoggerFactory.getLogger(ZookeeperClient.class);

    ZooKeeper zk;

    private final String connectString;

    public ZookeeperClient(String connectString) {
        log.info("Building zookeeper client to {}", connectString);
        this.connectString = connectString;
    }

    protected synchronized ZooKeeper getZk() throws IOException {
        ZooKeeper zk = this.zk;
        if (zk == null) {
            int sessionTimeout = 20000;
            Watcher watcher = new Watcher() {
                @Override
                public void process(WatchedEvent event) {
                    log.debug("Got ZK event {}", event);
                }
            };
            try {
                zk = new ZooKeeper(connectString, sessionTimeout, watcher);
            } catch (IOException e) {
                throw new IOException("Unable to connect to zookeeper", e);
            }
            this.zk = zk;
        }
        return zk;
    }

    protected synchronized ZooKeeper closeZk() {
        ZooKeeper zk = this.zk;
        if (zk != null) {
            this.zk = null;

            try {
                zk.close();
            } catch (Exception e) {
                log.warn("Error closing zk", e);
            }
        }
        return zk;
    }

    public Stat exists(String path, boolean watch) throws KeeperException, IOException {
        try {
            return getZk().exists(path, watch);
        } catch (KeeperException e) {
            if (processException(e)) {
                return exists(path, watch);
            }
            throw e;
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new IOException("Interrupted while communicating with zookeeper", e);
        }
    }

    public void delete(String path, int version) throws KeeperException, IOException {
        try {
            getZk().delete(path, version);
        } catch (KeeperException e) {
            if (processException(e)) {
                delete(path, version);
                return;
            }
            throw e;
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new IOException("Interrupted while communicating with zookeeper", e);
        }
    }

    public List<String> getChildren(String path, boolean watch) throws KeeperException, IOException {
        try {
            return getZk().getChildren(path, watch);
        } catch (KeeperException e) {
            if (processException(e)) {
                return getChildren(path, watch);
            }
            throw e;
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new IOException("Interrupted while communicating with zookeeper", e);
        }
    }

    public byte[] getData(String path, SettableFuture<Object> watch, Stat stat) throws IOException, KeeperException {
        try {
            Watcher watcher = null;

            if (watch != null) {
                watcher = new ListenableWatcher(watch);
            }

            return getZk().getData(path, watcher, stat);
        } catch (KeeperException e) {
            if (processException(e)) {
                return getData(path, watch, stat);
            }
            throw e;
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new IOException("Interrupted while communicating with zookeeper", e);
        }
    }

    public Stat setData(String path, byte[] data, int version) throws KeeperException, IOException {
        try {
            return getZk().setData(path, data, version);
        } catch (KeeperException e) {
            if (processException(e)) {
                return setData(path, data, version);
            }
            throw e;
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new IOException("Interrupted while communicating with zookeeper", e);
        }
    }

    private boolean processException(KeeperException e) {
        Code code = e.code();
        switch (code) {
        case SESSIONEXPIRED:
            log.warn("Closing ZK session after SESSIONEXPIRED");
            closeZk();
            return true;
        case CONNECTIONLOSS:
            log.warn("Closing ZK session after CONNECTIONLOSS");
            closeZk();
            return true;

        default:
            return false;
        }
    }

    public String create(final String path, byte[] data, List<ACL> acl, CreateMode createMode) throws IOException,
            KeeperException {
        try {
            return getZk().create(path, data, acl, createMode);
        } catch (KeeperException e) {
            if (processException(e)) {
                return create(path, data, acl, createMode);
            }
            throw e;
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new IOException("Interrupted while communicating with zookeeper", e);
        }
    }

    public void mkdirs(String path) throws KeeperException, IOException {
        try {
            log.debug("ZK create on {}", path);

            getZk().create(path, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        } catch (NoNodeException e) {
            mkdirs(getParent(path));
            mkdirs(path);
        } catch (NodeExistsException e) {
            return;
        } catch (KeeperException e) {
            if (processException(e)) {
                mkdirs(path);
                return;
            }
            throw e;
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new IOException("Error communicating with zookeeper", e);
        }
    }

    public static String getParent(String zkPath) {
        zkPath = CharMatcher.is('/').trimTrailingFrom(zkPath);

        int lastSlash = zkPath.lastIndexOf('/');
        if (lastSlash == -1) {
            throw new IllegalArgumentException();
        }
        return zkPath.substring(0, lastSlash);
    }

    public void createOrUpdate(String path, byte[] data, boolean mkdirs) throws KeeperException, IOException {
        try {
            setData(path, data, -1);
        } catch (NoNodeException e) {
            create(path, data, mkdirs);
        }
    }

    public String create(final String path, byte[] data, boolean mkdirs) throws IOException, KeeperException {
        try {
            return create(path, data, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        } catch (NoNodeException e) {
            if (mkdirs) {
                mkdirs(getParent(path));
                return create(path, data, false);
            } else {
                throw e;
            }
        }
    }

    public static String escape(String s) {
        StringBuilder sb = new StringBuilder(s.length());

        int length = s.length();
        for (int i = 0; i < length; i++) {
            char c = s.charAt(i);

            if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
                sb.append(c);
            } else {
                switch (c) {
                case '.':
                case ':':
                case '-':
                    sb.append(c);
                    break;

                default: {
                    String v = Integer.toHexString(c);
                    switch (v.length()) {
                    case 1:
                        sb.append("_0" + v);
                        break;

                    case 2:
                        sb.append("_" + v);
                        break;

                    case 3:
                        sb.append("__0" + v);
                        break;

                    case 4:
                        sb.append("__" + v);
                        break;

                    default:
                        throw new UnsupportedOperationException();
                    }
                }
                    break;
                }
            }
        }

        return sb.toString();
    }

}
TOP

Related Classes of io.fathom.cloud.zookeeper.ZookeeperClient

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.