// Path: zing-common/src/main/java/org/zxc/zing/common/constant/Constants.java
// public class Constants {
//     public final static int SERVER_DEFAULT_PORT = 4080;
// 
//     public final static String SERVER_IP_ADDRESS_CONFIG_KEY = "server.address.ip";
// 
//     public final static String SERVER_PORT_CONFIG_KEY = "server.address.port";
// 
//     public final static String ZOOKEEPER_ADDRESS = "registry.zookeeper.address";
// 
//     public final static String ZOOKEEPER_PATH_SEPARATOR = "/";
// 
//     public final static String SERVICE_ZK_PATH_PREFIX = "/zing/service";
// 
//     public final static String SERVICE_ZK_PATH_FORMAT = SERVICE_ZK_PATH_PREFIX+"/%s";
// }
// 
// Path: zing-common/src/main/java/org/zxc/zing/common/util/ZookeeperPathUtils.java
// public class ZookeeperPathUtils {
// 
//     private static final int PROVIDER_INFO_NODE_DEPTH = 4;
//     private static final int SERVICE_NAME_ZK_PATH_DEPTH = 3;
// 
//     public static String formatProviderPath(String serviceName, String ip, int port) {
//         StringBuilder pathBuilder = new StringBuilder();
// 
//         String serviceZkPath = String.format(Constants.SERVICE_ZK_PATH_FORMAT, serviceName);
//         pathBuilder.append(serviceZkPath);
//         pathBuilder.append("/");
// 
//         pathBuilder.append(ip);
//         pathBuilder.append(":");
//         pathBuilder.append(port);
// 
//         return pathBuilder.toString();
//     }
// 
//     public static boolean isServiceProviderNode(String nodePath) {
//         return ZookeeperPathUtils.zkNodeDepth(nodePath) == PROVIDER_INFO_NODE_DEPTH;
//     }
// 
//     public static int zkNodeDepth(String nodePath) {
//         if (Strings.isNullOrEmpty(nodePath) || "/".equals(nodePath)) {
//             return 0;
//         }
//         if (!nodePath.startsWith("/")) {
//             throw new IllegalArgumentException("zookeeper path should start with /!");
//         }
//         String pathWithoutFirstSlash = nodePath.substring(1);
//         return Iterables.size(Splitter.on(Constants.ZOOKEEPER_PATH_SEPARATOR).split(pathWithoutFirstSlash));
//     }
// 
//     public static String getServiceNameFromProviderZkPath(String providerZkPath) {
//         String pathWithoutFirstSlash = providerZkPath.substring(1);
//         List<String> parts = Lists.newArrayList(Splitter.on(Constants.ZOOKEEPER_PATH_SEPARATOR).split(pathWithoutFirstSlash));
//         return parts.get(SERVICE_NAME_ZK_PATH_DEPTH - 1);
//     }
// 
// }


import com.google.common.base.Strings;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.cache.TreeCacheEvent;
import org.apache.curator.framework.recipes.cache.TreeCacheListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zxc.zing.common.constant.Constants;
import org.zxc.zing.common.util.ZookeeperPathUtils;
package org.zxc.zing.common.registry;



/**
 * Created by xuanchen.zhao on 16-1-17.
 */
public class ProviderNodeEventListener implements TreeCacheListener {

    private static final Logger log = LoggerFactory.getLogger(ProviderNodeEventListener.class);

    @Override
    public void childEvent(CuratorFramework client, TreeCacheEvent event) throws Exception {
        log.info("curator event received:"+event);

        if (!isServiceProviderNodeChangeEvent(event)) {
            return;
        }

        String serviceName = ZookeeperPathUtils.getServiceNameFromProviderZkPath(event.getData().getPath());
        if (Strings.isNullOrEmpty(serviceName)) {
            return;
        }

        ProviderStateListenerManager.getInstance().onProviderChange(serviceName);

    }

    private boolean isServiceProviderNodeChangeEvent(TreeCacheEvent event) {
        if (event == null || event.getData() == null) {
// Path: zing-common/src/main/java/org/zxc/zing/common/constant/Constants.java
// public class Constants {
//     public final static int SERVER_DEFAULT_PORT = 4080;
// 
//     public final static String SERVER_IP_ADDRESS_CONFIG_KEY = "server.address.ip";
// 
//     public final static String SERVER_PORT_CONFIG_KEY = "server.address.port";
// 
//     public final static String ZOOKEEPER_ADDRESS = "registry.zookeeper.address";
// 
//     public final static String ZOOKEEPER_PATH_SEPARATOR = "/";
// 
//     public final static String SERVICE_ZK_PATH_PREFIX = "/zing/service";
// 
//     public final static String SERVICE_ZK_PATH_FORMAT = SERVICE_ZK_PATH_PREFIX+"/%s";
// }
// 
// Path: zing-common/src/main/java/org/zxc/zing/common/util/ZookeeperPathUtils.java
// public class ZookeeperPathUtils {
// 
//     private static final int PROVIDER_INFO_NODE_DEPTH = 4;
//     private static final int SERVICE_NAME_ZK_PATH_DEPTH = 3;
// 
//     public static String formatProviderPath(String serviceName, String ip, int port) {
//         StringBuilder pathBuilder = new StringBuilder();
// 
//         String serviceZkPath = String.format(Constants.SERVICE_ZK_PATH_FORMAT, serviceName);
//         pathBuilder.append(serviceZkPath);
//         pathBuilder.append("/");
// 
//         pathBuilder.append(ip);
//         pathBuilder.append(":");
//         pathBuilder.append(port);
// 
//         return pathBuilder.toString();
//     }
// 
//     public static boolean isServiceProviderNode(String nodePath) {
//         return ZookeeperPathUtils.zkNodeDepth(nodePath) == PROVIDER_INFO_NODE_DEPTH;
//     }
// 
//     public static int zkNodeDepth(String nodePath) {
//         if (Strings.isNullOrEmpty(nodePath) || "/".equals(nodePath)) {
//             return 0;
//         }
//         if (!nodePath.startsWith("/")) {
//             throw new IllegalArgumentException("zookeeper path should start with /!");
//         }
//         String pathWithoutFirstSlash = nodePath.substring(1);
//         return Iterables.size(Splitter.on(Constants.ZOOKEEPER_PATH_SEPARATOR).split(pathWithoutFirstSlash));
//     }
// 
//     public static String getServiceNameFromProviderZkPath(String providerZkPath) {
//         String pathWithoutFirstSlash = providerZkPath.substring(1);
//         List<String> parts = Lists.newArrayList(Splitter.on(Constants.ZOOKEEPER_PATH_SEPARATOR).split(pathWithoutFirstSlash));
//         return parts.get(SERVICE_NAME_ZK_PATH_DEPTH - 1);
//     }
// 
// }


// Path: zing-common/src/main/java/org/zxc/zing/common/registry/ProviderNodeEventListener.java
import com.google.common.base.Strings;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.cache.TreeCacheEvent;
import org.apache.curator.framework.recipes.cache.TreeCacheListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zxc.zing.common.constant.Constants;
import org.zxc.zing.common.util.ZookeeperPathUtils;

package org.zxc.zing.common.registry;



/**
 * Created by xuanchen.zhao on 16-1-17.
 */
public class ProviderNodeEventListener implements TreeCacheListener {

    private static final Logger log = LoggerFactory.getLogger(ProviderNodeEventListener.class);

    @Override
    public void childEvent(CuratorFramework client, TreeCacheEvent event) throws Exception {
        log.info("curator event received:"+event);

        if (!isServiceProviderNodeChangeEvent(event)) {
            return;
        }

        String serviceName = ZookeeperPathUtils.getServiceNameFromProviderZkPath(event.getData().getPath());
        if (Strings.isNullOrEmpty(serviceName)) {
            return;
        }

        ProviderStateListenerManager.getInstance().onProviderChange(serviceName);

    }

    private boolean isServiceProviderNodeChangeEvent(TreeCacheEvent event) {
        if (event == null || event.getData() == null) {
            return false;