com.alibaba.wasp.WaspCluster.java Source code

Java tutorial

Introduction

Here is the source code for com.alibaba.wasp.WaspCluster.java

Source

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.alibaba.wasp;

import com.alibaba.wasp.client.ClientProtocol;
import com.alibaba.wasp.fserver.AdminProtocol;
import com.alibaba.wasp.master.FMasterAdminProtocol;
import com.alibaba.wasp.master.FMasterMonitorProtocol;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configurable;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.util.Threads;

import java.io.Closeable;
import java.io.IOException;

/**
 * This class defines methods that can help with managing Wasp clusters from
 * unit tests and system tests. There are 1 type of cluster deployments:
 * <ul>
 * <li><b>MiniWaspCluster:</b> each server is run in the same JVM in separate
 * threads, used by unit tests</li>
 * <p>
 * WaspCluster unifies the way tests interact with the cluster, so that the same
 * test can be run against a mini-cluster during unit test execution.
 * 
 * <p>
 * WaspCluster exposes client-side public interfaces to tests, so that tests
 * does not assume running in a particular mode. Not all the tests are suitable
 * to be run on an actual cluster, and some tests will still need to mock stuff
 * and introspect internal state. For those use cases from unit tests, or if
 * more control is needed, you can use the subclasses directly. In that sense,
 * this class does not abstract away <strong>every</strong> interface that
 * MiniWaspCluster provides.
 */
public abstract class WaspCluster implements Closeable, Configurable {
    static final Log LOG = LogFactory.getLog(WaspCluster.class.getName());
    protected Configuration conf;

    /** the status of the cluster before we begin */
    protected ClusterStatus initialClusterStatus;

    /**
     * Construct an HBaseCluster
     * 
     * @param conf
     *          Configuration to be used for cluster
     */
    public WaspCluster(Configuration conf) {
        setConf(conf);
    }

    @Override
    public void setConf(Configuration conf) {
        this.conf = conf;
    }

    @Override
    public Configuration getConf() {
        return conf;
    }

    /**
     * Returns a ClusterStatus for this HBase cluster.
     * 
     * @see #getInitialClusterStatus()
     */
    public abstract ClusterStatus getClusterStatus() throws IOException;

    /**
     * Returns a ClusterStatus for this HBase cluster as observed at the starting
     * of the HBaseCluster
     */
    public ClusterStatus getInitialClusterStatus() throws IOException {
        return initialClusterStatus;
    }

    /**
     * Returns an {@link com.alibaba.wasp.master.FMasterAdminProtocol} to the active master
     */
    public abstract FMasterAdminProtocol getMasterAdmin() throws IOException;

    /**
     * Returns an {@link com.alibaba.wasp.master.FMasterMonitorProtocol} to the active master
     */
    public abstract FMasterMonitorProtocol getMasterMonitor() throws IOException;

    /**
     * Returns an AdminProtocol interface to the fserver
     */
    public abstract AdminProtocol getAdminProtocol(ServerName serverName) throws IOException;

    /**
     * Returns a ClientProtocol interface to the fserver
     */
    public abstract ClientProtocol getClientProtocol(ServerName serverName) throws IOException;

    /**
     * Starts a new fserver on the given hostname or if this is a mini/local
     * cluster, starts a fserver locally.
     *
     * @param hostname
     *          the hostname to start the fserver on
     * @throws java.io.IOException
     *           if something goes wrong
     */
    public abstract void startFServer(String hostname) throws IOException;

    /**
     * Kills the fserver process if this is a distributed cluster, otherwise this
     * causes the fserver to exit doing basic clean up only.
     *
     * @throws java.io.IOException
     *           if something goes wrong
     */
    public abstract void killFServer(ServerName serverName) throws IOException;

    /**
     * Stops the given fserver, by attempting a gradual stop.
     *
     * @return whether the operation finished with success
     * @throws java.io.IOException
     *           if something goes wrong
     */
    public abstract void stopFServer(ServerName serverName) throws IOException;

    /**
     * Wait for the specified fserver to join the cluster
     *
     * @return whether the operation finished with success
     * @throws java.io.IOException
     *           if something goes wrong or timeout occurs
     */
    public void waitForFServerToStart(String hostname, long timeout) throws IOException {
        long start = System.currentTimeMillis();
        while ((System.currentTimeMillis() - start) < timeout) {
            for (ServerName server : getClusterStatus().getServers()) {
                if (server.getHostname().equals(hostname)) {
                    return;
                }
            }
            Threads.sleep(100);
        }
        throw new IOException("did timeout waiting for fserver to start:" + hostname);
    }

    /**
     * Wait for the specified fserver to stop the thread / process.
     *
     * @return whether the operation finished with success
     * @throws java.io.IOException
     *           if something goes wrong or timeout occurs
     */
    public abstract void waitForFServerToStop(ServerName serverName, long timeout) throws IOException;

    /**
     * Starts a new master on the given hostname or if this is a mini/local
     * cluster, starts a master locally.
     *
     * @param hostname
     *          the hostname to start the master on
     * @return whether the operation finished with success
     * @throws java.io.IOException
     *           if something goes wrong
     */
    public abstract void startMaster(String hostname) throws IOException;

    /**
     * Kills the master process if this is a distributed cluster, otherwise, this
     * causes master to exit doing basic clean up only.
     *
     * @throws java.io.IOException
     *           if something goes wrong
     */
    public abstract void killMaster(ServerName serverName) throws IOException;

    /**
     * Stops the given master, by attempting a gradual stop.
     *
     * @throws java.io.IOException
     *           if something goes wrong
     */
    public abstract void stopMaster(ServerName serverName) throws IOException;

    /**
     * Wait for the specified master to stop the thread / process.
     *
     * @throws java.io.IOException
     *           if something goes wrong or timeout occurs
     */
    public abstract void waitForMasterToStop(ServerName serverName, long timeout) throws IOException;

    /**
     * Blocks until there is an active master and that master has completed
     * initialization.
     *
     * @return true if an active master becomes available. false if there are no
     *         masters left.
     * @throws java.io.IOException
     *           if something goes wrong or timeout occurs
     */
    public boolean waitForActiveAndReadyMaster() throws IOException {
        return waitForActiveAndReadyMaster(Long.MAX_VALUE);
    }

    /**
     * Blocks until there is an active master and that master has completed
     * initialization.
     * 
     * @param timeout
     *          the timeout limit in ms
     * @return true if an active master becomes available. false if there are no
     *         masters left.
     */
    public abstract boolean waitForActiveAndReadyMaster(long timeout) throws IOException;

    /**
     * Wait for HBase Cluster to shut down.
     */
    public abstract void waitUntilShutDown() throws IOException;

    /**
     * Shut down the HBase cluster
     */
    public abstract void shutdown() throws IOException;

    /**
     * Restores the cluster to it's initial state if this is a real cluster,
     * otherwise does nothing.
     */
    public void restoreInitialStatus() throws IOException {
        restoreClusterStatus(getInitialClusterStatus());
    }

    /**
     * Restores the cluster to given state if this is a real cluster, otherwise
     * does nothing.
     */
    public void restoreClusterStatus(ClusterStatus desiredStatus) throws IOException {
    }

    /**
     * Get the ServerName of fServer serving the specified entityGroup
     * 
     * @param entityGroupName
     *          Name of the entityGroup in bytes
     * @return ServerName that hosts the entityGroup or null
     */
    public abstract ServerName getServerHoldingEntityGroup(byte[] entityGroupName) throws IOException;

    /**
     * @return whether we are interacting with a distributed cluster as opposed to
     *         an in-process mini/local cluster.
     */
    public boolean isDistributedCluster() {
        return false;
    }

    /**
     * Closes all the resources held open for this cluster. Note that this call
     * does not shutdown the cluster.
     * 
     * @see #shutdown()
     */
    @Override
    public abstract void close() throws IOException;
}