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 }