1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase;
21
22 import java.io.IOException;
23 import java.security.PrivilegedAction;
24 import java.util.ArrayList;
25 import java.util.List;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.hadoop.conf.Configuration;
30 import org.apache.hadoop.fs.FileSystem;
31 import org.apache.hadoop.hbase.client.HConnectionManager;
32 import org.apache.hadoop.hbase.master.HMaster;
33 import org.apache.hadoop.hbase.regionserver.HRegion;
34 import org.apache.hadoop.hbase.regionserver.HRegionServer;
35 import org.apache.hadoop.hbase.security.User;
36 import org.apache.hadoop.hbase.util.Bytes;
37 import org.apache.hadoop.hbase.util.JVMClusterUtil;
38 import org.apache.hadoop.hbase.util.Threads;
39 import org.apache.hadoop.io.MapWritable;
40
41
42
43
44
45
46
47 public class MiniHBaseCluster {
48 static final Log LOG = LogFactory.getLog(MiniHBaseCluster.class.getName());
49 private Configuration conf;
50 public LocalHBaseCluster hbaseCluster;
51 private static int index;
52
53
54
55
56
57
58
59 public MiniHBaseCluster(Configuration conf, int numRegionServers)
60 throws IOException, InterruptedException {
61 this(conf, 1, numRegionServers);
62 }
63
64
65
66
67
68
69
70
71 public MiniHBaseCluster(Configuration conf, int numMasters,
72 int numRegionServers)
73 throws IOException, InterruptedException {
74 this.conf = conf;
75 conf.set(HConstants.MASTER_PORT, "0");
76 init(numMasters, numRegionServers);
77 }
78
79 public Configuration getConfiguration() {
80 return this.conf;
81 }
82
83
84
85
86
87
88
89 public static class MiniHBaseClusterRegionServer extends HRegionServer {
90 private Thread shutdownThread = null;
91 private User user = null;
92 public static boolean TEST_SKIP_CLOSE = false;
93
94 public MiniHBaseClusterRegionServer(Configuration conf)
95 throws IOException, InterruptedException {
96 super(conf);
97 this.user = User.getCurrent();
98 }
99
100
101
102
103
104
105
106
107
108 @Override
109 protected void handleReportForDutyResponse(MapWritable c) throws IOException {
110 super.handleReportForDutyResponse(c);
111
112 this.shutdownThread = new SingleFileSystemShutdownThread(getFileSystem());
113 }
114
115 @Override
116 public void run() {
117 try {
118 this.user.runAs(new PrivilegedAction<Object>(){
119 public Object run() {
120 runRegionServer();
121 return null;
122 }
123 });
124 } catch (Throwable t) {
125 LOG.error("Exception in run", t);
126 } finally {
127
128 if (this.shutdownThread != null) {
129 this.shutdownThread.start();
130 Threads.shutdown(this.shutdownThread, 30000);
131 }
132 }
133 }
134
135 private void runRegionServer() {
136 super.run();
137 }
138
139 @Override
140 public void kill() {
141 super.kill();
142 }
143
144 public void abort(final String reason, final Throwable cause) {
145 this.user.runAs(new PrivilegedAction<Object>() {
146 public Object run() {
147 abortRegionServer(reason, cause);
148 return null;
149 }
150 });
151 }
152
153 private void abortRegionServer(String reason, Throwable cause) {
154 super.abort(reason, cause);
155 }
156 }
157
158
159
160
161
162 static class SingleFileSystemShutdownThread extends Thread {
163 private final FileSystem fs;
164 SingleFileSystemShutdownThread(final FileSystem fs) {
165 super("Shutdown of " + fs);
166 this.fs = fs;
167 }
168 @Override
169 public void run() {
170 try {
171 LOG.info("Hook closing fs=" + this.fs);
172 this.fs.close();
173 } catch (NullPointerException npe) {
174 LOG.debug("Need to fix these: " + npe.toString());
175 } catch (IOException e) {
176 LOG.warn("Running hook", e);
177 }
178 }
179 }
180
181 private void init(final int nMasterNodes, final int nRegionNodes)
182 throws IOException, InterruptedException {
183 try {
184
185 hbaseCluster = new LocalHBaseCluster(conf, nMasterNodes, 0,
186 HMaster.class, MiniHBaseCluster.MiniHBaseClusterRegionServer.class);
187
188
189 for (int i=0; i<nRegionNodes; i++) {
190 Configuration rsConf = HBaseConfiguration.create(conf);
191 User user = HBaseTestingUtility.getDifferentUser(rsConf,
192 ".hfs."+index++);
193 hbaseCluster.addRegionServer(rsConf, i, user);
194 }
195
196 hbaseCluster.startup();
197 } catch (IOException e) {
198 shutdown();
199 throw e;
200 } catch (Throwable t) {
201 LOG.error("Error starting cluster", t);
202 shutdown();
203 throw new IOException("Shutting down", t);
204 }
205 }
206
207
208
209
210
211
212
213 public JVMClusterUtil.RegionServerThread startRegionServer()
214 throws IOException {
215 final Configuration newConf = HBaseConfiguration.create(conf);
216 User rsUser =
217 HBaseTestingUtility.getDifferentUser(newConf, ".hfs."+index++);
218 JVMClusterUtil.RegionServerThread t = null;
219 try {
220 t = hbaseCluster.addRegionServer(
221 newConf, hbaseCluster.getRegionServers().size(), rsUser);
222 t.start();
223 t.waitForServerOnline();
224 } catch (InterruptedException ie) {
225 throw new IOException("Interrupted adding regionserver to cluster", ie);
226 }
227 return t;
228 }
229
230
231
232
233
234 public String abortRegionServer(int serverNumber) {
235 HRegionServer server = getRegionServer(serverNumber);
236 LOG.info("Aborting " + server.toString());
237 server.abort("Aborting for tests", new Exception("Trace info"));
238 return server.toString();
239 }
240
241
242
243
244
245
246
247 public JVMClusterUtil.RegionServerThread stopRegionServer(int serverNumber) {
248 return stopRegionServer(serverNumber, true);
249 }
250
251
252
253
254
255
256
257
258
259
260
261 public JVMClusterUtil.RegionServerThread stopRegionServer(int serverNumber,
262 final boolean shutdownFS) {
263 JVMClusterUtil.RegionServerThread server =
264 hbaseCluster.getRegionServers().get(serverNumber);
265 LOG.info("Stopping " + server.toString());
266 server.getRegionServer().stop("Stopping rs " + serverNumber);
267 return server;
268 }
269
270
271
272
273
274
275
276 public String waitOnRegionServer(final int serverNumber) {
277 return this.hbaseCluster.waitOnRegionServer(serverNumber);
278 }
279
280
281
282
283
284
285
286
287 public JVMClusterUtil.MasterThread startMaster() throws IOException {
288 Configuration c = HBaseConfiguration.create(conf);
289 User user =
290 HBaseTestingUtility.getDifferentUser(c, ".hfs."+index++);
291
292 JVMClusterUtil.MasterThread t = null;
293 try {
294 t = hbaseCluster.addMaster(c, hbaseCluster.getMasters().size(), user);
295 t.start();
296 t.waitForServerOnline();
297 } catch (InterruptedException ie) {
298 throw new IOException("Interrupted adding master to cluster", ie);
299 }
300 return t;
301 }
302
303
304
305
306
307 public HMaster getMaster() {
308 return this.hbaseCluster.getActiveMaster();
309 }
310
311
312
313
314
315 public HMaster getMaster(final int serverNumber) {
316 return this.hbaseCluster.getMaster(serverNumber);
317 }
318
319
320
321
322
323 public String abortMaster(int serverNumber) {
324 HMaster server = getMaster(serverNumber);
325 LOG.info("Aborting " + server.toString());
326 server.abort("Aborting for tests", new Exception("Trace info"));
327 return server.toString();
328 }
329
330
331
332
333
334
335
336 public JVMClusterUtil.MasterThread stopMaster(int serverNumber) {
337 return stopMaster(serverNumber, true);
338 }
339
340
341
342
343
344
345
346
347
348
349
350 public JVMClusterUtil.MasterThread stopMaster(int serverNumber,
351 final boolean shutdownFS) {
352 JVMClusterUtil.MasterThread server =
353 hbaseCluster.getMasters().get(serverNumber);
354 LOG.info("Stopping " + server.toString());
355 server.getMaster().stop("Stopping master " + serverNumber);
356 return server;
357 }
358
359
360
361
362
363
364
365 public String waitOnMaster(final int serverNumber) {
366 return this.hbaseCluster.waitOnMaster(serverNumber);
367 }
368
369
370
371
372
373
374
375
376
377 public boolean waitForActiveAndReadyMaster() throws InterruptedException {
378 List<JVMClusterUtil.MasterThread> mts;
379 while (!(mts = getMasterThreads()).isEmpty()) {
380 for (JVMClusterUtil.MasterThread mt : mts) {
381 if (mt.getMaster().isActiveMaster() && mt.getMaster().isInitialized()) {
382 return true;
383 }
384 }
385 Thread.sleep(200);
386 }
387 return false;
388 }
389
390
391
392
393 public List<JVMClusterUtil.MasterThread> getMasterThreads() {
394 return this.hbaseCluster.getMasters();
395 }
396
397
398
399
400 public List<JVMClusterUtil.MasterThread> getLiveMasterThreads() {
401 return this.hbaseCluster.getLiveMasters();
402 }
403
404
405
406
407 public void join() {
408 this.hbaseCluster.join();
409 }
410
411
412
413
414
415 public void shutdown() throws IOException {
416 if (this.hbaseCluster != null) {
417 this.hbaseCluster.shutdown();
418 }
419 HConnectionManager.deleteAllConnections(false);
420 }
421
422
423
424
425
426 public void flushcache() throws IOException {
427 for (JVMClusterUtil.RegionServerThread t:
428 this.hbaseCluster.getRegionServers()) {
429 for(HRegion r: t.getRegionServer().getOnlineRegionsLocalContext()) {
430 r.flushcache();
431 }
432 }
433 }
434
435
436
437
438
439 public void flushcache(byte [] tableName) throws IOException {
440 for (JVMClusterUtil.RegionServerThread t:
441 this.hbaseCluster.getRegionServers()) {
442 for(HRegion r: t.getRegionServer().getOnlineRegionsLocalContext()) {
443 if(Bytes.equals(r.getTableDesc().getName(), tableName)) {
444 r.flushcache();
445 }
446 }
447 }
448 }
449
450
451
452
453 public List<JVMClusterUtil.RegionServerThread> getRegionServerThreads() {
454 return this.hbaseCluster.getRegionServers();
455 }
456
457
458
459
460 public List<JVMClusterUtil.RegionServerThread> getLiveRegionServerThreads() {
461 return this.hbaseCluster.getLiveRegionServers();
462 }
463
464
465
466
467
468
469 public HRegionServer getRegionServer(int serverNumber) {
470 return hbaseCluster.getRegionServer(serverNumber);
471 }
472
473 public List<HRegion> getRegions(byte[] tableName) {
474 List<HRegion> ret = new ArrayList<HRegion>();
475 for (JVMClusterUtil.RegionServerThread rst : getRegionServerThreads()) {
476 HRegionServer hrs = rst.getRegionServer();
477 for (HRegion region : hrs.getOnlineRegionsLocalContext()) {
478 if (Bytes.equals(region.getTableDesc().getName(), tableName)) {
479 ret.add(region);
480 }
481 }
482 }
483 return ret;
484 }
485
486
487
488
489
490 public int getServerWithMeta() {
491 return getServerWith(HRegionInfo.FIRST_META_REGIONINFO.getRegionName());
492 }
493
494
495
496
497
498
499
500 public int getServerWith(byte[] regionName) {
501 int index = -1;
502 int count = 0;
503 for (JVMClusterUtil.RegionServerThread rst: getRegionServerThreads()) {
504 HRegionServer hrs = rst.getRegionServer();
505 HRegion metaRegion =
506 hrs.getOnlineRegion(regionName);
507 if (metaRegion != null) {
508 index = count;
509 break;
510 }
511 count++;
512 }
513 return index;
514 }
515
516
517
518
519
520
521
522 public long countServedRegions() {
523 long count = 0;
524 for (JVMClusterUtil.RegionServerThread rst : getLiveRegionServerThreads()) {
525 count += rst.getRegionServer().getNumberOfOnlineRegions();
526 }
527 return count;
528 }
529 }