com.cip.crane.zookeeper.common.heartbeat.PollingAgentMonitor.java Source code

Java tutorial

Introduction

Here is the source code for com.cip.crane.zookeeper.common.heartbeat.PollingAgentMonitor.java

Source

/**
 * Project: taurus-zookeeper-helper
 * 
 * File Created at 2013-7-23
 * $Id$
 * 
 * Copyright 2013 dianping.com.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * Dianping Company. ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with dianping.com.
 */
package com.cip.crane.zookeeper.common.heartbeat;

import java.io.InputStream;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicBoolean;

import com.cip.crane.common.utils.ClassLoaderUtils;
import com.dianping.lion.EnvZooKeeperConfig;
import com.dianping.lion.client.ConfigCache;

import org.I0Itec.zkclient.ZkClient;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * PollingAgentMonitor monitor agent by checkout zookeeper heart beat termly
 * 
 * @author renyuan.sun
 */
public class PollingAgentMonitor implements AgentMonitor {

    private ZkClient zkClient;
    private List<String> lastAgents;
    protected static final long THIRTY_SECONDS = 30 * 1000;

    private static final String WATCH_PATH = "/taurus/heartbeats/agent/realtime";
    private static final String ZKCONFIG = "zooKeeper.properties";
    private static final long TIMEOUT = 5 * 60 * 1000;
    private static final Log LOGGER = LogFactory.getLog(PollingAgentMonitor.class);

    private final AtomicBoolean isInterrupt = new AtomicBoolean(false);

    public PollingAgentMonitor() {
        Properties props = new Properties();
        try {
            InputStream in = ClassLoaderUtils.getDefaultClassLoader().getResourceAsStream(ZKCONFIG);
            props.load(in);
            in.close();

            String connectString = ConfigCache.getInstance(EnvZooKeeperConfig.getZKAddress())
                    .getProperty("taurus.zookeeper.connectstring"); //props.getProperty("connectionString");

            int sessionTimeout = Integer.parseInt(props.getProperty("sessionTimeout"));
            zkClient = new ZkClient(connectString, sessionTimeout);
        } catch (Exception e) {
            throw new RuntimeException("Error initialize zookeeper client", e);
        }
    }

    @Override
    public void agentMonitor(final AgentHandler handler) {
        lastAgents = handler.getConnectedFromDB();
        Thread monitorThread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {

                    while (isInterrupt.get()) {
                    }

                    try {
                        checkAgentStatus(handler);
                        Thread.sleep(THIRTY_SECONDS);
                    } catch (InterruptedException e) {
                        LOGGER.error(e, e);
                    }

                }
            }
        });
        monitorThread.start();
    }

    private void checkAgentStatus(AgentHandler handler) {
        List<String> currentAgents = getConnectedHosts();
        for (String disConnectedIP : lastAgents) {
            boolean hasDisConnected = true;
            for (String tmp : currentAgents) {
                if (disConnectedIP.equals(tmp)) {
                    hasDisConnected = false;
                    break;
                }
            }
            if (hasDisConnected) {
                handler.disConnected(disConnectedIP);
            }
        }

        for (String connectedIP : currentAgents) {
            boolean hasConnectedIP = true;
            for (String tmp : lastAgents) {
                if (connectedIP.equals(tmp)) {
                    hasConnectedIP = false;
                    break;
                }
            }
            if (hasConnectedIP) {
                handler.connected(connectedIP);
            }
        }
        lastAgents = currentAgents;
    }

    private List<String> getConnectedHosts() {
        List<String> ips = zkClient.getChildren(WATCH_PATH);
        for (int i = 0; i < ips.size(); i++) {
            if (!isConnected(ips.get(i))) {
                ips.remove(i);
                i--;
            }
        }
        return ips;
    }

    private boolean isConnected(String ip) {
        Long time = null;
        try {
            time = zkClient.readData(WATCH_PATH + "/" + ip, true);
            //LOGGER.info("Agent " + ip + "'s last heartbeat time is" + new Date(time));
        } catch (Exception e) {
            LOGGER.error(e, e);
        }
        long now = System.currentTimeMillis();
        if (time == null) {
            return false;
        }
        if (now - time > TIMEOUT)
            return false;
        else {
            return true;
        }
    }

    @Override
    public void interruptMonitor(boolean interrupt) {
        boolean current = isInterrupt.get();
        isInterrupt.compareAndSet(current, interrupt);
    }

}