Java tutorial
/** * 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; }