Package com.alibaba.wasp

Source Code of com.alibaba.wasp.MiniWaspCluster$MiniWaspClusterFServer

/**
* 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.client.FConnectionManager;
import com.alibaba.wasp.conf.WaspConfiguration;
import com.alibaba.wasp.fserver.AdminProtocol;
import com.alibaba.wasp.fserver.EntityGroup;
import com.alibaba.wasp.fserver.FServer;
import com.alibaba.wasp.master.FMaster;
import com.alibaba.wasp.master.FMasterAdminProtocol;
import com.alibaba.wasp.master.FMasterMonitorProtocol;
import com.alibaba.wasp.protobuf.generated.FServerStatusProtos.FServerStartupResponse;
import com.alibaba.wasp.util.JVMClusterUtil;
import junit.framework.TestCase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.Threads;

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

/**
* MiniWaspCluster for test unit. This class creates a single process Wasp
* cluster. each server. The master uses the 'default' HBase. The FServers, if
* we are running on HBase, create a HBase instance each and will close down
* their instance on the way out.
*/
public class MiniWaspCluster extends WaspCluster {
  static final Log LOG = LogFactory.getLog(MiniWaspCluster.class.getName());
  public LocalWaspCluster waspCluster;

  /**
   * Start a MiniWaspCluster.
   *
   * @param conf
   *          Configuration to be used for cluster
   * @param numFServers
   *          initial number of fservers to start.
   * @throws java.io.IOException
   */
  public MiniWaspCluster(Configuration conf, int numFServers)
      throws IOException, InterruptedException {
    this(conf, 1, numFServers);
  }

  /**
   * Start a MiniWaspCluster.
   *
   * @param conf
   *          Configuration to be used for cluster
   * @param numMasters
   *          initial number of masters to start.
   * @param numFServers
   *          initial number of entityGroup servers to start.
   * @throws java.io.IOException
   */
  public MiniWaspCluster(Configuration conf, int numMasters, int numFServers)
      throws IOException, InterruptedException {
    this(conf, numMasters, numFServers, null, null);
  }

  public MiniWaspCluster(Configuration conf, int numMasters, int numFServers,
      Class<? extends FMaster> masterClass,
      Class<? extends MiniWaspClusterFServer> fserverClass)
      throws IOException, InterruptedException {
    super(conf);
    conf.set(FConstants.MASTER_PORT, "0");
    init(numMasters, numFServers, masterClass, fserverClass);
    this.initialClusterStatus = getClusterStatus();
  }

  public Configuration getConfiguration() {
    return this.conf;
  }

  /**
   * Subclass so can get at protected methods (none at moment).
   */
  public static class MiniWaspClusterFServer extends FServer {
    public static boolean TEST_SKIP_CLOSE = false;

    public MiniWaspClusterFServer(Configuration conf) throws IOException,
        InterruptedException {
      super(conf);
    }

    /*
     * @param c
     *
     * @param currentfs We return this if we did not make a new one.
     *
     * @param uniqueName Same name used to help identify the created fs.
     *
     * @return A new fs instance if we are up on DistributeFileSystem.
     *
     * @throws IOException
     */

    @Override
    protected void handleReportForDutyResponse(final FServerStartupResponse c)
        throws IOException {
      super.handleReportForDutyResponse(c);
    }

    @Override
    public void run() {
      try {
        runFServer();
      } catch (Throwable t) {
        LOG.error("Exception in run", t);
      }
    }

    private void runFServer() {
      super.run();
    }

    @Override
    public void kill() {
      super.kill();
    }

    public void abort(final String reason, final Throwable cause) {
      abortFServer(reason, cause);
    }

    private void abortFServer(String reason, Throwable cause) {
      super.abort(reason, cause);
    }
  }

  private void init(final int nMasterNodes, final int nEntityGroupNodes,
      Class<? extends FMaster> masterClass,
      Class<? extends MiniWaspClusterFServer> fserverClass)
      throws IOException, InterruptedException {
    try {
      if (masterClass == null) {
        masterClass = FMaster.class;
      }
      if (fserverClass == null) {
        fserverClass = MiniWaspCluster.MiniWaspClusterFServer.class;
      }

      // start up a LocalWaspCluster
      waspCluster = new LocalWaspCluster(conf, nMasterNodes, 0, masterClass,
          fserverClass);

      // manually add the fservers as other users
      for (int i = 0; i < nEntityGroupNodes; i++) {
        Configuration rsConf = WaspConfiguration.create(conf);
        waspCluster.addFServer(rsConf, i);
      }

      waspCluster.startup();
    } catch (IOException e) {
      shutdown();
      throw e;
    } catch (Throwable t) {
      LOG.error("Error starting cluster", t);
      shutdown();
      throw new IOException("Shutting down", t);
    }
  }

  @Override
  public void startFServer(String hostname) throws IOException {
    this.startFServer();
  }

  @Override
  public void killFServer(ServerName serverName) throws IOException {
    FServer server = getFServer(getFServerIndex(serverName));
    if (server instanceof MiniWaspClusterFServer) {
      LOG.info("Killing " + server.toString());
      ((MiniWaspClusterFServer) server).kill();
    } else {
      abortFServer(getFServerIndex(serverName));
    }
  }

  @Override
  public void stopFServer(ServerName serverName) throws IOException {
    stopFServer(getFServerIndex(serverName));
  }

  @Override
  public void waitForFServerToStop(ServerName serverName, long timeout)
      throws IOException {
    // ignore timeout for now
    waitOnEntityGroupServer(getFServerIndex(serverName));
  }

  @Override
  public void startMaster(String hostname) throws IOException {
    this.startMaster();
  }

  @Override
  public void killMaster(ServerName serverName) throws IOException {
    abortMaster(getMasterIndex(serverName));
  }

  @Override
  public void stopMaster(ServerName serverName) throws IOException {
    stopMaster(getMasterIndex(serverName));
  }

  @Override
  public void waitForMasterToStop(ServerName serverName, long timeout)
      throws IOException {
    // ignore timeout for now
    waitOnMaster(getMasterIndex(serverName));
  }

  /**
   * Starts a entityGroup server thread running
   *
   * @throws java.io.IOException
   * @return New FServerThread
   */
  public JVMClusterUtil.FServerThread startFServer() throws IOException {
    final Configuration newConf = WaspConfiguration.create(conf);
    JVMClusterUtil.FServerThread t = null;

    t = waspCluster.addFServer(newConf, waspCluster.getFServers().size());
    t.start();
    t.waitForServerOnline();
    return t;
  }

  /**
   * Cause a entityGroup server to exit doing basic clean up only on its way
   * out.
   *
   * @param serverNumber
   *          Used as index into a list.
   */
  public String abortFServer(int serverNumber) {
    FServer server = getFServer(serverNumber);
    LOG.info("Aborting " + server.toString());
    server.abort("Aborting for tests", new Exception("Trace info"));
    return server.toString();
  }

  /**
   * Shut down the specified entityGroup server cleanly
   *
   * @param serverNumber
   *          Used as index into a list.
   * @return the entityGroups server that was stopped
   */
  public JVMClusterUtil.FServerThread stopFServer(int serverNumber) {
    JVMClusterUtil.FServerThread server = waspCluster.getFServers().get(
        serverNumber);
    LOG.info("Stopping " + server.toString());
    server.getFServer().stop("Stopping rs " + serverNumber);
    return server;
  }

  /**
   * Wait for the specified entityGroup server to stop. Removes this thread from
   * list of running threads.
   *
   * @param serverNumber
   * @return Name of entityGroup server that just went down.
   */
  public String waitOnEntityGroupServer(final int serverNumber) {
    return this.waspCluster.waitOnFServer(serverNumber);
  }

  /**
   * Starts a master thread running
   *
   * @throws java.io.IOException
   * @return New FServerThread
   */
  public JVMClusterUtil.MasterThread startMaster() throws IOException {
    Configuration c = WaspConfiguration.create(conf);

    JVMClusterUtil.MasterThread t = null;
    t = waspCluster.addMaster(c, waspCluster.getMasters().size());
    t.start();
    return t;
  }

  @Override
  public FMasterAdminProtocol getMasterAdmin() {
    return this.waspCluster.getActiveMaster();
  }

  @Override
  public FMasterMonitorProtocol getMasterMonitor() {
    return this.waspCluster.getActiveMaster();
  }

  /**
   * Returns the current active master, if available.
   *
   * @return the active HMaster, null if none is active.
   */
  public FMaster getMaster() {
    return this.waspCluster.getActiveMaster();
  }

  /**
   * Returns the master at the specified index, if available.
   *
   * @return the active HMaster, null if none is active.
   */
  public FMaster getMaster(final int serverNumber) {
    return this.waspCluster.getMaster(serverNumber);
  }

  /**
   * Cause a master to exit without shutting down entire cluster.
   *
   * @param serverNumber
   *          Used as index into a list.
   */
  public String abortMaster(int serverNumber) {
    FMaster server = getMaster(serverNumber);
    LOG.info("Aborting " + server.toString());
    server.abort("Aborting for tests", new Exception("Trace info"));
    return server.toString();
  }

  /**
   * Shut down the specified master cleanly
   *
   * @param serverNumber
   *          Used as index into a list.
   * @return the entityGroup server that was stopped
   */
  public JVMClusterUtil.MasterThread stopMaster(int serverNumber) {
    return stopMaster(serverNumber, true);
  }

  /**
   * Shut down the specified master cleanly
   *
   * @param serverNumber
   *          Used as index into a list.
   * @param shutdownFS
   *          True is we are to shutdown the filesystem as part of this master's
   *          shutdown. Usually we do but you do not want to do this if you are
   *          running multiple master in a test and you shut down one before end
   *          of the test.
   * @return the master that was stopped
   */
  public JVMClusterUtil.MasterThread stopMaster(int serverNumber,
      final boolean shutdownFS) {
    JVMClusterUtil.MasterThread server = waspCluster.getMasters().get(
        serverNumber);
    LOG.info("Stopping " + server.toString());
    server.getMaster().stop("Stopping master " + serverNumber);
    return server;
  }

  /**
   * Wait for the specified master to stop. Removes this thread from list of
   * running threads.
   *
   * @param serverNumber
   * @return Name of master that just went down.
   */
  public String waitOnMaster(final int serverNumber) {
    return this.waspCluster.waitOnMaster(serverNumber);
  }

  /**
   * 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 InterruptedException
   */
  public boolean waitForActiveAndReadyMaster(long timeout) throws IOException {
    List<JVMClusterUtil.MasterThread> mts;
    long start = System.currentTimeMillis();
    while (!(mts = getMasterThreads()).isEmpty()
        && (System.currentTimeMillis() - start) < timeout) {
      for (JVMClusterUtil.MasterThread mt : mts) {
        if (mt.getMaster().isActiveMaster() && mt.getMaster().isInitialized()) {
          return true;
        }
      }

      Threads.sleep(100);
    }
    return false;
  }

  /**
   * @return List of master threads.
   */
  public List<JVMClusterUtil.MasterThread> getMasterThreads() {
    return this.waspCluster.getMasters();
  }

  /**
   * @return List of live master threads (skips the aborted and the killed)
   */
  public List<JVMClusterUtil.MasterThread> getLiveMasterThreads() {
    return this.waspCluster.getLiveMasters();
  }

  /**
   * Wait for Mini HBase Cluster to shut down.
   */
  public void join() {
    this.waspCluster.join();
  }

  /**
   * Shut down the mini HBase cluster
   *
   * @throws java.io.IOException
   */
  public void shutdown() throws IOException {
    if (this.waspCluster != null) {
      this.waspCluster.shutdown();
    }
    FConnectionManager.deleteAllConnections(false);
  }

  @Override
  public void close() throws IOException {
  }

  @Override
  public ClusterStatus getClusterStatus() throws IOException {
    FMaster master = getMaster();
    return master == null ? null : master.getClusterStatus();
  }

  /**
   * @return List of entityGroup server threads.
   */
  public List<JVMClusterUtil.FServerThread> getFServerThreads() {
    return this.waspCluster.getFServers();
  }

  /**
   * @return List of live entityGroup server threads (skips the aborted and the
   *         killed)
   */
  public List<JVMClusterUtil.FServerThread> getLiveFServerThreads() {
    return this.waspCluster.getLiveFServers();
  }

  /**
   * Grab a numbered entityGroup server of your choice.
   *
   * @param serverNumber
   * @return entityGroup server
   */
  public FServer getFServer(int serverNumber) {
    return waspCluster.getFServer(serverNumber);
  }

  public List<EntityGroup> getEntityGroups(byte[] tableName) {
    List<EntityGroup> ret = new ArrayList<EntityGroup>();
    for (JVMClusterUtil.FServerThread rst : getFServerThreads()) {
      FServer fs = rst.getFServer();
      Collection<EntityGroup> egs = fs.getOnlineEntityGroupsLocalContext();
      for (EntityGroup entityGroup : egs) {
        TestCase.assertNotNull(entityGroup);
        TestCase.assertNotNull(entityGroup.getTableDesc());
        TestCase.assertNotNull(entityGroup.getTableDesc().getTableName());
        TestCase.assertNotNull(tableName);
        if (Bytes
            .equals(Bytes.toBytes(entityGroup.getTableDesc().getTableName()),
                tableName)) {
          ret.add(entityGroup);
        }
      }
    }
    return ret;
  }

  /**
   * Get the location of the specified entityGroup
   *
   * @param entityGroupName
   *          Name of the entityGroup in bytes
   * @return Index into List of {@link MiniWaspCluster#getFServerThreads()} of
   *         HRS carrying .META.. Returns -1 if none found.
   */
  public int getServerWith(byte[] entityGroupName) {
    int index = -1;
    int count = 0;
    for (JVMClusterUtil.FServerThread rst : getFServerThreads()) {
      FServer hrs = rst.getFServer();
      EntityGroup entityGroup = hrs.getOnlineEntityGroup(entityGroupName);
      if (entityGroup != null) {
        index = count;
        break;
      }
      count++;
    }
    return index;
  }

  @Override
  public ServerName getServerHoldingEntityGroup(byte[] entityGroupName)
      throws IOException {
    int index = getServerWith(entityGroupName);
    if (index < 0) {
      return null;
    }
    return getFServer(index).getServerName();
  }

  /**
   * Counts the total numbers of entityGroups being served by the currently
   * online entityGroup servers by asking each how many entityGroups they have.
   * Does not look at META at all. Count includes catalog tables.
   *
   * @return number of entityGroups being served by all entityGroup servers
   */
  public long countServedEntityGroups() {
    long count = 0;
    for (JVMClusterUtil.FServerThread rst : getLiveFServerThreads()) {
      count += rst.getFServer().getNumberOfOnlineEntityGroups();
    }
    return count;
  }

  /**
   * Do a simulated kill all masters and entityGroups servers. Useful when it is
   * impossible to bring the mini-cluster back for clean shutdown.
   */
  public void killAll() {
    for (JVMClusterUtil.FServerThread rst : getFServerThreads()) {
      rst.getFServer().abort("killAll");
    }
    for (JVMClusterUtil.MasterThread masterThread : getMasterThreads()) {
      masterThread.getMaster().abort("killAll", new Throwable());
    }
  }

  @Override
  public void waitUntilShutDown() {
    this.waspCluster.join();
  }

  protected int getFServerIndex(ServerName serverName) {
    // we have a small number of entityGroup servers, this should be fine for
    // now.
    List<JVMClusterUtil.FServerThread> servers = getFServerThreads();
    for (int i = 0; i < servers.size(); i++) {
      if (servers.get(i).getFServer().getServerName().equals(serverName)) {
        return i;
      }
    }
    return -1;
  }

  protected int getMasterIndex(ServerName serverName) {
    List<JVMClusterUtil.MasterThread> masters = getMasterThreads();
    for (int i = 0; i < masters.size(); i++) {
      if (masters.get(i).getMaster().getServerName().equals(serverName)) {
        return i;
      }
    }
    return -1;
  }

  @Override
  public AdminProtocol getAdminProtocol(ServerName serverName)
      throws IOException {
    return getFServer(getFServerIndex(serverName));
  }

  @Override
  public ClientProtocol getClientProtocol(ServerName serverName)
      throws IOException {
    return getFServer(getFServerIndex(serverName));
  }
}
TOP

Related Classes of com.alibaba.wasp.MiniWaspCluster$MiniWaspClusterFServer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.