View Javadoc

1   /**
2    * Copyright 2010 The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  package org.apache.hadoop.hbase.util;
21  
22  import java.io.IOException;
23  import java.util.List;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  import org.apache.hadoop.conf.Configuration;
28  import org.apache.hadoop.hbase.master.HMaster;
29  import org.apache.hadoop.hbase.regionserver.HRegionServer;
30  
31  /**
32   * Utility used running a cluster all in the one JVM.
33   */
34  public class JVMClusterUtil {
35    private static final Log LOG = LogFactory.getLog(JVMClusterUtil.class);
36  
37    /**
38     * Datastructure to hold RegionServer Thread and RegionServer instance
39     */
40    public static class RegionServerThread extends Thread {
41      private final HRegionServer regionServer;
42  
43      public RegionServerThread(final HRegionServer r, final int index) {
44        super(r, "RegionServer:" + index);
45        this.regionServer = r;
46      }
47  
48      /** @return the region server */
49      public HRegionServer getRegionServer() {
50        return this.regionServer;
51      }
52  
53      /**
54       * Block until the region server has come online, indicating it is ready
55       * to be used.
56       */
57      public void waitForServerOnline() {
58        // The server is marked online after the init method completes inside of
59        // the HRS#run method.  HRS#init can fail for whatever region.  In those
60        // cases, we'll jump out of the run without setting online flag.  Check
61        // stopRequested so we don't wait here a flag that will never be flipped.
62        while (!this.regionServer.isOnline() &&
63            !this.regionServer.isStopRequested()) {
64          try {
65            Thread.sleep(1000);
66          } catch (InterruptedException e) {
67            // continue waiting
68          }
69        }
70      }
71    }
72  
73    /**
74     * Creates a {@link RegionServerThread}.
75     * Call 'start' on the returned thread to make it run.
76     * @param c Configuration to use.
77     * @param hrsc Class to create.
78     * @param index Used distingushing the object returned.
79     * @throws IOException
80     * @return Region server added.
81     */
82    public static JVMClusterUtil.RegionServerThread createRegionServerThread(final Configuration c,
83      final Class<? extends HRegionServer> hrsc, final int index)
84    throws IOException {
85        HRegionServer server;
86        try {
87          server = hrsc.getConstructor(Configuration.class).newInstance(c);
88        } catch (Exception e) {
89          IOException ioe = new IOException();
90          ioe.initCause(e);
91          throw ioe;
92        }
93        return new JVMClusterUtil.RegionServerThread(server, index);
94    }
95  
96    /**
97     * Start the cluster.
98     * @param m
99     * @param regionServers
100    * @return Address to use contacting master.
101    */
102   public static String startup(final HMaster m,
103       final List<JVMClusterUtil.RegionServerThread> regionservers) {
104     if (m != null) m.start();
105     if (regionservers != null) {
106       for (JVMClusterUtil.RegionServerThread t: regionservers) {
107         t.start();
108       }
109     }
110     return m == null? null: m.getMasterAddress().toString();
111   }
112 
113   /**
114    * @param master
115    * @param regionservers
116    */
117   public static void shutdown(final HMaster master,
118       final List<RegionServerThread> regionservers) {
119     LOG.debug("Shutting down HBase Cluster");
120     if (master != null) {
121       master.shutdown();
122     }
123     // regionServerThreads can never be null because they are initialized when
124     // the class is constructed.
125       for(Thread t: regionservers) {
126         if (t.isAlive()) {
127           try {
128             t.join();
129           } catch (InterruptedException e) {
130             // continue
131           }
132         }
133       }
134     if (master != null) {
135       while (master.isAlive()) {
136         try {
137           // The below has been replaced to debug sometime hangs on end of
138           // tests.
139           // this.master.join():
140           Threads.threadDumpingIsAlive(master);
141         } catch(InterruptedException e) {
142           // continue
143         }
144       }
145     }
146     LOG.info("Shutdown " +
147       ((regionservers != null)? master.getName(): "0 masters") +
148       " " + regionservers.size() + " region server(s)");
149   }
150 }