org.prot.util.zookeeper.ZooHelper.java Source code

Java tutorial

Introduction

Here is the source code for org.prot.util.zookeeper.ZooHelper.java

Source

/*******************************************************************************
 * Copyright (c) 2010 Andreas Wolke.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Andreas Wolke - initial API and implementation and initial documentation
 *******************************************************************************/
package org.prot.util.zookeeper;

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

import org.apache.log4j.Logger;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.ZooKeeper.States;
import org.apache.zookeeper.data.ACL;

public class ZooHelper implements Watcher {
    private static final Logger logger = Logger.getLogger(ZooHelper.class);

    private static final int SESSION_TIMEOUT = 4000;

    // ZooKeeper host and port
    private String host;
    private int port;

    // ZooKeeper connection
    private ZooKeeper zooKeeper;

    // Job queue which manages the execution of all ZooKeeper jobs
    private JobQueue queue;

    // Listeners
    private List<SynchronizationListener> listeners = new ArrayList<SynchronizationListener>();

    public ZooHelper(String host, int port) {
        this.host = host;
        this.port = port;

        // Create a new job queue
        queue = new JobQueue(this);
    }

    public void setup() {
        // Prevent queue from accepting further connection jobs
        queue.finishSetup();

        // Connect
        reconnect();
    }

    public void addListener(SynchronizationListener listener) {
        synchronized (listeners) {
            listeners.add(listener);
        }
    }

    private void listenerReconnect() {
        ArrayList<SynchronizationListener> copy = new ArrayList<SynchronizationListener>();
        synchronized (listeners) {
            copy.addAll(listeners);
        }

        for (SynchronizationListener listener : copy)
            listener.reconnected(this);
    }

    @Override
    public void process(WatchedEvent event) {
        logger.info("ZooKeeper event");
        switch (event.getState()) {
        case Expired:
            logger.info("ZooKeeper session expired");
            break;
        case Disconnected:
            logger.info("ZooKeeper disconnected");
            break;
        default:
            logger.debug("Unhandled ZooKeeper event");
            return;
        }

        reconnect();
    }

    final synchronized void reconnect() {
        if (isConnected())
            return;

        zooKeeper = null;
        connect();
        listenerReconnect();
        queue.reconnected();
        queue.proceed();
    }

    private synchronized boolean isConnected() {
        if (zooKeeper == null)
            return false;

        return zooKeeper.getState() == States.CONNECTED;
    }

    public boolean checkConnection() {
        boolean connected = isConnected();

        if (!connected)
            reconnect();

        return connected;
    }

    private synchronized final void connect() {
        try {
            while (zooKeeper == null) {
                logger.info("ZooKeeper is connecting...");

                // Create a new ZooKeeper instance
                ZooKeeper connection = new ZooKeeper(host + ":" + port, SESSION_TIMEOUT, this);

                // Wait while ZooKeeper is CONNECTING
                while (connection.getState() == States.CONNECTING) {
                    logger.debug("ZooKeeper is waiting for connection ...");
                    Thread.sleep(1000);
                }

                // Check if it is connected
                if (connection.getState() == States.CONNECTED) {
                    logger.info("Connected with ZooKeeper");
                    zooKeeper = connection;
                } else {
                    logger.warn("Could not connect with ZooKeeper...");
                    Thread.sleep(3000);
                }
            }
        } catch (InterruptedException e) {
            logger.error("InterruptedException", e);
            System.exit(1);
        } catch (IOException e) {
            logger.error("IOException", e);
            System.exit(1);
        }
    }

    public final List<ACL> getACL() {
        List<ACL> acl = new ArrayList<ACL>();

        ACL all = new ACL();
        all.setId(ZooDefs.Ids.ANYONE_ID_UNSAFE);
        all.setPerms(ZooDefs.Perms.ALL);

        acl.add(all);

        return acl;
    }

    public final JobQueue getQueue() {
        return queue;
    }

    public final ZooKeeper getZooKeeper() {
        return zooKeeper;
    }
}