1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.client;
20
21 import com.google.common.annotations.VisibleForTesting;
22 import com.google.protobuf.ByteString;
23 import com.google.protobuf.ServiceException;
24
25 import java.io.IOException;
26 import java.io.InterruptedIOException;
27 import java.util.ArrayList;
28 import java.util.Arrays;
29 import java.util.HashMap;
30 import java.util.LinkedList;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.Map.Entry;
34 import java.util.concurrent.ExecutionException;
35 import java.util.concurrent.Future;
36 import java.util.concurrent.TimeUnit;
37 import java.util.concurrent.TimeoutException;
38 import java.util.concurrent.atomic.AtomicInteger;
39 import java.util.concurrent.atomic.AtomicReference;
40 import java.util.regex.Pattern;
41
42 import org.apache.commons.logging.Log;
43 import org.apache.commons.logging.LogFactory;
44 import org.apache.hadoop.conf.Configuration;
45 import org.apache.hadoop.hbase.Abortable;
46 import org.apache.hadoop.hbase.ClusterStatus;
47 import org.apache.hadoop.hbase.DoNotRetryIOException;
48 import org.apache.hadoop.hbase.HBaseConfiguration;
49 import org.apache.hadoop.hbase.HColumnDescriptor;
50 import org.apache.hadoop.hbase.HConstants;
51 import org.apache.hadoop.hbase.HRegionInfo;
52 import org.apache.hadoop.hbase.HRegionLocation;
53 import org.apache.hadoop.hbase.HTableDescriptor;
54 import org.apache.hadoop.hbase.MasterNotRunningException;
55 import org.apache.hadoop.hbase.MetaTableAccessor;
56 import org.apache.hadoop.hbase.NamespaceDescriptor;
57 import org.apache.hadoop.hbase.NamespaceNotFoundException;
58 import org.apache.hadoop.hbase.NotServingRegionException;
59 import org.apache.hadoop.hbase.ProcedureInfo;
60 import org.apache.hadoop.hbase.RegionLocations;
61 import org.apache.hadoop.hbase.ServerName;
62 import org.apache.hadoop.hbase.TableExistsException;
63 import org.apache.hadoop.hbase.TableName;
64 import org.apache.hadoop.hbase.TableNotDisabledException;
65 import org.apache.hadoop.hbase.TableNotFoundException;
66 import org.apache.hadoop.hbase.UnknownRegionException;
67 import org.apache.hadoop.hbase.ZooKeeperConnectionException;
68 import org.apache.hadoop.hbase.classification.InterfaceAudience;
69 import org.apache.hadoop.hbase.classification.InterfaceStability;
70 import org.apache.hadoop.hbase.client.MetaScanner.MetaScannerVisitor;
71 import org.apache.hadoop.hbase.client.MetaScanner.MetaScannerVisitorBase;
72 import org.apache.hadoop.hbase.client.security.SecurityCapability;
73 import org.apache.hadoop.hbase.exceptions.DeserializationException;
74 import org.apache.hadoop.hbase.exceptions.TimeoutIOException;
75 import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel;
76 import org.apache.hadoop.hbase.ipc.HBaseRpcController;
77 import org.apache.hadoop.hbase.ipc.MasterCoprocessorRpcChannel;
78 import org.apache.hadoop.hbase.ipc.RegionServerCoprocessorRpcChannel;
79 import org.apache.hadoop.hbase.ipc.RpcControllerFactory;
80 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
81 import org.apache.hadoop.hbase.protobuf.RequestConverter;
82 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.AdminService;
83 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.CloseRegionRequest;
84 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.CloseRegionResponse;
85 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.CompactRegionRequest;
86 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.FlushRegionRequest;
87 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetRegionInfoRequest;
88 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetRegionInfoResponse;
89 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetRegionInfoResponse.CompactionState;
90 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.RollWALWriterRequest;
91 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.RollWALWriterResponse;
92 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.StopServerRequest;
93 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.UpdateConfigurationRequest;
94 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos;
95 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.NameStringPair;
96 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.ProcedureDescription;
97 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.RegionSpecifier.RegionSpecifierType;
98 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
99 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchema;
100 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos;
101 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.AbortProcedureRequest;
102 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.AbortProcedureResponse;
103 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.AddColumnRequest;
104 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.AssignRegionRequest;
105 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ClearDeadServersRequest;
106 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.CreateNamespaceRequest;
107 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.CreateTableRequest;
108 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.CreateTableResponse;
109 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DeleteColumnRequest;
110 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DeleteNamespaceRequest;
111 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DeleteSnapshotRequest;
112 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DeleteTableRequest;
113 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DeleteTableResponse;
114 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DisableTableRequest;
115 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DisableTableResponse;
116 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DispatchMergingRegionsRequest;
117 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.EnableTableRequest;
118 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.EnableTableResponse;
119 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ExecProcedureRequest;
120 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ExecProcedureResponse;
121 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetClusterStatusRequest;
122 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetCompletedSnapshotsRequest;
123 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetNamespaceDescriptorRequest;
124 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetProcedureResultRequest;
125 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetProcedureResultResponse;
126 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetSchemaAlterStatusRequest;
127 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetSchemaAlterStatusResponse;
128 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableDescriptorsRequest;
129 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableDescriptorsResponse;
130 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableNamesRequest;
131 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsInMaintenanceModeRequest;
132 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsInMaintenanceModeResponse;
133 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsProcedureDoneRequest;
134 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsProcedureDoneResponse;
135 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsRestoreSnapshotDoneRequest;
136 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsRestoreSnapshotDoneResponse;
137 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsSnapshotDoneRequest;
138 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsSnapshotDoneResponse;
139 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ListNamespaceDescriptorsRequest;
140 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ListProceduresRequest;
141 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ListTableDescriptorsByNamespaceRequest;
142 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ListTableNamesByNamespaceRequest;
143 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.MajorCompactionTimestampForRegionRequest;
144 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.MajorCompactionTimestampRequest;
145 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ModifyColumnRequest;
146 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ModifyNamespaceRequest;
147 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ModifyTableRequest;
148 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.MoveRegionRequest;
149 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RestoreSnapshotRequest;
150 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RestoreSnapshotResponse;
151 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SecurityCapabilitiesRequest;
152 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetBalancerRunningRequest;
153 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetNormalizerRunningRequest;
154 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ShutdownRequest;
155 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SnapshotRequest;
156 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SnapshotResponse;
157 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.StopMasterRequest;
158 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.TruncateTableRequest;
159 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.UnassignRegionRequest;
160 import org.apache.hadoop.hbase.protobuf.generated.ProcedureProtos;
161 import org.apache.hadoop.hbase.protobuf.generated.TableProtos;
162 import org.apache.hadoop.hbase.quotas.QuotaFilter;
163 import org.apache.hadoop.hbase.quotas.QuotaRetriever;
164 import org.apache.hadoop.hbase.quotas.QuotaSettings;
165 import org.apache.hadoop.hbase.regionserver.wal.FailedLogCloseException;
166 import org.apache.hadoop.hbase.snapshot.ClientSnapshotDescriptionUtils;
167 import org.apache.hadoop.hbase.snapshot.HBaseSnapshotException;
168 import org.apache.hadoop.hbase.snapshot.RestoreSnapshotException;
169 import org.apache.hadoop.hbase.snapshot.SnapshotCreationException;
170 import org.apache.hadoop.hbase.snapshot.UnknownSnapshotException;
171 import org.apache.hadoop.hbase.util.Addressing;
172 import org.apache.hadoop.hbase.util.Bytes;
173 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
174 import org.apache.hadoop.hbase.util.ForeignExceptionUtil;
175 import org.apache.hadoop.hbase.util.Pair;
176 import org.apache.hadoop.hbase.zookeeper.MasterAddressTracker;
177 import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
178 import org.apache.hadoop.ipc.RemoteException;
179 import org.apache.hadoop.util.StringUtils;
180 import org.apache.zookeeper.KeeperException;
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198 @InterfaceAudience.Private
199 @InterfaceStability.Evolving
200 public class HBaseAdmin implements Admin {
201 private static final Log LOG = LogFactory.getLog(HBaseAdmin.class);
202
203 private static final String ZK_IDENTIFIER_PREFIX = "hbase-admin-on-";
204
205 private ClusterConnection connection;
206
207 private volatile Configuration conf;
208 private final long pause;
209 private final int numRetries;
210
211
212
213 private final int retryLongerMultiplier;
214 private final int syncWaitTimeout;
215 private boolean aborted;
216 private boolean cleanupConnectionOnClose = false;
217 private boolean closed = false;
218 private int operationTimeout;
219 private int rpcTimeout;
220
221 private RpcRetryingCallerFactory rpcCallerFactory;
222 private RpcControllerFactory rpcControllerFactory;
223
224 private NonceGenerator ng;
225
226
227
228
229
230
231
232
233
234 @Deprecated
235 public HBaseAdmin(Configuration c)
236 throws MasterNotRunningException, ZooKeeperConnectionException, IOException {
237
238
239 this(ConnectionManager.getConnectionInternal(new Configuration(c)));
240 this.cleanupConnectionOnClose = true;
241 }
242
243 @Override
244 public int getOperationTimeout() {
245 return operationTimeout;
246 }
247
248
249
250
251
252
253
254
255
256
257
258
259
260 @Deprecated
261 public HBaseAdmin(Connection connection)
262 throws MasterNotRunningException, ZooKeeperConnectionException {
263 this((ClusterConnection)connection);
264 }
265
266 HBaseAdmin(ClusterConnection connection) {
267 this.conf = connection.getConfiguration();
268 this.connection = connection;
269
270
271 this.pause = this.conf.getLong(HConstants.HBASE_CLIENT_PAUSE,
272 HConstants.DEFAULT_HBASE_CLIENT_PAUSE);
273 this.numRetries = this.conf.getInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER,
274 HConstants.DEFAULT_HBASE_CLIENT_RETRIES_NUMBER);
275 this.retryLongerMultiplier = this.conf.getInt(
276 "hbase.client.retries.longer.multiplier", 10);
277 this.operationTimeout = this.conf.getInt(HConstants.HBASE_CLIENT_OPERATION_TIMEOUT,
278 HConstants.DEFAULT_HBASE_CLIENT_OPERATION_TIMEOUT);
279 this.rpcTimeout = this.conf.getInt(HConstants.HBASE_RPC_TIMEOUT_KEY,
280 HConstants.DEFAULT_HBASE_RPC_TIMEOUT);
281 this.syncWaitTimeout = this.conf.getInt(
282 "hbase.client.sync.wait.timeout.msec", 10 * 60000);
283
284 this.rpcCallerFactory = connection.getRpcRetryingCallerFactory();
285 this.rpcControllerFactory = connection.getRpcControllerFactory();
286
287 this.ng = this.connection.getNonceGenerator();
288 }
289
290 @Override
291 public void abort(String why, Throwable e) {
292
293 this.aborted = true;
294 throw new RuntimeException(why, e);
295 }
296
297 @Override
298 public boolean isAborted(){
299 return this.aborted;
300 }
301
302
303
304
305
306
307
308
309 @Override
310 public boolean abortProcedure(
311 final long procId,
312 final boolean mayInterruptIfRunning) throws IOException {
313 Future<Boolean> future = abortProcedureAsync(procId, mayInterruptIfRunning);
314 try {
315 return future.get(syncWaitTimeout, TimeUnit.MILLISECONDS);
316 } catch (InterruptedException e) {
317 throw new InterruptedIOException("Interrupted when waiting for procedure to be cancelled");
318 } catch (TimeoutException e) {
319 throw new TimeoutIOException(e);
320 } catch (ExecutionException e) {
321 if (e.getCause() instanceof IOException) {
322 throw (IOException)e.getCause();
323 } else {
324 throw new IOException(e.getCause());
325 }
326 }
327 }
328
329
330
331
332
333
334
335
336
337
338
339
340
341 @Override
342 public Future<Boolean> abortProcedureAsync(
343 final long procId,
344 final boolean mayInterruptIfRunning) throws IOException {
345 Boolean abortProcResponse = executeCallable(
346 new MasterCallable<AbortProcedureResponse>(getConnection()) {
347 @Override
348 public AbortProcedureResponse call(int callTimeout) throws ServiceException {
349 HBaseRpcController controller = rpcControllerFactory.newController();
350 controller.setCallTimeout(callTimeout);
351 AbortProcedureRequest abortProcRequest =
352 AbortProcedureRequest.newBuilder().setProcId(procId).build();
353 return master.abortProcedure(controller, abortProcRequest);
354 }
355 }).getIsProcedureAborted();
356
357 AbortProcedureFuture abortProcFuture =
358 new AbortProcedureFuture(this, procId, abortProcResponse);
359 return abortProcFuture;
360 }
361
362 private static class AbortProcedureFuture extends ProcedureFuture<Boolean> {
363 private boolean isAbortInProgress;
364
365 public AbortProcedureFuture(
366 final HBaseAdmin admin,
367 final Long procId,
368 final Boolean abortProcResponse) {
369 super(admin, procId);
370 this.isAbortInProgress = abortProcResponse;
371 }
372
373 @Override
374 public Boolean get(long timeout, TimeUnit unit)
375 throws InterruptedException, ExecutionException, TimeoutException {
376 if (!this.isAbortInProgress) {
377 return false;
378 }
379 super.get(timeout, unit);
380 return true;
381 }
382 }
383
384
385 @Override
386 public HConnection getConnection() {
387 return connection;
388 }
389
390
391
392
393
394
395
396 @Deprecated
397 public boolean isMasterRunning()
398 throws MasterNotRunningException, ZooKeeperConnectionException {
399 return connection.isMasterRunning();
400 }
401
402
403
404
405
406
407 @Override
408 public boolean tableExists(final TableName tableName) throws IOException {
409 return MetaTableAccessor.tableExists(connection, tableName);
410 }
411
412 public boolean tableExists(final byte[] tableName)
413 throws IOException {
414 return tableExists(TableName.valueOf(tableName));
415 }
416
417 public boolean tableExists(final String tableName)
418 throws IOException {
419 return tableExists(TableName.valueOf(tableName));
420 }
421
422 @Override
423 public HTableDescriptor[] listTables() throws IOException {
424 return listTables((Pattern)null, false);
425 }
426
427 @Override
428 public HTableDescriptor[] listTables(Pattern pattern) throws IOException {
429 return listTables(pattern, false);
430 }
431
432 @Override
433 public HTableDescriptor[] listTables(String regex) throws IOException {
434 return listTables(Pattern.compile(regex), false);
435 }
436
437 @Override
438 public HTableDescriptor[] listTables(final Pattern pattern, final boolean includeSysTables)
439 throws IOException {
440 return executeCallable(new MasterCallable<HTableDescriptor[]>(getConnection()) {
441 @Override
442 public HTableDescriptor[] call(int callTimeout) throws ServiceException {
443 HBaseRpcController controller = rpcControllerFactory.newController();
444 controller.setCallTimeout(callTimeout);
445 GetTableDescriptorsRequest req =
446 RequestConverter.buildGetTableDescriptorsRequest(pattern, includeSysTables);
447 return ProtobufUtil.getHTableDescriptorArray(master.getTableDescriptors(controller, req));
448 }
449 });
450 }
451
452 @Override
453 public HTableDescriptor[] listTables(String regex, boolean includeSysTables)
454 throws IOException {
455 return listTables(Pattern.compile(regex), includeSysTables);
456 }
457
458
459
460
461
462
463
464 @Deprecated
465 public String[] getTableNames() throws IOException {
466 TableName[] tableNames = listTableNames();
467 String result[] = new String[tableNames.length];
468 for (int i = 0; i < tableNames.length; i++) {
469 result[i] = tableNames[i].getNameAsString();
470 }
471 return result;
472 }
473
474
475
476
477
478
479
480
481 @Deprecated
482 public String[] getTableNames(Pattern pattern) throws IOException {
483 TableName[] tableNames = listTableNames(pattern);
484 String result[] = new String[tableNames.length];
485 for (int i = 0; i < tableNames.length; i++) {
486 result[i] = tableNames[i].getNameAsString();
487 }
488 return result;
489 }
490
491
492
493
494
495
496
497
498 @Deprecated
499 public String[] getTableNames(String regex) throws IOException {
500 return getTableNames(Pattern.compile(regex));
501 }
502
503 @Override
504 public TableName[] listTableNames() throws IOException {
505 return listTableNames((Pattern)null, false);
506 }
507
508 @Override
509 public TableName[] listTableNames(Pattern pattern) throws IOException {
510 return listTableNames(pattern, false);
511 }
512
513 @Override
514 public TableName[] listTableNames(String regex) throws IOException {
515 return listTableNames(Pattern.compile(regex), false);
516 }
517
518 @Override
519 public TableName[] listTableNames(final Pattern pattern, final boolean includeSysTables)
520 throws IOException {
521 return executeCallable(new MasterCallable<TableName[]>(getConnection()) {
522 @Override
523 public TableName[] call(int callTimeout) throws ServiceException {
524 HBaseRpcController controller = rpcControllerFactory.newController();
525 controller.setCallTimeout(callTimeout);
526 GetTableNamesRequest req =
527 RequestConverter.buildGetTableNamesRequest(pattern, includeSysTables);
528 return ProtobufUtil.getTableNameArray(master.getTableNames(controller, req)
529 .getTableNamesList());
530 }
531 });
532 }
533
534 @Override
535 public TableName[] listTableNames(final String regex, final boolean includeSysTables)
536 throws IOException {
537 return listTableNames(Pattern.compile(regex), includeSysTables);
538 }
539
540
541
542
543
544
545
546
547 @Override
548 public HTableDescriptor getTableDescriptor(final TableName tableName)
549 throws TableNotFoundException, IOException {
550 return getTableDescriptor(tableName, getConnection(), rpcCallerFactory, rpcControllerFactory,
551 operationTimeout, rpcTimeout);
552 }
553
554 static HTableDescriptor getTableDescriptor(final TableName tableName, HConnection connection,
555 RpcRetryingCallerFactory rpcCallerFactory, final RpcControllerFactory rpcControllerFactory,
556 int operationTimeout, int rpcTimeout) throws TableNotFoundException, IOException {
557
558 if (tableName == null) return null;
559 HTableDescriptor htd = executeCallable(new MasterCallable<HTableDescriptor>(connection) {
560 @Override
561 public HTableDescriptor call(int callTimeout) throws ServiceException {
562 HBaseRpcController controller = rpcControllerFactory.newController();
563 controller.setCallTimeout(callTimeout);
564 GetTableDescriptorsResponse htds;
565 GetTableDescriptorsRequest req =
566 RequestConverter.buildGetTableDescriptorsRequest(tableName);
567 htds = master.getTableDescriptors(controller, req);
568
569 if (!htds.getTableSchemaList().isEmpty()) {
570 return HTableDescriptor.convert(htds.getTableSchemaList().get(0));
571 }
572 return null;
573 }
574 }, rpcCallerFactory, operationTimeout, rpcTimeout);
575 if (htd != null) {
576 return htd;
577 }
578 throw new TableNotFoundException(tableName.getNameAsString());
579 }
580
581 public HTableDescriptor getTableDescriptor(final byte[] tableName)
582 throws TableNotFoundException, IOException {
583 return getTableDescriptor(TableName.valueOf(tableName));
584 }
585
586 private long getPauseTime(int tries) {
587 int triesCount = tries;
588 if (triesCount >= HConstants.RETRY_BACKOFF.length) {
589 triesCount = HConstants.RETRY_BACKOFF.length - 1;
590 }
591 return this.pause * HConstants.RETRY_BACKOFF[triesCount];
592 }
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607 @Override
608 public void createTable(HTableDescriptor desc)
609 throws IOException {
610 createTable(desc, null);
611 }
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637 @Override
638 public void createTable(HTableDescriptor desc, byte [] startKey,
639 byte [] endKey, int numRegions)
640 throws IOException {
641 if(numRegions < 3) {
642 throw new IllegalArgumentException("Must create at least three regions");
643 } else if(Bytes.compareTo(startKey, endKey) >= 0) {
644 throw new IllegalArgumentException("Start key must be smaller than end key");
645 }
646 if (numRegions == 3) {
647 createTable(desc, new byte[][]{startKey, endKey});
648 return;
649 }
650 byte [][] splitKeys = Bytes.split(startKey, endKey, numRegions - 3);
651 if(splitKeys == null || splitKeys.length != numRegions - 1) {
652 throw new IllegalArgumentException("Unable to split key range into enough regions");
653 }
654 createTable(desc, splitKeys);
655 }
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674 @Override
675 public void createTable(final HTableDescriptor desc, byte [][] splitKeys)
676 throws IOException {
677 Future<Void> future = createTableAsyncV2(desc, splitKeys);
678 try {
679
680 future.get(syncWaitTimeout, TimeUnit.MILLISECONDS);
681 } catch (InterruptedException e) {
682 throw new InterruptedIOException("Interrupted when waiting" +
683 " for table to be enabled; meta scan was done");
684 } catch (TimeoutException e) {
685 throw new TimeoutIOException(e);
686 } catch (ExecutionException e) {
687 if (e.getCause() instanceof IOException) {
688 throw (IOException)e.getCause();
689 } else {
690 throw new IOException(e.getCause());
691 }
692 }
693 }
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711 @Override
712 public void createTableAsync(final HTableDescriptor desc, final byte [][] splitKeys)
713 throws IOException {
714 createTableAsyncV2(desc, splitKeys);
715 }
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733 private Future<Void> createTableAsyncV2(final HTableDescriptor desc, final byte[][] splitKeys)
734 throws IOException {
735 if (desc.getTableName() == null) {
736 throw new IllegalArgumentException("TableName cannot be null");
737 }
738 if (splitKeys != null && splitKeys.length > 0) {
739 Arrays.sort(splitKeys, Bytes.BYTES_COMPARATOR);
740
741 byte[] lastKey = null;
742 for (byte[] splitKey : splitKeys) {
743 if (Bytes.compareTo(splitKey, HConstants.EMPTY_BYTE_ARRAY) == 0) {
744 throw new IllegalArgumentException(
745 "Empty split key must not be passed in the split keys.");
746 }
747 if (lastKey != null && Bytes.equals(splitKey, lastKey)) {
748 throw new IllegalArgumentException("All split keys must be unique, " +
749 "found duplicate: " + Bytes.toStringBinary(splitKey) +
750 ", " + Bytes.toStringBinary(lastKey));
751 }
752 lastKey = splitKey;
753 }
754 }
755
756 CreateTableResponse response = executeCallable(
757 new MasterCallable<CreateTableResponse>(getConnection()) {
758 @Override
759 public CreateTableResponse call(int callTimeout) throws ServiceException {
760 HBaseRpcController controller = rpcControllerFactory.newController();
761 controller.setCallTimeout(callTimeout);
762 controller.setPriority(desc.getTableName());
763 CreateTableRequest request = RequestConverter.buildCreateTableRequest(
764 desc, splitKeys, ng.getNonceGroup(), ng.newNonce());
765 return master.createTable(controller, request);
766 }
767 });
768 return new CreateTableFuture(this, desc, splitKeys, response);
769 }
770
771 private static class CreateTableFuture extends ProcedureFuture<Void> {
772 private final HTableDescriptor desc;
773 private final byte[][] splitKeys;
774
775 public CreateTableFuture(final HBaseAdmin admin, final HTableDescriptor desc,
776 final byte[][] splitKeys, final CreateTableResponse response) {
777 super(admin, (response != null && response.hasProcId()) ? response.getProcId() : null, true);
778 this.splitKeys = splitKeys;
779 this.desc = desc;
780 }
781
782 @Override
783 protected Void waitOperationResult(final long deadlineTs)
784 throws IOException, TimeoutException {
785 waitForTableEnabled(deadlineTs);
786 waitForAllRegionsOnline(deadlineTs);
787 return null;
788 }
789
790 @Override
791 protected Void postOperationResult(final Void result, final long deadlineTs)
792 throws IOException, TimeoutException {
793 LOG.info("Created " + desc.getTableName());
794 return result;
795 }
796
797 private void waitForTableEnabled(final long deadlineTs)
798 throws IOException, TimeoutException {
799 waitForState(deadlineTs, new WaitForStateCallable() {
800 @Override
801 public boolean checkState(int tries) throws IOException {
802 try {
803 if (getAdmin().isTableAvailable(desc.getTableName())) {
804 return true;
805 }
806 } catch (TableNotFoundException tnfe) {
807 LOG.debug("Table "+ desc.getTableName() +" was not enabled, sleeping. tries="+ tries);
808 }
809 return false;
810 }
811
812 @Override
813 public void throwInterruptedException() throws InterruptedIOException {
814 throw new InterruptedIOException("Interrupted when waiting for table " +
815 desc.getTableName() + " to be enabled");
816 }
817
818 @Override
819 public void throwTimeoutException(long elapsedTime) throws TimeoutException {
820 throw new TimeoutException("Table " + desc.getTableName() +
821 " not enabled after " + elapsedTime + "msec");
822 }
823 });
824 }
825
826 private void waitForAllRegionsOnline(final long deadlineTs)
827 throws IOException, TimeoutException {
828 final AtomicInteger actualRegCount = new AtomicInteger(0);
829 final MetaScannerVisitor visitor = new MetaScannerVisitorBase() {
830 @Override
831 public boolean processRow(Result rowResult) throws IOException {
832 RegionLocations list = MetaTableAccessor.getRegionLocations(rowResult);
833 if (list == null) {
834 LOG.warn("No serialized HRegionInfo in " + rowResult);
835 return true;
836 }
837 HRegionLocation l = list.getRegionLocation();
838 if (l == null) {
839 return true;
840 }
841 if (!l.getRegionInfo().getTable().equals(desc.getTableName())) {
842 return false;
843 }
844 if (l.getRegionInfo().isOffline() || l.getRegionInfo().isSplit()) return true;
845 HRegionLocation[] locations = list.getRegionLocations();
846 for (HRegionLocation location : locations) {
847 if (location == null) continue;
848 ServerName serverName = location.getServerName();
849
850 if (serverName != null && serverName.getHostAndPort() != null) {
851 actualRegCount.incrementAndGet();
852 }
853 }
854 return true;
855 }
856 };
857
858 int tries = 0;
859 IOException serverEx = null;
860 int numRegs = (splitKeys == null ? 1 : splitKeys.length + 1) * desc.getRegionReplication();
861 while (EnvironmentEdgeManager.currentTime() < deadlineTs) {
862 actualRegCount.set(0);
863 MetaScanner.metaScan(getAdmin().getConnection(), visitor, desc.getTableName());
864 if (actualRegCount.get() == numRegs) {
865
866 return;
867 }
868
869 try {
870 Thread.sleep(getAdmin().getPauseTime(tries++));
871 } catch (InterruptedException e) {
872 throw new InterruptedIOException("Interrupted when opening" +
873 " regions; " + actualRegCount.get() + " of " + numRegs +
874 " regions processed so far");
875 }
876 }
877 throw new TimeoutException("Only " + actualRegCount.get() +
878 " of " + numRegs + " regions are online; retries exhausted.");
879 }
880 }
881
882 public void deleteTable(final String tableName) throws IOException {
883 deleteTable(TableName.valueOf(tableName));
884 }
885
886 public void deleteTable(final byte[] tableName) throws IOException {
887 deleteTable(TableName.valueOf(tableName));
888 }
889
890
891
892
893
894
895
896
897 @Override
898 public void deleteTable(final TableName tableName) throws IOException {
899 Future<Void> future = deleteTableAsyncV2(tableName);
900 try {
901 future.get(syncWaitTimeout, TimeUnit.MILLISECONDS);
902 } catch (InterruptedException e) {
903 throw new InterruptedIOException("Interrupted when waiting for table to be deleted");
904 } catch (TimeoutException e) {
905 throw new TimeoutIOException(e);
906 } catch (ExecutionException e) {
907 if (e.getCause() instanceof IOException) {
908 throw (IOException)e.getCause();
909 } else {
910 throw new IOException(e.getCause());
911 }
912 }
913 }
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928 private Future<Void> deleteTableAsyncV2(final TableName tableName) throws IOException {
929 DeleteTableResponse response = executeCallable(
930 new MasterCallable<DeleteTableResponse>(getConnection()) {
931 @Override
932 public DeleteTableResponse call(int callTimeout) throws ServiceException {
933 HBaseRpcController controller = rpcControllerFactory.newController();
934 controller.setCallTimeout(callTimeout);
935 controller.setPriority(tableName);
936 DeleteTableRequest req =
937 RequestConverter.buildDeleteTableRequest(tableName, ng.getNonceGroup(),ng.newNonce());
938 return master.deleteTable(controller,req);
939 }
940 });
941 return new DeleteTableFuture(this, tableName, response);
942 }
943
944 private static class DeleteTableFuture extends ProcedureFuture<Void> {
945 private final TableName tableName;
946
947 public DeleteTableFuture(final HBaseAdmin admin, final TableName tableName,
948 final DeleteTableResponse response) {
949 super(admin, (response != null && response.hasProcId()) ? response.getProcId() : null);
950 this.tableName = tableName;
951 }
952
953 @Override
954 protected Void waitOperationResult(final long deadlineTs)
955 throws IOException, TimeoutException {
956 waitTableNotFound(deadlineTs);
957 return null;
958 }
959
960 @Override
961 protected Void postOperationResult(final Void result, final long deadlineTs)
962 throws IOException, TimeoutException {
963
964 getAdmin().getConnection().clearRegionCache(tableName);
965 LOG.info("Deleted " + tableName);
966 return result;
967 }
968
969 private void waitTableNotFound(final long deadlineTs)
970 throws IOException, TimeoutException {
971 waitForState(deadlineTs, new WaitForStateCallable() {
972 @Override
973 public boolean checkState(int tries) throws IOException {
974 return !getAdmin().tableExists(tableName);
975 }
976
977 @Override
978 public void throwInterruptedException() throws InterruptedIOException {
979 throw new InterruptedIOException("Interrupted when waiting for table to be deleted");
980 }
981
982 @Override
983 public void throwTimeoutException(long elapsedTime) throws TimeoutException {
984 throw new TimeoutException("Table " + tableName + " not yet deleted after " +
985 elapsedTime + "msec");
986 }
987 });
988 }
989 }
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004 @Override
1005 public HTableDescriptor[] deleteTables(String regex) throws IOException {
1006 return deleteTables(Pattern.compile(regex));
1007 }
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020 @Override
1021 public HTableDescriptor[] deleteTables(Pattern pattern) throws IOException {
1022 List<HTableDescriptor> failed = new LinkedList<HTableDescriptor>();
1023 for (HTableDescriptor table : listTables(pattern)) {
1024 try {
1025 deleteTable(table.getTableName());
1026 } catch (IOException ex) {
1027 LOG.info("Failed to delete table " + table.getTableName(), ex);
1028 failed.add(table);
1029 }
1030 }
1031 return failed.toArray(new HTableDescriptor[failed.size()]);
1032 }
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042 @Override
1043 public void truncateTable(final TableName tableName, final boolean preserveSplits)
1044 throws IOException {
1045 executeCallable(new MasterCallable<Void>(getConnection()) {
1046 @Override
1047 public Void call(int callTimeout) throws ServiceException {
1048 TruncateTableRequest req = RequestConverter.buildTruncateTableRequest(
1049 tableName, preserveSplits, ng.getNonceGroup(), ng.newNonce());
1050 master.truncateTable(null, req);
1051 return null;
1052 }
1053 });
1054 }
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069 @Override
1070 public void enableTable(final TableName tableName)
1071 throws IOException {
1072 Future<Void> future = enableTableAsyncV2(tableName);
1073 try {
1074 future.get(syncWaitTimeout, TimeUnit.MILLISECONDS);
1075 } catch (InterruptedException e) {
1076 throw new InterruptedIOException("Interrupted when waiting for table to be disabled");
1077 } catch (TimeoutException e) {
1078 throw new TimeoutIOException(e);
1079 } catch (ExecutionException e) {
1080 if (e.getCause() instanceof IOException) {
1081 throw (IOException)e.getCause();
1082 } else {
1083 throw new IOException(e.getCause());
1084 }
1085 }
1086 }
1087
1088 public void enableTable(final byte[] tableName)
1089 throws IOException {
1090 enableTable(TableName.valueOf(tableName));
1091 }
1092
1093 public void enableTable(final String tableName)
1094 throws IOException {
1095 enableTable(TableName.valueOf(tableName));
1096 }
1097
1098
1099
1100
1101
1102
1103
1104
1105 private void waitUntilTableIsEnabled(final TableName tableName) throws IOException {
1106 boolean enabled = false;
1107 long start = EnvironmentEdgeManager.currentTime();
1108 for (int tries = 0; tries < (this.numRetries * this.retryLongerMultiplier); tries++) {
1109 try {
1110 enabled = isTableEnabled(tableName);
1111 } catch (TableNotFoundException tnfe) {
1112
1113 enabled = false;
1114 }
1115 enabled = enabled && isTableAvailable(tableName);
1116 if (enabled) {
1117 break;
1118 }
1119 long sleep = getPauseTime(tries);
1120 if (LOG.isDebugEnabled()) {
1121 LOG.debug("Sleeping= " + sleep + "ms, waiting for all regions to be " +
1122 "enabled in " + tableName);
1123 }
1124 try {
1125 Thread.sleep(sleep);
1126 } catch (InterruptedException e) {
1127
1128
1129 throw (InterruptedIOException)new InterruptedIOException("Interrupted").initCause(e);
1130 }
1131 }
1132 if (!enabled) {
1133 long msec = EnvironmentEdgeManager.currentTime() - start;
1134 throw new IOException("Table '" + tableName +
1135 "' not yet enabled, after " + msec + "ms.");
1136 }
1137 }
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149 @Override
1150 public void enableTableAsync(final TableName tableName)
1151 throws IOException {
1152 enableTableAsyncV2(tableName);
1153 }
1154
1155 public void enableTableAsync(final byte[] tableName)
1156 throws IOException {
1157 enableTable(TableName.valueOf(tableName));
1158 }
1159
1160 public void enableTableAsync(final String tableName)
1161 throws IOException {
1162 enableTableAsync(TableName.valueOf(tableName));
1163 }
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178 private Future<Void> enableTableAsyncV2(final TableName tableName) throws IOException {
1179 TableName.isLegalFullyQualifiedTableName(tableName.getName());
1180 EnableTableResponse response = executeCallable(
1181 new MasterCallable<EnableTableResponse>(getConnection()) {
1182 @Override
1183 public EnableTableResponse call(int callTimeout) throws ServiceException {
1184 HBaseRpcController controller = rpcControllerFactory.newController();
1185 controller.setCallTimeout(callTimeout);
1186 controller.setPriority(tableName);
1187
1188 LOG.info("Started enable of " + tableName);
1189 EnableTableRequest req =
1190 RequestConverter.buildEnableTableRequest(tableName, ng.getNonceGroup(),ng.newNonce());
1191 return master.enableTable(controller,req);
1192 }
1193 });
1194 return new EnableTableFuture(this, tableName, response);
1195 }
1196
1197 private static class EnableTableFuture extends ProcedureFuture<Void> {
1198 private final TableName tableName;
1199
1200 public EnableTableFuture(final HBaseAdmin admin, final TableName tableName,
1201 final EnableTableResponse response) {
1202 super(admin, (response != null && response.hasProcId()) ? response.getProcId() : null, true);
1203 this.tableName = tableName;
1204 }
1205
1206 @Override
1207 protected Void waitOperationResult(final long deadlineTs)
1208 throws IOException, TimeoutException {
1209 waitTableEnabled(deadlineTs);
1210 return null;
1211 }
1212
1213 @Override
1214 protected Void postOperationResult(final Void result, final long deadlineTs)
1215 throws IOException, TimeoutException {
1216 LOG.info("Enabled " + tableName);
1217 return result;
1218 }
1219
1220 private void waitTableEnabled(final long deadlineTs)
1221 throws IOException, TimeoutException {
1222 waitForState(deadlineTs, new WaitForStateCallable() {
1223 @Override
1224 public boolean checkState(int tries) throws IOException {
1225 boolean enabled;
1226 try {
1227 enabled = getAdmin().isTableEnabled(tableName);
1228 } catch (TableNotFoundException tnfe) {
1229 return false;
1230 }
1231 return enabled && getAdmin().isTableAvailable(tableName);
1232 }
1233
1234 @Override
1235 public void throwInterruptedException() throws InterruptedIOException {
1236 throw new InterruptedIOException("Interrupted when waiting for table to be enabled");
1237 }
1238
1239 @Override
1240 public void throwTimeoutException(long elapsedTime) throws TimeoutException {
1241 throw new TimeoutException("Table " + tableName + " not yet enabled after " +
1242 elapsedTime + "msec");
1243 }
1244 });
1245 }
1246 }
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260 @Override
1261 public HTableDescriptor[] enableTables(String regex) throws IOException {
1262 return enableTables(Pattern.compile(regex));
1263 }
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275 @Override
1276 public HTableDescriptor[] enableTables(Pattern pattern) throws IOException {
1277 List<HTableDescriptor> failed = new LinkedList<HTableDescriptor>();
1278 for (HTableDescriptor table : listTables(pattern)) {
1279 if (isTableDisabled(table.getTableName())) {
1280 try {
1281 enableTable(table.getTableName());
1282 } catch (IOException ex) {
1283 LOG.info("Failed to enable table " + table.getTableName(), ex);
1284 failed.add(table);
1285 }
1286 }
1287 }
1288 return failed.toArray(new HTableDescriptor[failed.size()]);
1289 }
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304 @Override
1305 public void disableTableAsync(final TableName tableName) throws IOException {
1306 disableTableAsyncV2(tableName);
1307 }
1308
1309 public void disableTableAsync(final byte[] tableName) throws IOException {
1310 disableTableAsync(TableName.valueOf(tableName));
1311 }
1312
1313 public void disableTableAsync(final String tableName) throws IOException {
1314 disableTableAsync(TableName.valueOf(tableName));
1315 }
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328 @Override
1329 public void disableTable(final TableName tableName)
1330 throws IOException {
1331 Future<Void> future = disableTableAsyncV2(tableName);
1332 try {
1333 future.get(syncWaitTimeout, TimeUnit.MILLISECONDS);
1334 } catch (InterruptedException e) {
1335 throw new InterruptedIOException("Interrupted when waiting for table to be disabled");
1336 } catch (TimeoutException e) {
1337 throw new TimeoutIOException(e);
1338 } catch (ExecutionException e) {
1339 if (e.getCause() instanceof IOException) {
1340 throw (IOException)e.getCause();
1341 } else {
1342 throw new IOException(e.getCause());
1343 }
1344 }
1345 }
1346
1347 public void disableTable(final byte[] tableName)
1348 throws IOException {
1349 disableTable(TableName.valueOf(tableName));
1350 }
1351
1352 public void disableTable(final String tableName)
1353 throws IOException {
1354 disableTable(TableName.valueOf(tableName));
1355 }
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370 private Future<Void> disableTableAsyncV2(final TableName tableName) throws IOException {
1371 TableName.isLegalFullyQualifiedTableName(tableName.getName());
1372 DisableTableResponse response = executeCallable(
1373 new MasterCallable<DisableTableResponse>(getConnection()) {
1374 @Override
1375 public DisableTableResponse call(int callTimeout) throws ServiceException {
1376 HBaseRpcController controller = rpcControllerFactory.newController();
1377 controller.setCallTimeout(callTimeout);
1378 controller.setPriority(tableName);
1379
1380 LOG.info("Started disable of " + tableName);
1381 DisableTableRequest req =
1382 RequestConverter.buildDisableTableRequest(
1383 tableName, ng.getNonceGroup(), ng.newNonce());
1384 return master.disableTable(controller, req);
1385 }
1386 });
1387 return new DisableTableFuture(this, tableName, response);
1388 }
1389
1390 private static class DisableTableFuture extends ProcedureFuture<Void> {
1391 private final TableName tableName;
1392
1393 public DisableTableFuture(final HBaseAdmin admin, final TableName tableName,
1394 final DisableTableResponse response) {
1395 super(admin, (response != null && response.hasProcId()) ? response.getProcId() : null);
1396 this.tableName = tableName;
1397 }
1398
1399 @Override
1400 protected Void waitOperationResult(final long deadlineTs)
1401 throws IOException, TimeoutException {
1402 waitTableDisabled(deadlineTs);
1403 return null;
1404 }
1405
1406 @Override
1407 protected Void postOperationResult(final Void result, final long deadlineTs)
1408 throws IOException, TimeoutException {
1409 LOG.info("Disabled " + tableName);
1410 return result;
1411 }
1412
1413 private void waitTableDisabled(final long deadlineTs)
1414 throws IOException, TimeoutException {
1415 waitForState(deadlineTs, new WaitForStateCallable() {
1416 @Override
1417 public boolean checkState(int tries) throws IOException {
1418 return getAdmin().isTableDisabled(tableName);
1419 }
1420
1421 @Override
1422 public void throwInterruptedException() throws InterruptedIOException {
1423 throw new InterruptedIOException("Interrupted when waiting for table to be disabled");
1424 }
1425
1426 @Override
1427 public void throwTimeoutException(long elapsedTime) throws TimeoutException {
1428 throw new TimeoutException("Table " + tableName + " not yet disabled after " +
1429 elapsedTime + "msec");
1430 }
1431 });
1432 }
1433 }
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448 @Override
1449 public HTableDescriptor[] disableTables(String regex) throws IOException {
1450 return disableTables(Pattern.compile(regex));
1451 }
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464 @Override
1465 public HTableDescriptor[] disableTables(Pattern pattern) throws IOException {
1466 List<HTableDescriptor> failed = new LinkedList<HTableDescriptor>();
1467 for (HTableDescriptor table : listTables(pattern)) {
1468 if (isTableEnabled(table.getTableName())) {
1469 try {
1470 disableTable(table.getTableName());
1471 } catch (IOException ex) {
1472 LOG.info("Failed to disable table " + table.getTableName(), ex);
1473 failed.add(table);
1474 }
1475 }
1476 }
1477 return failed.toArray(new HTableDescriptor[failed.size()]);
1478 }
1479
1480
1481
1482
1483
1484 private void checkTableExistence(TableName tableName) throws IOException {
1485 if (!tableExists(tableName)) {
1486 throw new TableNotFoundException(tableName);
1487 }
1488 }
1489
1490
1491
1492
1493
1494
1495 @Override
1496 public boolean isTableEnabled(TableName tableName) throws IOException {
1497 checkTableExistence(tableName);
1498 return connection.isTableEnabled(tableName);
1499 }
1500
1501 public boolean isTableEnabled(byte[] tableName) throws IOException {
1502 return isTableEnabled(TableName.valueOf(tableName));
1503 }
1504
1505 public boolean isTableEnabled(String tableName) throws IOException {
1506 return isTableEnabled(TableName.valueOf(tableName));
1507 }
1508
1509
1510
1511
1512
1513
1514
1515
1516 @Override
1517 public boolean isTableDisabled(TableName tableName) throws IOException {
1518 checkTableExistence(tableName);
1519 return connection.isTableDisabled(tableName);
1520 }
1521
1522 public boolean isTableDisabled(byte[] tableName) throws IOException {
1523 return isTableDisabled(TableName.valueOf(tableName));
1524 }
1525
1526 public boolean isTableDisabled(String tableName) throws IOException {
1527 return isTableDisabled(TableName.valueOf(tableName));
1528 }
1529
1530
1531
1532
1533
1534
1535 @Override
1536 public boolean isTableAvailable(TableName tableName) throws IOException {
1537 return connection.isTableAvailable(tableName);
1538 }
1539
1540 public boolean isTableAvailable(byte[] tableName) throws IOException {
1541 return isTableAvailable(TableName.valueOf(tableName));
1542 }
1543
1544 public boolean isTableAvailable(String tableName) throws IOException {
1545 return isTableAvailable(TableName.valueOf(tableName));
1546 }
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560 @Override
1561 public boolean isTableAvailable(TableName tableName,
1562 byte[][] splitKeys) throws IOException {
1563 return connection.isTableAvailable(tableName, splitKeys);
1564 }
1565
1566 public boolean isTableAvailable(byte[] tableName,
1567 byte[][] splitKeys) throws IOException {
1568 return isTableAvailable(TableName.valueOf(tableName), splitKeys);
1569 }
1570
1571 public boolean isTableAvailable(String tableName,
1572 byte[][] splitKeys) throws IOException {
1573 return isTableAvailable(TableName.valueOf(tableName), splitKeys);
1574 }
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587 @Override
1588 public Pair<Integer, Integer> getAlterStatus(final TableName tableName)
1589 throws IOException {
1590 return executeCallable(new MasterCallable<Pair<Integer, Integer>>(getConnection()) {
1591 @Override
1592 public Pair<Integer, Integer> call(int callTimeout) throws ServiceException {
1593 HBaseRpcController controller = rpcControllerFactory.newController();
1594 controller.setCallTimeout(callTimeout);
1595 controller.setPriority(tableName);
1596
1597 GetSchemaAlterStatusRequest req = RequestConverter
1598 .buildGetSchemaAlterStatusRequest(tableName);
1599 GetSchemaAlterStatusResponse ret = master.getSchemaAlterStatus(controller, req);
1600 Pair<Integer, Integer> pair = new Pair<Integer, Integer>(Integer.valueOf(ret
1601 .getYetToUpdateRegions()), Integer.valueOf(ret.getTotalRegions()));
1602 return pair;
1603 }
1604 });
1605 }
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619 @Override
1620 public Pair<Integer, Integer> getAlterStatus(final byte[] tableName)
1621 throws IOException {
1622 return getAlterStatus(TableName.valueOf(tableName));
1623 }
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633 public void addColumn(final byte[] tableName, HColumnDescriptor column)
1634 throws IOException {
1635 addColumn(TableName.valueOf(tableName), column);
1636 }
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646 public void addColumn(final String tableName, HColumnDescriptor column)
1647 throws IOException {
1648 addColumn(TableName.valueOf(tableName), column);
1649 }
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659 @Override
1660 public void addColumn(final TableName tableName, final HColumnDescriptor column)
1661 throws IOException {
1662 executeCallable(new MasterCallable<Void>(getConnection()) {
1663 @Override
1664 public Void call(int callTimeout) throws ServiceException {
1665 HBaseRpcController controller = rpcControllerFactory.newController();
1666 controller.setCallTimeout(callTimeout);
1667 controller.setPriority(tableName);
1668 AddColumnRequest req = RequestConverter.buildAddColumnRequest(
1669 tableName, column, ng.getNonceGroup(), ng.newNonce());
1670 master.addColumn(controller,req);
1671 return null;
1672 }
1673 });
1674 }
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684 public void deleteColumn(final byte[] tableName, final String columnName)
1685 throws IOException {
1686 deleteColumn(TableName.valueOf(tableName), Bytes.toBytes(columnName));
1687 }
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697 public void deleteColumn(final String tableName, final String columnName)
1698 throws IOException {
1699 deleteColumn(TableName.valueOf(tableName), Bytes.toBytes(columnName));
1700 }
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710 @Override
1711 public void deleteColumn(final TableName tableName, final byte [] columnName)
1712 throws IOException {
1713 executeCallable(new MasterCallable<Void>(getConnection()) {
1714 @Override
1715 public Void call(int callTimeout) throws ServiceException {
1716 HBaseRpcController controller = rpcControllerFactory.newController();
1717 controller.setCallTimeout(callTimeout);
1718 controller.setPriority(tableName);
1719 DeleteColumnRequest req = RequestConverter.buildDeleteColumnRequest(
1720 tableName, columnName, ng.getNonceGroup(), ng.newNonce());
1721 master.deleteColumn(controller, req);
1722 return null;
1723 }
1724 });
1725 }
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735 public void modifyColumn(final String tableName, HColumnDescriptor descriptor)
1736 throws IOException {
1737 modifyColumn(TableName.valueOf(tableName), descriptor);
1738 }
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748 public void modifyColumn(final byte[] tableName, HColumnDescriptor descriptor)
1749 throws IOException {
1750 modifyColumn(TableName.valueOf(tableName), descriptor);
1751 }
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761 @Override
1762 public void modifyColumn(final TableName tableName, final HColumnDescriptor descriptor)
1763 throws IOException {
1764 executeCallable(new MasterCallable<Void>(getConnection()) {
1765 @Override
1766 public Void call(int callTimeout) throws ServiceException {
1767 HBaseRpcController controller = rpcControllerFactory.newController();
1768 controller.setCallTimeout(callTimeout);
1769 controller.setPriority(tableName);
1770 ModifyColumnRequest req = RequestConverter.buildModifyColumnRequest(
1771 tableName, descriptor, ng.getNonceGroup(), ng.newNonce());
1772 master.modifyColumn(controller, req);
1773 return null;
1774 }
1775 });
1776 }
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786 @Override
1787 public void closeRegion(final String regionname, final String serverName)
1788 throws IOException {
1789 closeRegion(Bytes.toBytes(regionname), serverName);
1790 }
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802 @Override
1803 public void closeRegion(final byte [] regionname, final String serverName)
1804 throws IOException {
1805 if (serverName != null) {
1806 Pair<HRegionInfo, ServerName> pair = MetaTableAccessor.getRegion(connection, regionname);
1807 if (pair == null || pair.getFirst() == null) {
1808 throw new UnknownRegionException(Bytes.toStringBinary(regionname));
1809 } else {
1810 closeRegion(ServerName.valueOf(serverName), pair.getFirst());
1811 }
1812 } else {
1813 Pair<HRegionInfo, ServerName> pair = MetaTableAccessor.getRegion(connection, regionname);
1814 if (pair == null) {
1815 throw new UnknownRegionException(Bytes.toStringBinary(regionname));
1816 } else if (pair.getSecond() == null) {
1817 throw new NoServerForRegionException(Bytes.toStringBinary(regionname));
1818 } else {
1819 closeRegion(pair.getSecond(), pair.getFirst());
1820 }
1821 }
1822 }
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845 @Override
1846 public boolean closeRegionWithEncodedRegionName(final String encodedRegionName,
1847 final String serverName) throws IOException {
1848 if (null == serverName || ("").equals(serverName.trim())) {
1849 throw new IllegalArgumentException(
1850 "The servername cannot be null or empty.");
1851 }
1852 ServerName sn = ServerName.valueOf(serverName);
1853 AdminService.BlockingInterface admin = this.connection.getAdmin(sn);
1854
1855 CloseRegionRequest request =
1856 RequestConverter.buildCloseRegionRequest(sn, encodedRegionName, false);
1857 try {
1858 HBaseRpcController controller = rpcControllerFactory.newController();
1859
1860
1861 CloseRegionResponse response = admin.closeRegion(controller, request);
1862 boolean isRegionClosed = response.getClosed();
1863 if (false == isRegionClosed) {
1864 LOG.error("Not able to close the region " + encodedRegionName + ".");
1865 }
1866 return isRegionClosed;
1867 } catch (ServiceException se) {
1868 throw ProtobufUtil.getRemoteException(se);
1869 }
1870 }
1871
1872
1873
1874
1875
1876
1877
1878
1879 @Override
1880 public void closeRegion(final ServerName sn, final HRegionInfo hri)
1881 throws IOException {
1882 AdminService.BlockingInterface admin = this.connection.getAdmin(sn);
1883 HBaseRpcController controller = rpcControllerFactory.newController();
1884
1885
1886 ProtobufUtil.closeRegion(controller, admin, sn, hri.getRegionName(), false);
1887 }
1888
1889
1890
1891
1892 @Override
1893 public List<HRegionInfo> getOnlineRegions(final ServerName sn) throws IOException {
1894 AdminService.BlockingInterface admin = this.connection.getAdmin(sn);
1895 HBaseRpcController controller = rpcControllerFactory.newController();
1896 return ProtobufUtil.getOnlineRegions(controller, admin);
1897 }
1898
1899
1900
1901
1902 @Override
1903 public void flush(final TableName tableName) throws IOException {
1904 checkTableExists(tableName);
1905 if (isTableDisabled(tableName)) {
1906 LOG.info("Table is disabled: " + tableName.getNameAsString());
1907 return;
1908 }
1909 execProcedure("flush-table-proc", tableName.getNameAsString(),
1910 new HashMap<String, String>());
1911 }
1912
1913
1914
1915
1916 @Override
1917 public void flushRegion(final byte[] regionName) throws IOException {
1918 Pair<HRegionInfo, ServerName> regionServerPair = getRegion(regionName);
1919 if (regionServerPair == null) {
1920 throw new IllegalArgumentException("Unknown regionname: " + Bytes.toStringBinary(regionName));
1921 }
1922 if (regionServerPair.getSecond() == null) {
1923 throw new NoServerForRegionException(Bytes.toStringBinary(regionName));
1924 }
1925 flush(regionServerPair.getSecond(), regionServerPair.getFirst());
1926 }
1927
1928
1929
1930
1931
1932 @Deprecated
1933 public void flush(final String tableNameOrRegionName)
1934 throws IOException, InterruptedException {
1935 flush(Bytes.toBytes(tableNameOrRegionName));
1936 }
1937
1938
1939
1940
1941
1942 @Deprecated
1943 public void flush(final byte[] tableNameOrRegionName)
1944 throws IOException, InterruptedException {
1945 try {
1946 flushRegion(tableNameOrRegionName);
1947 } catch (IllegalArgumentException e) {
1948
1949 flush(TableName.valueOf(tableNameOrRegionName));
1950 }
1951 }
1952
1953 private void flush(final ServerName sn, final HRegionInfo hri)
1954 throws IOException {
1955 HBaseRpcController controller = rpcControllerFactory.newController();
1956 AdminService.BlockingInterface admin = this.connection.getAdmin(sn);
1957 FlushRegionRequest request =
1958 RequestConverter.buildFlushRegionRequest(hri.getRegionName());
1959 try {
1960 admin.flushRegion(controller, request);
1961 } catch (ServiceException se) {
1962 throw ProtobufUtil.getRemoteException(se);
1963 }
1964 }
1965
1966
1967
1968
1969 @Override
1970 public void compact(final TableName tableName)
1971 throws IOException {
1972 compact(tableName, null, false);
1973 }
1974
1975
1976
1977
1978 @Override
1979 public void compactRegion(final byte[] regionName)
1980 throws IOException {
1981 compactRegion(regionName, null, false);
1982 }
1983
1984
1985
1986
1987
1988 @Deprecated
1989 public void compact(final String tableNameOrRegionName)
1990 throws IOException {
1991 compact(Bytes.toBytes(tableNameOrRegionName));
1992 }
1993
1994
1995
1996
1997
1998 @Deprecated
1999 public void compact(final byte[] tableNameOrRegionName)
2000 throws IOException {
2001 try {
2002 compactRegion(tableNameOrRegionName, null, false);
2003 } catch (IllegalArgumentException e) {
2004 compact(TableName.valueOf(tableNameOrRegionName), null, false);
2005 }
2006 }
2007
2008
2009
2010
2011 @Override
2012 public void compact(final TableName tableName, final byte[] columnFamily)
2013 throws IOException {
2014 compact(tableName, columnFamily, false);
2015 }
2016
2017
2018
2019
2020 @Override
2021 public void compactRegion(final byte[] regionName, final byte[] columnFamily)
2022 throws IOException {
2023 compactRegion(regionName, columnFamily, false);
2024 }
2025
2026
2027
2028
2029
2030 @Deprecated
2031 public void compact(String tableOrRegionName, String columnFamily)
2032 throws IOException {
2033 compact(Bytes.toBytes(tableOrRegionName), Bytes.toBytes(columnFamily));
2034 }
2035
2036
2037
2038
2039
2040 @Deprecated
2041 public void compact(final byte[] tableNameOrRegionName, final byte[] columnFamily)
2042 throws IOException {
2043 try {
2044 compactRegion(tableNameOrRegionName, columnFamily, false);
2045 } catch (IllegalArgumentException e) {
2046
2047 compact(TableName.valueOf(tableNameOrRegionName), columnFamily, false);
2048 }
2049 }
2050
2051
2052
2053
2054 @Override
2055 public void compactRegionServer(final ServerName sn, boolean major)
2056 throws IOException, InterruptedException {
2057 for (HRegionInfo region : getOnlineRegions(sn)) {
2058 compact(sn, region, major, null);
2059 }
2060 }
2061
2062
2063
2064
2065 @Override
2066 public void majorCompact(final TableName tableName)
2067 throws IOException {
2068 compact(tableName, null, true);
2069 }
2070
2071
2072
2073
2074 @Override
2075 public void majorCompactRegion(final byte[] regionName)
2076 throws IOException {
2077 compactRegion(regionName, null, true);
2078 }
2079
2080
2081
2082
2083
2084 @Deprecated
2085 public void majorCompact(final String tableNameOrRegionName)
2086 throws IOException {
2087 majorCompact(Bytes.toBytes(tableNameOrRegionName));
2088 }
2089
2090
2091
2092
2093
2094 @Deprecated
2095 public void majorCompact(final byte[] tableNameOrRegionName)
2096 throws IOException {
2097 try {
2098 compactRegion(tableNameOrRegionName, null, true);
2099 } catch (IllegalArgumentException e) {
2100
2101 compact(TableName.valueOf(tableNameOrRegionName), null, true);
2102 }
2103 }
2104
2105
2106
2107
2108 @Override
2109 public void majorCompact(final TableName tableName, final byte[] columnFamily)
2110 throws IOException {
2111 compact(tableName, columnFamily, true);
2112 }
2113
2114
2115
2116
2117 @Override
2118 public void majorCompactRegion(final byte[] regionName, final byte[] columnFamily)
2119 throws IOException {
2120 compactRegion(regionName, columnFamily, true);
2121 }
2122
2123
2124
2125
2126
2127 @Deprecated
2128 public void majorCompact(final String tableNameOrRegionName, final String columnFamily)
2129 throws IOException {
2130 majorCompact(Bytes.toBytes(tableNameOrRegionName), Bytes.toBytes(columnFamily));
2131 }
2132
2133
2134
2135
2136
2137 @Deprecated
2138 public void majorCompact(final byte[] tableNameOrRegionName, final byte[] columnFamily)
2139 throws IOException {
2140 try {
2141 compactRegion(tableNameOrRegionName, columnFamily, true);
2142 } catch (IllegalArgumentException e) {
2143
2144 compact(TableName.valueOf(tableNameOrRegionName), columnFamily, true);
2145 }
2146 }
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158 private void compact(final TableName tableName, final byte[] columnFamily,final boolean major)
2159 throws IOException {
2160 ZooKeeperWatcher zookeeper = null;
2161 try {
2162 checkTableExists(tableName);
2163 zookeeper = new ZooKeeperWatcher(conf, ZK_IDENTIFIER_PREFIX + connection.toString(),
2164 new ThrowableAbortable());
2165 List<Pair<HRegionInfo, ServerName>> pairs =
2166 MetaTableAccessor.getTableRegionsAndLocations(zookeeper, connection, tableName);
2167 for (Pair<HRegionInfo, ServerName> pair: pairs) {
2168 if (pair.getFirst().isOffline()) continue;
2169 if (pair.getSecond() == null) continue;
2170 try {
2171 compact(pair.getSecond(), pair.getFirst(), major, columnFamily);
2172 } catch (NotServingRegionException e) {
2173 if (LOG.isDebugEnabled()) {
2174 LOG.debug("Trying to" + (major ? " major" : "") + " compact " +
2175 pair.getFirst() + ": " +
2176 StringUtils.stringifyException(e));
2177 }
2178 }
2179 }
2180 } finally {
2181 if (zookeeper != null) {
2182 zookeeper.close();
2183 }
2184 }
2185 }
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197 private void compactRegion(final byte[] regionName, final byte[] columnFamily,final boolean major)
2198 throws IOException {
2199 Pair<HRegionInfo, ServerName> regionServerPair = getRegion(regionName);
2200 if (regionServerPair == null) {
2201 throw new IllegalArgumentException("Invalid region: " + Bytes.toStringBinary(regionName));
2202 }
2203 if (regionServerPair.getSecond() == null) {
2204 throw new NoServerForRegionException(Bytes.toStringBinary(regionName));
2205 }
2206 compact(regionServerPair.getSecond(), regionServerPair.getFirst(), major, columnFamily);
2207 }
2208
2209 private void compact(final ServerName sn, final HRegionInfo hri,
2210 final boolean major, final byte [] family)
2211 throws IOException {
2212 HBaseRpcController controller = rpcControllerFactory.newController();
2213 AdminService.BlockingInterface admin = this.connection.getAdmin(sn);
2214 CompactRegionRequest request =
2215 RequestConverter.buildCompactRegionRequest(hri.getRegionName(), major, family);
2216 try {
2217
2218 admin.compactRegion(controller, request);
2219 } catch (ServiceException se) {
2220 throw ProtobufUtil.getRemoteException(se);
2221 }
2222 }
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237 @Override
2238 public void move(final byte [] encodedRegionName, final byte [] destServerName)
2239 throws IOException {
2240
2241 executeCallable(new MasterCallable<Void>(getConnection()) {
2242 @Override
2243 public Void call(int callTimeout) throws ServiceException {
2244 HBaseRpcController controller = rpcControllerFactory.newController();
2245 controller.setCallTimeout(callTimeout);
2246
2247 if (isMetaRegion(encodedRegionName)) {
2248 controller.setPriority(TableName.META_TABLE_NAME);
2249 }
2250
2251 try {
2252 MoveRegionRequest request =
2253 RequestConverter.buildMoveRegionRequest(encodedRegionName, destServerName);
2254 master.moveRegion(controller, request);
2255 } catch (DeserializationException de) {
2256 LOG.error("Could not parse destination server name: " + de);
2257 throw new ServiceException(new DoNotRetryIOException(de));
2258 }
2259 return null;
2260 }
2261 });
2262 }
2263
2264 private boolean isMetaRegion(final byte[] regionName) {
2265 return Bytes.equals(regionName, HRegionInfo.FIRST_META_REGIONINFO.getRegionName())
2266 || Bytes.equals(regionName, HRegionInfo.FIRST_META_REGIONINFO.getEncodedNameAsBytes());
2267 }
2268
2269
2270
2271
2272
2273
2274
2275
2276 @Override
2277 public void assign(final byte[] regionName) throws MasterNotRunningException,
2278 ZooKeeperConnectionException, IOException {
2279 final byte[] toBeAssigned = getRegionName(regionName);
2280 executeCallable(new MasterCallable<Void>(getConnection()) {
2281 @Override
2282 public Void call(int callTimeout) throws ServiceException {
2283 HBaseRpcController controller = rpcControllerFactory.newController();
2284 controller.setCallTimeout(callTimeout);
2285
2286 if (isMetaRegion(regionName)) {
2287 controller.setPriority(TableName.META_TABLE_NAME);
2288 }
2289
2290 AssignRegionRequest request =
2291 RequestConverter.buildAssignRegionRequest(toBeAssigned);
2292 master.assignRegion(controller,request);
2293 return null;
2294 }
2295 });
2296 }
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312 @Override
2313 public void unassign(final byte [] regionName, final boolean force)
2314 throws MasterNotRunningException, ZooKeeperConnectionException, IOException {
2315 final byte[] toBeUnassigned = getRegionName(regionName);
2316 executeCallable(new MasterCallable<Void>(getConnection()) {
2317 @Override
2318 public Void call(int callTimeout) throws ServiceException {
2319 HBaseRpcController controller = rpcControllerFactory.newController();
2320 controller.setCallTimeout(callTimeout);
2321
2322 if (isMetaRegion(regionName)) {
2323 controller.setPriority(TableName.META_TABLE_NAME);
2324 }
2325 UnassignRegionRequest request =
2326 RequestConverter.buildUnassignRegionRequest(toBeUnassigned, force);
2327 master.unassignRegion(controller, request);
2328 return null;
2329 }
2330 });
2331 }
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345 @Override
2346 public void offline(final byte [] regionName)
2347 throws IOException {
2348 executeCallable(new MasterCallable<Void>(getConnection()) {
2349 @Override
2350 public Void call(int callTimeout) throws ServiceException {
2351 HBaseRpcController controller = rpcControllerFactory.newController();
2352 controller.setCallTimeout(callTimeout);
2353
2354 if (isMetaRegion(regionName)) {
2355 controller.setPriority(TableName.META_TABLE_NAME);
2356 }
2357 master.offlineRegion(controller, RequestConverter.buildOfflineRegionRequest(regionName));
2358 return null;
2359 }
2360 });
2361 }
2362
2363
2364
2365
2366
2367
2368
2369 @Override
2370 public boolean setBalancerRunning(final boolean on, final boolean synchronous)
2371 throws IOException {
2372 return executeCallable(new MasterCallable<Boolean>(getConnection()) {
2373 @Override
2374 public Boolean call(int callTimeout) throws ServiceException {
2375 HBaseRpcController controller = rpcControllerFactory.newController();
2376 controller.setCallTimeout(callTimeout);
2377
2378 SetBalancerRunningRequest req =
2379 RequestConverter.buildSetBalancerRunningRequest(on, synchronous);
2380 return master.setBalancerRunning(controller, req).getPrevBalanceValue();
2381 }
2382 });
2383 }
2384
2385
2386
2387
2388
2389
2390
2391 @Override
2392 public boolean balancer() throws IOException {
2393 return executeCallable(new MasterCallable<Boolean>(getConnection()) {
2394 @Override
2395 public Boolean call(int callTimeout) throws ServiceException {
2396 HBaseRpcController controller = rpcControllerFactory.newController();
2397 controller.setCallTimeout(callTimeout);
2398
2399 return master.balance(controller,
2400 RequestConverter.buildBalanceRequest(false)).getBalancerRan();
2401 }
2402 });
2403 }
2404
2405 @Override
2406 public boolean balancer(final boolean force) throws IOException {
2407 return executeCallable(new MasterCallable<Boolean>(getConnection()) {
2408 @Override
2409 public Boolean call(int callTimeout) throws ServiceException {
2410 HBaseRpcController controller = rpcControllerFactory.newController();
2411 controller.setCallTimeout(callTimeout);
2412
2413 return master.balance(controller,
2414 RequestConverter.buildBalanceRequest(force)).getBalancerRan();
2415 }
2416 });
2417 }
2418
2419
2420
2421
2422
2423
2424
2425 @Override
2426 public boolean isBalancerEnabled() throws IOException {
2427 return executeCallable(new MasterCallable<Boolean>(getConnection()) {
2428 @Override
2429 public Boolean call(int callTimeout) throws ServiceException {
2430 HBaseRpcController controller = rpcControllerFactory.newController();
2431 controller.setCallTimeout(callTimeout);
2432
2433 return master.isBalancerEnabled(controller,
2434 RequestConverter.buildIsBalancerEnabledRequest()).getEnabled();
2435 }
2436 });
2437 }
2438
2439
2440
2441
2442
2443
2444 @Override
2445 public boolean normalize() throws IOException {
2446 return executeCallable(new MasterCallable<Boolean>(getConnection()) {
2447 @Override
2448 public Boolean call(int callTimeout) throws ServiceException {
2449 HBaseRpcController controller = rpcControllerFactory.newController();
2450 controller.setCallTimeout(callTimeout);
2451
2452 return master.normalize(controller,
2453 RequestConverter.buildNormalizeRequest()).getNormalizerRan();
2454 }
2455 });
2456 }
2457
2458
2459
2460
2461
2462
2463 @Override
2464 public boolean isNormalizerEnabled() throws IOException {
2465 return executeCallable(new MasterCallable<Boolean>(getConnection()) {
2466 @Override
2467 public Boolean call(int callTimeout) throws ServiceException {
2468 HBaseRpcController controller = rpcControllerFactory.newController();
2469 controller.setCallTimeout(callTimeout);
2470
2471 return master.isNormalizerEnabled(controller,
2472 RequestConverter.buildIsNormalizerEnabledRequest()).getEnabled();
2473 }
2474 });
2475 }
2476
2477
2478
2479
2480
2481
2482 @Override
2483 public boolean setNormalizerRunning(final boolean on) throws IOException {
2484 return executeCallable(new MasterCallable<Boolean>(getConnection()) {
2485 @Override
2486 public Boolean call(int callTimeout) throws ServiceException {
2487 HBaseRpcController controller = rpcControllerFactory.newController();
2488 controller.setCallTimeout(callTimeout);
2489
2490 SetNormalizerRunningRequest req =
2491 RequestConverter.buildSetNormalizerRunningRequest(on);
2492 return master.setNormalizerRunning(controller, req).getPrevNormalizerValue();
2493 }
2494 });
2495 }
2496
2497
2498
2499
2500
2501
2502
2503 @Override
2504 public boolean enableCatalogJanitor(final boolean enable)
2505 throws IOException {
2506 return executeCallable(new MasterCallable<Boolean>(getConnection()) {
2507 @Override
2508 public Boolean call(int callTimeout) throws ServiceException {
2509 HBaseRpcController controller = rpcControllerFactory.newController();
2510 controller.setCallTimeout(callTimeout);
2511
2512 return master.enableCatalogJanitor(controller,
2513 RequestConverter.buildEnableCatalogJanitorRequest(enable)).getPrevValue();
2514 }
2515 });
2516 }
2517
2518
2519
2520
2521
2522
2523 @Override
2524 public int runCatalogScan() throws IOException {
2525 return executeCallable(new MasterCallable<Integer>(getConnection()) {
2526 @Override
2527 public Integer call(int callTimeout) throws ServiceException {
2528 HBaseRpcController controller = rpcControllerFactory.newController();
2529 controller.setCallTimeout(callTimeout);
2530
2531 return master.runCatalogScan(controller,
2532 RequestConverter.buildCatalogScanRequest()).getScanResult();
2533 }
2534 });
2535 }
2536
2537
2538
2539
2540
2541 @Override
2542 public boolean isCatalogJanitorEnabled() throws IOException {
2543 return executeCallable(new MasterCallable<Boolean>(getConnection()) {
2544 @Override
2545 public Boolean call(int callTimeout) throws ServiceException {
2546 HBaseRpcController controller = rpcControllerFactory.newController();
2547 controller.setCallTimeout(callTimeout);
2548
2549 return master.isCatalogJanitorEnabled(controller,
2550 RequestConverter.buildIsCatalogJanitorEnabledRequest()).getValue();
2551 }
2552 });
2553 }
2554
2555 @Override
2556 public boolean setCleanerChoreRunning(final boolean on) throws IOException {
2557 return executeCallable(new MasterCallable<Boolean>(getConnection()) {
2558 @Override
2559 public Boolean call(int callTimeout) throws ServiceException {
2560 return master.setCleanerChoreRunning(null,
2561 RequestConverter.buildSetCleanerChoreRunningRequest(on)).getPrevValue();
2562 }
2563 });
2564 }
2565
2566 @Override
2567 public boolean runCleanerChore() throws IOException {
2568 return executeCallable(new MasterCallable<Boolean>(getConnection()) {
2569 @Override
2570 public Boolean call(int callTimeout) throws ServiceException {
2571 return master.runCleanerChore(null, RequestConverter.buildCleanerChoreRequest())
2572 .getCleanerChoreRan();
2573 }
2574 });
2575 }
2576
2577 @Override
2578 public boolean isCleanerChoreEnabled() throws IOException {
2579 return executeCallable(new MasterCallable<Boolean>(getConnection()) {
2580 @Override
2581 public Boolean call(int callTimeout) throws ServiceException {
2582 return master.isCleanerChoreEnabled(null,
2583 RequestConverter.buildIsCleanerChoreEnabledRequest()).getValue();
2584 }
2585 });
2586 }
2587
2588 private boolean isEncodedRegionName(byte[] regionName) throws IOException {
2589 try {
2590 HRegionInfo.parseRegionName(regionName);
2591 return false;
2592 } catch (IOException e) {
2593 if (StringUtils.stringifyException(e)
2594 .contains(HRegionInfo.INVALID_REGION_NAME_FORMAT_MESSAGE)) {
2595 return true;
2596 }
2597 throw e;
2598 }
2599 }
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609 @Override
2610 public void mergeRegions(final byte[] nameOfRegionA,
2611 final byte[] nameOfRegionB, final boolean forcible)
2612 throws IOException {
2613 final byte[] encodedNameOfRegionA = isEncodedRegionName(nameOfRegionA) ? nameOfRegionA :
2614 Bytes.toBytes(HRegionInfo.encodeRegionName(nameOfRegionA));
2615 final byte[] encodedNameOfRegionB = isEncodedRegionName(nameOfRegionB) ? nameOfRegionB :
2616 Bytes.toBytes(HRegionInfo.encodeRegionName(nameOfRegionB));
2617
2618 Pair<HRegionInfo, ServerName> pair = getRegion(nameOfRegionA);
2619 if (pair != null && pair.getFirst().getReplicaId() != HRegionInfo.DEFAULT_REPLICA_ID)
2620 throw new IllegalArgumentException("Can't invoke merge on non-default regions directly");
2621 pair = getRegion(nameOfRegionB);
2622 if (pair != null && pair.getFirst().getReplicaId() != HRegionInfo.DEFAULT_REPLICA_ID)
2623 throw new IllegalArgumentException("Can't invoke merge on non-default regions directly");
2624 executeCallable(new MasterCallable<Void>(getConnection()) {
2625 @Override
2626 public Void call(int callTimeout) throws ServiceException {
2627 HBaseRpcController controller = rpcControllerFactory.newController();
2628 controller.setCallTimeout(callTimeout);
2629
2630 try {
2631 DispatchMergingRegionsRequest request = RequestConverter
2632 .buildDispatchMergingRegionsRequest(encodedNameOfRegionA,
2633 encodedNameOfRegionB, forcible);
2634 master.dispatchMergingRegions(controller, request);
2635 } catch (DeserializationException de) {
2636 LOG.error("Could not parse destination server name: " + de);
2637 }
2638 return null;
2639 }
2640 });
2641 }
2642
2643
2644
2645
2646 @Override
2647 public void split(final TableName tableName)
2648 throws IOException {
2649 split(tableName, null);
2650 }
2651
2652
2653
2654
2655 @Override
2656 public void splitRegion(final byte[] regionName)
2657 throws IOException {
2658 splitRegion(regionName, null);
2659 }
2660
2661
2662
2663
2664
2665 @Deprecated
2666 public void split(final String tableNameOrRegionName)
2667 throws IOException, InterruptedException {
2668 split(Bytes.toBytes(tableNameOrRegionName));
2669 }
2670
2671
2672
2673
2674
2675 @Deprecated
2676 public void split(final byte[] tableNameOrRegionName)
2677 throws IOException, InterruptedException {
2678 split(tableNameOrRegionName, null);
2679 }
2680
2681
2682
2683
2684 @Override
2685 public void split(final TableName tableName, final byte [] splitPoint)
2686 throws IOException {
2687 ZooKeeperWatcher zookeeper = null;
2688 try {
2689 checkTableExists(tableName);
2690 zookeeper = new ZooKeeperWatcher(conf, ZK_IDENTIFIER_PREFIX + connection.toString(),
2691 new ThrowableAbortable());
2692 List<Pair<HRegionInfo, ServerName>> pairs =
2693 MetaTableAccessor.getTableRegionsAndLocations(zookeeper, connection, tableName);
2694 for (Pair<HRegionInfo, ServerName> pair: pairs) {
2695
2696 if (pair.getSecond() == null) continue;
2697 HRegionInfo r = pair.getFirst();
2698
2699 if (r.isSplitParent()) continue;
2700
2701 if (r.getReplicaId() != HRegionInfo.DEFAULT_REPLICA_ID ||
2702 (splitPoint != null && !r.containsRow(splitPoint))) continue;
2703
2704 split(pair.getSecond(), pair.getFirst(), splitPoint);
2705 }
2706 } finally {
2707 if (zookeeper != null) {
2708 zookeeper.close();
2709 }
2710 }
2711 }
2712
2713
2714
2715
2716 @Override
2717 public void splitRegion(final byte[] regionName, final byte [] splitPoint)
2718 throws IOException {
2719 Pair<HRegionInfo, ServerName> regionServerPair = getRegion(regionName);
2720 if (regionServerPair == null) {
2721 throw new IllegalArgumentException("Invalid region: " + Bytes.toStringBinary(regionName));
2722 }
2723 if (regionServerPair.getFirst() != null &&
2724 regionServerPair.getFirst().getReplicaId() != HRegionInfo.DEFAULT_REPLICA_ID) {
2725 throw new IllegalArgumentException("Can't split replicas directly. "
2726 + "Replicas are auto-split when their primary is split.");
2727 }
2728 if (regionServerPair.getSecond() == null) {
2729 throw new NoServerForRegionException(Bytes.toStringBinary(regionName));
2730 }
2731 split(regionServerPair.getSecond(), regionServerPair.getFirst(), splitPoint);
2732 }
2733
2734
2735
2736
2737
2738 @Deprecated
2739 public void split(final String tableNameOrRegionName,
2740 final String splitPoint) throws IOException {
2741 split(Bytes.toBytes(tableNameOrRegionName), Bytes.toBytes(splitPoint));
2742 }
2743
2744
2745
2746
2747
2748 @Deprecated
2749 public void split(final byte[] tableNameOrRegionName,
2750 final byte [] splitPoint) throws IOException {
2751 try {
2752 splitRegion(tableNameOrRegionName, splitPoint);
2753 } catch (IllegalArgumentException e) {
2754
2755 split(TableName.valueOf(tableNameOrRegionName), splitPoint);
2756 }
2757 }
2758
2759 @VisibleForTesting
2760 public void split(final ServerName sn, final HRegionInfo hri,
2761 byte[] splitPoint) throws IOException {
2762 if (hri.getStartKey() != null && splitPoint != null &&
2763 Bytes.compareTo(hri.getStartKey(), splitPoint) == 0) {
2764 throw new IOException("should not give a splitkey which equals to startkey!");
2765 }
2766 HBaseRpcController controller = rpcControllerFactory.newController();
2767 controller.setPriority(hri.getTable());
2768
2769
2770 AdminService.BlockingInterface admin = this.connection.getAdmin(sn);
2771 ProtobufUtil.split(controller, admin, hri, splitPoint);
2772 }
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783 @Override
2784 public void modifyTable(final TableName tableName, final HTableDescriptor htd)
2785 throws IOException {
2786 if (!tableName.equals(htd.getTableName())) {
2787 throw new IllegalArgumentException("the specified table name '" + tableName +
2788 "' doesn't match with the HTD one: " + htd.getTableName());
2789 }
2790
2791 executeCallable(new MasterCallable<Void>(getConnection()) {
2792 @Override
2793 public Void call(int callTimeout) throws ServiceException {
2794 HBaseRpcController controller = rpcControllerFactory.newController();
2795 controller.setCallTimeout(callTimeout);
2796 controller.setPriority(tableName);
2797 ModifyTableRequest request = RequestConverter.buildModifyTableRequest(
2798 tableName, htd, ng.getNonceGroup(), ng.newNonce());
2799 master.modifyTable(controller, request);
2800 return null;
2801 }
2802 });
2803 }
2804
2805 public void modifyTable(final byte[] tableName, final HTableDescriptor htd)
2806 throws IOException {
2807 modifyTable(TableName.valueOf(tableName), htd);
2808 }
2809
2810 public void modifyTable(final String tableName, final HTableDescriptor htd)
2811 throws IOException {
2812 modifyTable(TableName.valueOf(tableName), htd);
2813 }
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824 Pair<HRegionInfo, ServerName> getRegion(final byte[] regionName) throws IOException {
2825 if (regionName == null) {
2826 throw new IllegalArgumentException("Pass a table name or region name");
2827 }
2828 Pair<HRegionInfo, ServerName> pair =
2829 MetaTableAccessor.getRegion(connection, regionName);
2830 if (pair == null) {
2831 final AtomicReference<Pair<HRegionInfo, ServerName>> result =
2832 new AtomicReference<Pair<HRegionInfo, ServerName>>(null);
2833 final String encodedName = Bytes.toString(regionName);
2834 MetaScannerVisitor visitor = new MetaScannerVisitorBase() {
2835 @Override
2836 public boolean processRow(Result data) throws IOException {
2837 HRegionInfo info = HRegionInfo.getHRegionInfo(data);
2838 if (info == null) {
2839 LOG.warn("No serialized HRegionInfo in " + data);
2840 return true;
2841 }
2842 RegionLocations rl = MetaTableAccessor.getRegionLocations(data);
2843 boolean matched = false;
2844 ServerName sn = null;
2845 for (HRegionLocation h : rl.getRegionLocations()) {
2846 if (h != null && encodedName.equals(h.getRegionInfo().getEncodedName())) {
2847 sn = h.getServerName();
2848 info = h.getRegionInfo();
2849 matched = true;
2850 }
2851 }
2852 if (!matched) return true;
2853 result.set(new Pair<HRegionInfo, ServerName>(info, sn));
2854 return false;
2855 }
2856 };
2857
2858 MetaScanner.metaScan(connection, visitor, null);
2859 pair = result.get();
2860 }
2861 return pair;
2862 }
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872 private byte[] getRegionName(
2873 final byte[] regionNameOrEncodedRegionName) throws IOException {
2874 if (Bytes.equals(regionNameOrEncodedRegionName,
2875 HRegionInfo.FIRST_META_REGIONINFO.getRegionName())
2876 || Bytes.equals(regionNameOrEncodedRegionName,
2877 HRegionInfo.FIRST_META_REGIONINFO.getEncodedNameAsBytes())) {
2878 return HRegionInfo.FIRST_META_REGIONINFO.getRegionName();
2879 }
2880 byte[] tmp = regionNameOrEncodedRegionName;
2881 Pair<HRegionInfo, ServerName> regionServerPair = getRegion(regionNameOrEncodedRegionName);
2882 if (regionServerPair != null && regionServerPair.getFirst() != null) {
2883 tmp = regionServerPair.getFirst().getRegionName();
2884 }
2885 return tmp;
2886 }
2887
2888
2889
2890
2891
2892
2893
2894
2895 private TableName checkTableExists(final TableName tableName)
2896 throws IOException {
2897 if (!MetaTableAccessor.tableExists(connection, tableName)) {
2898 throw new TableNotFoundException(tableName);
2899 }
2900 return tableName;
2901 }
2902
2903
2904
2905
2906
2907 @Override
2908 public synchronized void shutdown() throws IOException {
2909 executeCallable(new MasterCallable<Void>(getConnection()) {
2910 @Override
2911 public Void call(int callTimeout) throws ServiceException {
2912 HBaseRpcController controller = rpcControllerFactory.newController();
2913 controller.setCallTimeout(callTimeout);
2914 controller.setPriority(HConstants.HIGH_QOS);
2915 master.shutdown(controller, ShutdownRequest.newBuilder().build());
2916 return null;
2917 }
2918 });
2919 }
2920
2921
2922
2923
2924
2925
2926
2927 @Override
2928 public synchronized void stopMaster() throws IOException {
2929 executeCallable(new MasterCallable<Void>(getConnection()) {
2930 @Override
2931 public Void call(int callTimeout) throws ServiceException {
2932 HBaseRpcController controller = rpcControllerFactory.newController();
2933 controller.setCallTimeout(callTimeout);
2934 controller.setPriority(HConstants.HIGH_QOS);
2935 master.stopMaster(controller, StopMasterRequest.newBuilder().build());
2936 return null;
2937 }
2938 });
2939 }
2940
2941
2942
2943
2944
2945
2946
2947 @Override
2948 public synchronized void stopRegionServer(final String hostnamePort)
2949 throws IOException {
2950 String hostname = Addressing.parseHostname(hostnamePort);
2951 int port = Addressing.parsePort(hostnamePort);
2952 AdminService.BlockingInterface admin =
2953 this.connection.getAdmin(ServerName.valueOf(hostname, port, 0));
2954 StopServerRequest request = RequestConverter.buildStopServerRequest(
2955 "Called by admin client " + this.connection.toString());
2956 HBaseRpcController controller = rpcControllerFactory.newController();
2957
2958 controller.setPriority(HConstants.HIGH_QOS);
2959 try {
2960
2961 admin.stopServer(controller, request);
2962 } catch (ServiceException se) {
2963 throw ProtobufUtil.getRemoteException(se);
2964 }
2965 }
2966
2967
2968
2969
2970
2971
2972 @Override
2973 public boolean isMasterInMaintenanceMode() throws IOException {
2974 return executeCallable(new MasterCallable<IsInMaintenanceModeResponse>(getConnection()) {
2975 @Override
2976 public IsInMaintenanceModeResponse call(int callTimeout) throws ServiceException {
2977 HBaseRpcController controller = rpcControllerFactory.newController();
2978 controller.setCallTimeout(callTimeout);
2979 return master.isMasterInMaintenanceMode(
2980 controller, IsInMaintenanceModeRequest.newBuilder().build());
2981 }
2982 }).getInMaintenanceMode();
2983 }
2984
2985 @Override
2986 public ClusterStatus getClusterStatus() throws IOException {
2987 return executeCallable(new MasterCallable<ClusterStatus>(getConnection()) {
2988 @Override
2989 public ClusterStatus call(int callTimeout) throws ServiceException {
2990 HBaseRpcController controller = rpcControllerFactory.newController();
2991 controller.setCallTimeout(callTimeout);
2992 GetClusterStatusRequest req = RequestConverter.buildGetClusterStatusRequest();
2993 return ClusterStatus.convert(master.getClusterStatus(controller, req).getClusterStatus());
2994 }
2995 });
2996 }
2997
2998
2999
3000
3001 @Override
3002 public Configuration getConfiguration() {
3003 return this.conf;
3004 }
3005
3006
3007
3008
3009
3010
3011 @Override
3012 public void createNamespace(final NamespaceDescriptor descriptor) throws IOException {
3013 executeCallable(new MasterCallable<Void>(getConnection()) {
3014 @Override
3015 public Void call(int callTimeout) throws Exception {
3016 HBaseRpcController controller = rpcControllerFactory.newController();
3017 controller.setCallTimeout(callTimeout);
3018
3019 master.createNamespace(controller,
3020 CreateNamespaceRequest.newBuilder()
3021 .setNamespaceDescriptor(ProtobufUtil
3022 .toProtoNamespaceDescriptor(descriptor)).build()
3023 );
3024 return null;
3025 }
3026 });
3027 }
3028
3029
3030
3031
3032
3033
3034 @Override
3035 public void modifyNamespace(final NamespaceDescriptor descriptor) throws IOException {
3036 executeCallable(new MasterCallable<Void>(getConnection()) {
3037 @Override
3038 public Void call(int callTimeout) throws Exception {
3039 HBaseRpcController controller = rpcControllerFactory.newController();
3040 controller.setCallTimeout(callTimeout);
3041 master.modifyNamespace(controller, ModifyNamespaceRequest.newBuilder().
3042 setNamespaceDescriptor(ProtobufUtil.toProtoNamespaceDescriptor(descriptor)).build());
3043 return null;
3044 }
3045 });
3046 }
3047
3048
3049
3050
3051
3052
3053 @Override
3054 public void deleteNamespace(final String name) throws IOException {
3055 executeCallable(new MasterCallable<Void>(getConnection()) {
3056 @Override
3057 public Void call(int callTimeout) throws Exception {
3058 HBaseRpcController controller = rpcControllerFactory.newController();
3059 controller.setCallTimeout(callTimeout);
3060 master.deleteNamespace(controller, DeleteNamespaceRequest.newBuilder().
3061 setNamespaceName(name).build());
3062 return null;
3063 }
3064 });
3065 }
3066
3067
3068
3069
3070
3071
3072
3073 @Override
3074 public NamespaceDescriptor getNamespaceDescriptor(final String name)
3075 throws NamespaceNotFoundException, IOException {
3076 return
3077 executeCallable(new MasterCallable<NamespaceDescriptor>(getConnection()) {
3078 @Override
3079 public NamespaceDescriptor call(int callTimeout) throws Exception {
3080 HBaseRpcController controller = rpcControllerFactory.newController();
3081 controller.setCallTimeout(callTimeout);
3082 return ProtobufUtil.toNamespaceDescriptor(
3083 master.getNamespaceDescriptor(controller, GetNamespaceDescriptorRequest.newBuilder().
3084 setNamespaceName(name).build()).getNamespaceDescriptor());
3085 }
3086 });
3087 }
3088
3089
3090
3091
3092
3093
3094 @Override
3095 public NamespaceDescriptor[] listNamespaceDescriptors() throws IOException {
3096 return
3097 executeCallable(new MasterCallable<NamespaceDescriptor[]>(getConnection()) {
3098 @Override
3099 public NamespaceDescriptor[] call(int callTimeout) throws Exception {
3100 HBaseRpcController controller = rpcControllerFactory.newController();
3101 controller.setCallTimeout(callTimeout);
3102 List<HBaseProtos.NamespaceDescriptor> list =
3103 master.listNamespaceDescriptors(controller,
3104 ListNamespaceDescriptorsRequest.newBuilder().build())
3105 .getNamespaceDescriptorList();
3106 NamespaceDescriptor[] res = new NamespaceDescriptor[list.size()];
3107 for(int i = 0; i < list.size(); i++) {
3108 res[i] = ProtobufUtil.toNamespaceDescriptor(list.get(i));
3109 }
3110 return res;
3111 }
3112 });
3113 }
3114
3115
3116
3117
3118
3119
3120 @Override
3121 public ProcedureInfo[] listProcedures() throws IOException {
3122 return
3123 executeCallable(new MasterCallable<ProcedureInfo[]>(getConnection()) {
3124 @Override
3125 public ProcedureInfo[] call(int callTimeout) throws Exception {
3126 HBaseRpcController controller = rpcControllerFactory.newController();
3127 controller.setCallTimeout(callTimeout);
3128 List<ProcedureProtos.Procedure> procList = master.listProcedures(
3129 controller, ListProceduresRequest.newBuilder().build()).getProcedureList();
3130 ProcedureInfo[] procInfoList = new ProcedureInfo[procList.size()];
3131 for (int i = 0; i < procList.size(); i++) {
3132 procInfoList[i] = ProcedureInfo.convert(procList.get(i));
3133 }
3134 return procInfoList;
3135 }
3136 });
3137 }
3138
3139
3140
3141
3142
3143
3144
3145 @Override
3146 public HTableDescriptor[] listTableDescriptorsByNamespace(final String name) throws IOException {
3147 return
3148 executeCallable(new MasterCallable<HTableDescriptor[]>(getConnection()) {
3149 @Override
3150 public HTableDescriptor[] call(int callTimeout) throws Exception {
3151 HBaseRpcController controller = rpcControllerFactory.newController();
3152 controller.setCallTimeout(callTimeout);
3153 List<TableSchema> list =
3154 master.listTableDescriptorsByNamespace(controller,
3155 ListTableDescriptorsByNamespaceRequest.newBuilder().setNamespaceName(name)
3156 .build()).getTableSchemaList();
3157 HTableDescriptor[] res = new HTableDescriptor[list.size()];
3158 for(int i=0; i < list.size(); i++) {
3159
3160 res[i] = HTableDescriptor.convert(list.get(i));
3161 }
3162 return res;
3163 }
3164 });
3165 }
3166
3167
3168
3169
3170
3171
3172
3173 @Override
3174 public TableName[] listTableNamesByNamespace(final String name) throws IOException {
3175 return
3176 executeCallable(new MasterCallable<TableName[]>(getConnection()) {
3177 @Override
3178 public TableName[] call(int callTimeout) throws Exception {
3179 HBaseRpcController controller = rpcControllerFactory.newController();
3180 controller.setCallTimeout(callTimeout);
3181 List<TableProtos.TableName> tableNames =
3182 master.listTableNamesByNamespace(controller, ListTableNamesByNamespaceRequest.
3183 newBuilder().setNamespaceName(name).build())
3184 .getTableNameList();
3185 TableName[] result = new TableName[tableNames.size()];
3186 for (int i = 0; i < tableNames.size(); i++) {
3187 result[i] = ProtobufUtil.toTableName(tableNames.get(i));
3188 }
3189 return result;
3190 }
3191 });
3192 }
3193
3194
3195
3196
3197
3198
3199
3200
3201 public static void checkHBaseAvailable(Configuration conf)
3202 throws MasterNotRunningException, ZooKeeperConnectionException, ServiceException, IOException {
3203 Configuration copyOfConf = HBaseConfiguration.create(conf);
3204
3205 copyOfConf.setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 1);
3206 copyOfConf.setInt("zookeeper.recovery.retry", 0);
3207 try (ClusterConnection connection =
3208 (ClusterConnection)ConnectionFactory.createConnection(copyOfConf)) {
3209
3210
3211 ZooKeeperKeepAliveConnection zkw = null;
3212 try {
3213
3214 zkw = ((ConnectionManager.HConnectionImplementation)connection).
3215 getKeepAliveZooKeeperWatcher();
3216 zkw.getRecoverableZooKeeper().getZooKeeper().exists(zkw.baseZNode, false);
3217 } catch (IOException e) {
3218 throw new ZooKeeperConnectionException("Can't connect to ZooKeeper", e);
3219 } catch (InterruptedException e) {
3220 throw (InterruptedIOException)
3221 new InterruptedIOException("Can't connect to ZooKeeper").initCause(e);
3222 } catch (KeeperException e) {
3223 throw new ZooKeeperConnectionException("Can't connect to ZooKeeper", e);
3224 } finally {
3225 if (zkw != null) {
3226 zkw.close();
3227 }
3228 }
3229 connection.isMasterRunning();
3230 }
3231 }
3232
3233
3234
3235
3236
3237
3238
3239
3240 @Override
3241 public List<HRegionInfo> getTableRegions(final TableName tableName)
3242 throws IOException {
3243 ZooKeeperWatcher zookeeper =
3244 new ZooKeeperWatcher(conf, ZK_IDENTIFIER_PREFIX + connection.toString(),
3245 new ThrowableAbortable());
3246 List<HRegionInfo> Regions = null;
3247 try {
3248 Regions = MetaTableAccessor.getTableRegions(zookeeper, connection, tableName, true);
3249 } finally {
3250 zookeeper.close();
3251 }
3252 return Regions;
3253 }
3254
3255 public List<HRegionInfo> getTableRegions(final byte[] tableName)
3256 throws IOException {
3257 return getTableRegions(TableName.valueOf(tableName));
3258 }
3259
3260 @Override
3261 public synchronized void close() throws IOException {
3262 if (cleanupConnectionOnClose && this.connection != null && !this.closed) {
3263 this.connection.close();
3264 this.closed = true;
3265 }
3266 }
3267
3268
3269
3270
3271
3272
3273
3274 @Override
3275 public HTableDescriptor[] getTableDescriptorsByTableName(final List<TableName> tableNames)
3276 throws IOException {
3277 return executeCallable(new MasterCallable<HTableDescriptor[]>(getConnection()) {
3278 @Override
3279 public HTableDescriptor[] call(int callTimeout) throws Exception {
3280 HBaseRpcController controller = rpcControllerFactory.newController();
3281 controller.setCallTimeout(callTimeout);
3282 GetTableDescriptorsRequest req =
3283 RequestConverter.buildGetTableDescriptorsRequest(tableNames);
3284 return ProtobufUtil.getHTableDescriptorArray(master.getTableDescriptors(controller, req));
3285 }
3286 });
3287 }
3288
3289
3290
3291
3292
3293
3294
3295 private HTableDescriptor getTableDescriptorByTableName(TableName tableName)
3296 throws IOException {
3297 List<TableName> tableNames = new ArrayList<TableName>(1);
3298 tableNames.add(tableName);
3299
3300 HTableDescriptor[] htdl = getTableDescriptorsByTableName(tableNames);
3301
3302 if (htdl == null || htdl.length == 0) {
3303 return null;
3304 }
3305 else {
3306 return htdl[0];
3307 }
3308 }
3309
3310
3311
3312
3313
3314
3315
3316 @Override
3317 public HTableDescriptor[] getTableDescriptors(List<String> names)
3318 throws IOException {
3319 List<TableName> tableNames = new ArrayList<TableName>(names.size());
3320 for(String name : names) {
3321 tableNames.add(TableName.valueOf(name));
3322 }
3323 return getTableDescriptorsByTableName(tableNames);
3324 }
3325
3326 private RollWALWriterResponse rollWALWriterImpl(final ServerName sn) throws IOException,
3327 FailedLogCloseException {
3328 AdminService.BlockingInterface admin = this.connection.getAdmin(sn);
3329 RollWALWriterRequest request = RequestConverter.buildRollWALWriterRequest();
3330 HBaseRpcController controller = rpcControllerFactory.newController();
3331
3332 try {
3333
3334 return admin.rollWALWriter(controller, request);
3335 } catch (ServiceException se) {
3336 throw ProtobufUtil.getRemoteException(se);
3337 }
3338 }
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362 @Deprecated
3363 public synchronized byte[][] rollHLogWriter(String serverName)
3364 throws IOException, FailedLogCloseException {
3365 ServerName sn = ServerName.valueOf(serverName);
3366 final RollWALWriterResponse response = rollWALWriterImpl(sn);
3367 int regionCount = response.getRegionToFlushCount();
3368 if (0 == regionCount) {
3369 return null;
3370 }
3371 byte[][] regionsToFlush = new byte[regionCount][];
3372 for (int i = 0; i < regionCount; i++) {
3373 ByteString region = response.getRegionToFlush(i);
3374 regionsToFlush[i] = region.toByteArray();
3375 }
3376 return regionsToFlush;
3377 }
3378
3379 @Override
3380 public synchronized void rollWALWriter(ServerName serverName)
3381 throws IOException, FailedLogCloseException {
3382 rollWALWriterImpl(serverName);
3383 }
3384
3385 @Override
3386 public String[] getMasterCoprocessors() {
3387 try {
3388 return getClusterStatus().getMasterCoprocessors();
3389 } catch (IOException e) {
3390 LOG.error("Could not getClusterStatus()",e);
3391 return null;
3392 }
3393 }
3394
3395
3396
3397
3398 @Override
3399 public CompactionState getCompactionState(final TableName tableName)
3400 throws IOException {
3401 CompactionState state = CompactionState.NONE;
3402 ZooKeeperWatcher zookeeper =
3403 new ZooKeeperWatcher(conf, ZK_IDENTIFIER_PREFIX + connection.toString(),
3404 new ThrowableAbortable());
3405 try {
3406 checkTableExists(tableName);
3407 List<Pair<HRegionInfo, ServerName>> pairs =
3408 MetaTableAccessor.getTableRegionsAndLocations(zookeeper, connection, tableName);
3409 for (Pair<HRegionInfo, ServerName> pair: pairs) {
3410 if (pair.getFirst().isOffline()) continue;
3411 if (pair.getSecond() == null) continue;
3412 try {
3413 ServerName sn = pair.getSecond();
3414 AdminService.BlockingInterface admin = this.connection.getAdmin(sn);
3415 GetRegionInfoRequest request = RequestConverter.buildGetRegionInfoRequest(
3416 pair.getFirst().getRegionName(), true);
3417 GetRegionInfoResponse response = admin.getRegionInfo(null, request);
3418 switch (response.getCompactionState()) {
3419 case MAJOR_AND_MINOR:
3420 return CompactionState.MAJOR_AND_MINOR;
3421 case MAJOR:
3422 if (state == CompactionState.MINOR) {
3423 return CompactionState.MAJOR_AND_MINOR;
3424 }
3425 state = CompactionState.MAJOR;
3426 break;
3427 case MINOR:
3428 if (state == CompactionState.MAJOR) {
3429 return CompactionState.MAJOR_AND_MINOR;
3430 }
3431 state = CompactionState.MINOR;
3432 break;
3433 case NONE:
3434 default:
3435 }
3436 } catch (NotServingRegionException e) {
3437 if (LOG.isDebugEnabled()) {
3438 LOG.debug("Trying to get compaction state of " +
3439 pair.getFirst() + ": " +
3440 StringUtils.stringifyException(e));
3441 }
3442 } catch (RemoteException e) {
3443 if (e.getMessage().indexOf(NotServingRegionException.class.getName()) >= 0) {
3444 if (LOG.isDebugEnabled()) {
3445 LOG.debug("Trying to get compaction state of " + pair.getFirst() + ": "
3446 + StringUtils.stringifyException(e));
3447 }
3448 } else {
3449 throw e;
3450 }
3451 }
3452 }
3453 } catch (ServiceException se) {
3454 throw ProtobufUtil.getRemoteException(se);
3455 } finally {
3456 zookeeper.close();
3457 }
3458 return state;
3459 }
3460
3461
3462
3463
3464 @Override
3465 public CompactionState getCompactionStateForRegion(final byte[] regionName)
3466 throws IOException {
3467 try {
3468 Pair<HRegionInfo, ServerName> regionServerPair = getRegion(regionName);
3469 if (regionServerPair == null) {
3470 throw new IllegalArgumentException("Invalid region: " + Bytes.toStringBinary(regionName));
3471 }
3472 if (regionServerPair.getSecond() == null) {
3473 throw new NoServerForRegionException(Bytes.toStringBinary(regionName));
3474 }
3475 ServerName sn = regionServerPair.getSecond();
3476 AdminService.BlockingInterface admin = this.connection.getAdmin(sn);
3477 GetRegionInfoRequest request = RequestConverter.buildGetRegionInfoRequest(
3478 regionServerPair.getFirst().getRegionName(), true);
3479 HBaseRpcController controller = rpcControllerFactory.newController();
3480
3481 GetRegionInfoResponse response = admin.getRegionInfo(controller, request);
3482 return response.getCompactionState();
3483 } catch (ServiceException se) {
3484 throw ProtobufUtil.getRemoteException(se);
3485 }
3486 }
3487
3488
3489
3490
3491
3492 @Deprecated
3493 public CompactionState getCompactionState(final String tableNameOrRegionName)
3494 throws IOException, InterruptedException {
3495 return getCompactionState(Bytes.toBytes(tableNameOrRegionName));
3496 }
3497
3498
3499
3500
3501
3502 @Deprecated
3503 public CompactionState getCompactionState(final byte[] tableNameOrRegionName)
3504 throws IOException, InterruptedException {
3505 try {
3506 return getCompactionStateForRegion(tableNameOrRegionName);
3507 } catch (IllegalArgumentException e) {
3508
3509 return getCompactionState(TableName.valueOf(tableNameOrRegionName));
3510 }
3511 }
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529 @Override
3530 public void snapshot(final String snapshotName,
3531 final TableName tableName) throws IOException,
3532 SnapshotCreationException, IllegalArgumentException {
3533 snapshot(snapshotName, tableName, SnapshotDescription.Type.FLUSH);
3534 }
3535
3536 public void snapshot(final String snapshotName,
3537 final String tableName) throws IOException,
3538 SnapshotCreationException, IllegalArgumentException {
3539 snapshot(snapshotName, TableName.valueOf(tableName),
3540 SnapshotDescription.Type.FLUSH);
3541 }
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558 public void snapshot(final byte[] snapshotName, final byte[] tableName,
3559 final SnapshotDescription.Type flushType) throws
3560 IOException, SnapshotCreationException, IllegalArgumentException {
3561 snapshot(Bytes.toString(snapshotName), Bytes.toString(tableName), flushType);
3562 }
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579 @Override
3580 public void snapshot(final byte[] snapshotName,
3581 final TableName tableName) throws IOException,
3582 SnapshotCreationException, IllegalArgumentException {
3583 snapshot(Bytes.toString(snapshotName), tableName, SnapshotDescription.Type.FLUSH);
3584 }
3585
3586 public void snapshot(final byte[] snapshotName,
3587 final byte[] tableName) throws IOException,
3588 SnapshotCreationException, IllegalArgumentException {
3589 snapshot(Bytes.toString(snapshotName), TableName.valueOf(tableName),
3590 SnapshotDescription.Type.FLUSH);
3591 }
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611 @Override
3612 public void snapshot(final String snapshotName,
3613 final TableName tableName,
3614 SnapshotDescription.Type type) throws IOException, SnapshotCreationException,
3615 IllegalArgumentException {
3616 SnapshotDescription.Builder builder = SnapshotDescription.newBuilder();
3617 builder.setTable(tableName.getNameAsString());
3618 builder.setName(snapshotName);
3619 builder.setType(type);
3620 snapshot(builder.build());
3621 }
3622
3623 public void snapshot(final String snapshotName,
3624 final String tableName,
3625 SnapshotDescription.Type type) throws IOException, SnapshotCreationException,
3626 IllegalArgumentException {
3627 snapshot(snapshotName, TableName.valueOf(tableName), type);
3628 }
3629
3630 public void snapshot(final String snapshotName,
3631 final byte[] tableName,
3632 SnapshotDescription.Type type) throws IOException, SnapshotCreationException,
3633 IllegalArgumentException {
3634 snapshot(snapshotName, TableName.valueOf(tableName), type);
3635 }
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658 @Override
3659 public void snapshot(SnapshotDescription snapshot) throws IOException, SnapshotCreationException,
3660 IllegalArgumentException {
3661
3662 SnapshotResponse response = takeSnapshotAsync(snapshot);
3663 final IsSnapshotDoneRequest request = IsSnapshotDoneRequest.newBuilder().setSnapshot(snapshot)
3664 .build();
3665 IsSnapshotDoneResponse done = null;
3666 long start = EnvironmentEdgeManager.currentTime();
3667 long max = response.getExpectedTimeout();
3668 long maxPauseTime = max / this.numRetries;
3669 int tries = 0;
3670 LOG.debug("Waiting a max of " + max + " ms for snapshot '" +
3671 ClientSnapshotDescriptionUtils.toString(snapshot) + "'' to complete. (max " +
3672 maxPauseTime + " ms per retry)");
3673 while (tries == 0
3674 || ((EnvironmentEdgeManager.currentTime() - start) < max && !done.getDone())) {
3675 try {
3676
3677 long sleep = getPauseTime(tries++);
3678 sleep = sleep > maxPauseTime ? maxPauseTime : sleep;
3679 LOG.debug("(#" + tries + ") Sleeping: " + sleep +
3680 "ms while waiting for snapshot completion.");
3681 Thread.sleep(sleep);
3682 } catch (InterruptedException e) {
3683 throw (InterruptedIOException)new InterruptedIOException("Interrupted").initCause(e);
3684 }
3685 LOG.debug("Getting current status of snapshot from master...");
3686 done = executeCallable(new MasterCallable<IsSnapshotDoneResponse>(getConnection()) {
3687 @Override
3688 public IsSnapshotDoneResponse call(int callTimeout) throws ServiceException {
3689 HBaseRpcController controller = rpcControllerFactory.newController();
3690 controller.setCallTimeout(callTimeout);
3691 return master.isSnapshotDone(controller, request);
3692 }
3693 });
3694 }
3695 if (!done.getDone()) {
3696 throw new SnapshotCreationException("Snapshot '" + snapshot.getName()
3697 + "' wasn't completed in expectedTime:" + max + " ms", snapshot);
3698 }
3699 }
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711 @Override
3712 public SnapshotResponse takeSnapshotAsync(SnapshotDescription snapshot) throws IOException,
3713 SnapshotCreationException {
3714 ClientSnapshotDescriptionUtils.assertSnapshotRequestIsValid(snapshot);
3715 final SnapshotRequest request = SnapshotRequest.newBuilder().setSnapshot(snapshot)
3716 .build();
3717
3718 return executeCallable(new MasterCallable<SnapshotResponse>(getConnection()) {
3719 @Override
3720 public SnapshotResponse call(int callTimeout) throws ServiceException {
3721 HBaseRpcController controller = rpcControllerFactory.newController();
3722 controller.setCallTimeout(callTimeout);
3723 return master.snapshot(controller, request);
3724 }
3725 });
3726 }
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748 @Override
3749 public boolean isSnapshotFinished(final SnapshotDescription snapshot)
3750 throws IOException, HBaseSnapshotException, UnknownSnapshotException {
3751
3752 return executeCallable(new MasterCallable<IsSnapshotDoneResponse>(getConnection()) {
3753 @Override
3754 public IsSnapshotDoneResponse call(int callTimeout) throws ServiceException {
3755 HBaseRpcController controller = rpcControllerFactory.newController();
3756 controller.setCallTimeout(callTimeout);
3757 return master.isSnapshotDone(controller,
3758 IsSnapshotDoneRequest.newBuilder().setSnapshot(snapshot).build());
3759 }
3760 }).getDone();
3761 }
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776 @Override
3777 public void restoreSnapshot(final byte[] snapshotName)
3778 throws IOException, RestoreSnapshotException {
3779 restoreSnapshot(Bytes.toString(snapshotName));
3780 }
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795 @Override
3796 public void restoreSnapshot(final String snapshotName)
3797 throws IOException, RestoreSnapshotException {
3798 boolean takeFailSafeSnapshot =
3799 conf.getBoolean("hbase.snapshot.restore.take.failsafe.snapshot", false);
3800 restoreSnapshot(snapshotName, takeFailSafeSnapshot);
3801 }
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819 @Override
3820 public void restoreSnapshot(final byte[] snapshotName, final boolean takeFailSafeSnapshot)
3821 throws IOException, RestoreSnapshotException {
3822 restoreSnapshot(Bytes.toString(snapshotName), takeFailSafeSnapshot);
3823 }
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839 @Override
3840 public void restoreSnapshot(final String snapshotName, boolean takeFailSafeSnapshot, boolean restoreAcl)
3841 throws IOException, RestoreSnapshotException {
3842 TableName tableName = null;
3843 for (SnapshotDescription snapshotInfo: listSnapshots()) {
3844 if (snapshotInfo.getName().equals(snapshotName)) {
3845 tableName = TableName.valueOf(snapshotInfo.getTable());
3846 break;
3847 }
3848 }
3849
3850 if (tableName == null) {
3851 throw new RestoreSnapshotException(
3852 "Unable to find the table name for snapshot=" + snapshotName);
3853 }
3854
3855
3856 if (!tableExists(tableName)) {
3857 cloneSnapshot(snapshotName, tableName, restoreAcl);
3858 return;
3859 }
3860
3861
3862 if (!isTableDisabled(tableName)) {
3863 throw new TableNotDisabledException(tableName);
3864 }
3865
3866
3867 String failSafeSnapshotSnapshotName = null;
3868 if (takeFailSafeSnapshot) {
3869 failSafeSnapshotSnapshotName = conf.get("hbase.snapshot.restore.failsafe.name",
3870 "hbase-failsafe-{snapshot.name}-{restore.timestamp}");
3871 failSafeSnapshotSnapshotName = failSafeSnapshotSnapshotName
3872 .replace("{snapshot.name}", snapshotName)
3873 .replace("{table.name}", tableName.toString().replace(TableName.NAMESPACE_DELIM, '.'))
3874 .replace("{restore.timestamp}", String.valueOf(EnvironmentEdgeManager.currentTime()));
3875 LOG.info("Taking restore-failsafe snapshot: " + failSafeSnapshotSnapshotName);
3876 snapshot(failSafeSnapshotSnapshotName, tableName);
3877 }
3878
3879 try {
3880
3881 internalRestoreSnapshot(snapshotName, tableName, restoreAcl);
3882 } catch (IOException e) {
3883
3884
3885 if (takeFailSafeSnapshot) {
3886 try {
3887 internalRestoreSnapshot(failSafeSnapshotSnapshotName, tableName, restoreAcl);
3888 String msg = "Restore snapshot=" + snapshotName +
3889 " failed. Rollback to snapshot=" + failSafeSnapshotSnapshotName + " succeeded.";
3890 LOG.error(msg, e);
3891 throw new RestoreSnapshotException(msg, e);
3892 } catch (IOException ex) {
3893 String msg = "Failed to restore and rollback to snapshot=" + failSafeSnapshotSnapshotName;
3894 LOG.error(msg, ex);
3895 throw new RestoreSnapshotException(msg, e);
3896 }
3897 } else {
3898 throw new RestoreSnapshotException("Failed to restore snapshot=" + snapshotName, e);
3899 }
3900 }
3901
3902
3903 if (takeFailSafeSnapshot) {
3904 try {
3905 LOG.info("Deleting restore-failsafe snapshot: " + failSafeSnapshotSnapshotName);
3906 deleteSnapshot(failSafeSnapshotSnapshotName);
3907 } catch (IOException e) {
3908 LOG.error("Unable to remove the failsafe snapshot: " + failSafeSnapshotSnapshotName, e);
3909 }
3910 }
3911 }
3912
3913 @Override
3914 public void restoreSnapshot(String snapshotName, boolean takeFailSafeSnapshot)
3915 throws IOException, RestoreSnapshotException {
3916 restoreSnapshot(snapshotName, takeFailSafeSnapshot, false);
3917 }
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929 public void cloneSnapshot(final byte[] snapshotName, final byte[] tableName)
3930 throws IOException, TableExistsException, RestoreSnapshotException {
3931 cloneSnapshot(Bytes.toString(snapshotName), TableName.valueOf(tableName));
3932 }
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944 @Override
3945 public void cloneSnapshot(final byte[] snapshotName, final TableName tableName)
3946 throws IOException, TableExistsException, RestoreSnapshotException {
3947 cloneSnapshot(Bytes.toString(snapshotName), tableName);
3948 }
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962 public void cloneSnapshot(final String snapshotName, final String tableName)
3963 throws IOException, TableExistsException, RestoreSnapshotException, InterruptedException {
3964 cloneSnapshot(snapshotName, TableName.valueOf(tableName));
3965 }
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977 @Override
3978 public void cloneSnapshot(final String snapshotName, final TableName tableName,
3979 final boolean restoreAcl) throws IOException, TableExistsException, RestoreSnapshotException {
3980 if (tableExists(tableName)) {
3981 throw new TableExistsException(tableName);
3982 }
3983 internalRestoreSnapshot(snapshotName, tableName, restoreAcl);
3984 waitUntilTableIsEnabled(tableName);
3985 }
3986
3987 @Override
3988 public void cloneSnapshot(String snapshotName, TableName tableName)
3989 throws IOException, TableExistsException, RestoreSnapshotException {
3990 cloneSnapshot(snapshotName, tableName, false);
3991 }
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004 @Override
4005 public byte[] execProcedureWithRet(String signature, String instance,
4006 Map<String, String> props) throws IOException {
4007 ProcedureDescription.Builder builder = ProcedureDescription.newBuilder();
4008 builder.setSignature(signature).setInstance(instance);
4009 for (Entry<String, String> entry : props.entrySet()) {
4010 NameStringPair pair = NameStringPair.newBuilder().setName(entry.getKey())
4011 .setValue(entry.getValue()).build();
4012 builder.addConfiguration(pair);
4013 }
4014
4015 final ExecProcedureRequest request = ExecProcedureRequest.newBuilder()
4016 .setProcedure(builder.build()).build();
4017
4018 ExecProcedureResponse response = executeCallable(new MasterCallable<ExecProcedureResponse>(
4019 getConnection()) {
4020 @Override
4021 public ExecProcedureResponse call(int callTimeout) throws ServiceException {
4022 HBaseRpcController controller = rpcControllerFactory.newController();
4023 controller.setCallTimeout(callTimeout);
4024 return master.execProcedureWithRet(controller, request);
4025 }
4026 });
4027
4028 return response.hasReturnData() ? response.getReturnData().toByteArray() : null;
4029 }
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040 @Override
4041 public void execProcedure(String signature, String instance,
4042 Map<String, String> props) throws IOException {
4043 ProcedureDescription.Builder builder = ProcedureDescription.newBuilder();
4044 builder.setSignature(signature).setInstance(instance);
4045 for (Entry<String, String> entry : props.entrySet()) {
4046 NameStringPair pair = NameStringPair.newBuilder().setName(entry.getKey())
4047 .setValue(entry.getValue()).build();
4048 builder.addConfiguration(pair);
4049 }
4050
4051 final ExecProcedureRequest request = ExecProcedureRequest.newBuilder()
4052 .setProcedure(builder.build()).build();
4053
4054 ExecProcedureResponse response = executeCallable(new MasterCallable<ExecProcedureResponse>(
4055 getConnection()) {
4056 @Override
4057 public ExecProcedureResponse call(int callTimeout) throws ServiceException {
4058 HBaseRpcController controller = rpcControllerFactory.newController();
4059 controller.setCallTimeout(callTimeout);
4060 return master.execProcedure(controller, request);
4061 }
4062 });
4063
4064 long start = EnvironmentEdgeManager.currentTime();
4065 long max = response.getExpectedTimeout();
4066 long maxPauseTime = max / this.numRetries;
4067 int tries = 0;
4068 LOG.debug("Waiting a max of " + max + " ms for procedure '" +
4069 signature + " : " + instance + "'' to complete. (max " + maxPauseTime + " ms per retry)");
4070 boolean done = false;
4071 while (tries == 0
4072 || ((EnvironmentEdgeManager.currentTime() - start) < max && !done)) {
4073 try {
4074
4075 long sleep = getPauseTime(tries++);
4076 sleep = sleep > maxPauseTime ? maxPauseTime : sleep;
4077 LOG.debug("(#" + tries + ") Sleeping: " + sleep +
4078 "ms while waiting for procedure completion.");
4079 Thread.sleep(sleep);
4080 } catch (InterruptedException e) {
4081 throw (InterruptedIOException)new InterruptedIOException("Interrupted").initCause(e);
4082 }
4083 LOG.debug("Getting current status of procedure from master...");
4084 done = isProcedureFinished(signature, instance, props);
4085 }
4086 if (!done) {
4087 throw new IOException("Procedure '" + signature + " : " + instance
4088 + "' wasn't completed in expectedTime:" + max + " ms");
4089 }
4090 }
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109 @Override
4110 public boolean isProcedureFinished(String signature, String instance, Map<String, String> props)
4111 throws IOException {
4112 final ProcedureDescription.Builder builder = ProcedureDescription.newBuilder();
4113 builder.setSignature(signature).setInstance(instance);
4114 for (Entry<String, String> entry : props.entrySet()) {
4115 NameStringPair pair = NameStringPair.newBuilder().setName(entry.getKey())
4116 .setValue(entry.getValue()).build();
4117 builder.addConfiguration(pair);
4118 }
4119 final ProcedureDescription desc = builder.build();
4120 return executeCallable(
4121 new MasterCallable<IsProcedureDoneResponse>(getConnection()) {
4122 @Override
4123 public IsProcedureDoneResponse call(int callTimeout) throws ServiceException {
4124 HBaseRpcController controller = rpcControllerFactory.newController();
4125 controller.setCallTimeout(callTimeout);
4126 return master.isProcedureDone(controller, IsProcedureDoneRequest
4127 .newBuilder().setProcedure(desc).build());
4128 }
4129 }).getDone();
4130 }
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142 private void internalRestoreSnapshot(final String snapshotName, final TableName tableName,
4143 final boolean restoreAcl)
4144 throws IOException, RestoreSnapshotException {
4145 SnapshotDescription snapshot = SnapshotDescription.newBuilder()
4146 .setName(snapshotName).setTable(tableName.getNameAsString()).build();
4147
4148
4149 internalRestoreSnapshotAsync(snapshot, restoreAcl);
4150
4151 final IsRestoreSnapshotDoneRequest request = IsRestoreSnapshotDoneRequest.newBuilder()
4152 .setSnapshot(snapshot).build();
4153 IsRestoreSnapshotDoneResponse done = IsRestoreSnapshotDoneResponse.newBuilder()
4154 .setDone(false).buildPartial();
4155 final long maxPauseTime = 5000;
4156 int tries = 0;
4157 while (!done.getDone()) {
4158 try {
4159
4160 long sleep = getPauseTime(tries++);
4161 sleep = sleep > maxPauseTime ? maxPauseTime : sleep;
4162 LOG.debug(tries + ") Sleeping: " + sleep + " ms while we wait for snapshot restore to complete.");
4163 Thread.sleep(sleep);
4164 } catch (InterruptedException e) {
4165 throw (InterruptedIOException)new InterruptedIOException("Interrupted").initCause(e);
4166 }
4167 LOG.debug("Getting current status of snapshot restore from master...");
4168 done = executeCallable(new MasterCallable<IsRestoreSnapshotDoneResponse>(
4169 getConnection()) {
4170 @Override
4171 public IsRestoreSnapshotDoneResponse call(int callTimeout) throws ServiceException {
4172 HBaseRpcController controller = rpcControllerFactory.newController();
4173 controller.setCallTimeout(callTimeout);
4174 return master.isRestoreSnapshotDone(controller, request);
4175 }
4176 });
4177 }
4178 if (!done.getDone()) {
4179 throw new RestoreSnapshotException("Snapshot '" + snapshot.getName() + "' wasn't restored.");
4180 }
4181 }
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193 private RestoreSnapshotResponse internalRestoreSnapshotAsync(final SnapshotDescription snapshot,
4194 final boolean restoreAcl) throws IOException, RestoreSnapshotException {
4195 ClientSnapshotDescriptionUtils.assertSnapshotRequestIsValid(snapshot);
4196
4197 final RestoreSnapshotRequest request =
4198 RestoreSnapshotRequest.newBuilder().setSnapshot(snapshot).setRestoreACL(restoreAcl).build();
4199
4200
4201 return executeCallable(new MasterCallable<RestoreSnapshotResponse>(getConnection()) {
4202 @Override
4203 public RestoreSnapshotResponse call(int callTimeout) throws ServiceException {
4204 HBaseRpcController controller = rpcControllerFactory.newController();
4205 controller.setCallTimeout(callTimeout);
4206 return master.restoreSnapshot(controller, request);
4207 }
4208 });
4209 }
4210
4211
4212
4213
4214
4215
4216 @Override
4217 public List<SnapshotDescription> listSnapshots() throws IOException {
4218 return executeCallable(new MasterCallable<List<SnapshotDescription>>(getConnection()) {
4219 @Override
4220 public List<SnapshotDescription> call(int callTimeout) throws ServiceException {
4221 HBaseRpcController controller = rpcControllerFactory.newController();
4222 controller.setCallTimeout(callTimeout);
4223 return master.getCompletedSnapshots(controller,
4224 GetCompletedSnapshotsRequest.newBuilder().build()).getSnapshotsList();
4225 }
4226 });
4227 }
4228
4229
4230
4231
4232
4233
4234
4235
4236 @Override
4237 public List<SnapshotDescription> listSnapshots(String regex) throws IOException {
4238 return listSnapshots(Pattern.compile(regex));
4239 }
4240
4241
4242
4243
4244
4245
4246
4247
4248 @Override
4249 public List<SnapshotDescription> listSnapshots(Pattern pattern) throws IOException {
4250 List<SnapshotDescription> matched = new LinkedList<SnapshotDescription>();
4251 List<SnapshotDescription> snapshots = listSnapshots();
4252 for (SnapshotDescription snapshot : snapshots) {
4253 if (pattern.matcher(snapshot.getName()).matches()) {
4254 matched.add(snapshot);
4255 }
4256 }
4257 return matched;
4258 }
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268 @Override
4269 public List<SnapshotDescription> listTableSnapshots(String tableNameRegex,
4270 String snapshotNameRegex) throws IOException {
4271 return listTableSnapshots(Pattern.compile(tableNameRegex), Pattern.compile(snapshotNameRegex));
4272 }
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282 @Override
4283 public List<SnapshotDescription> listTableSnapshots(Pattern tableNamePattern,
4284 Pattern snapshotNamePattern) throws IOException {
4285 TableName[] tableNames = listTableNames(tableNamePattern);
4286
4287 List<SnapshotDescription> tableSnapshots = new LinkedList<SnapshotDescription>();
4288 List<SnapshotDescription> snapshots = listSnapshots(snapshotNamePattern);
4289
4290 List<TableName> listOfTableNames = Arrays.asList(tableNames);
4291 for (SnapshotDescription snapshot : snapshots) {
4292 if (listOfTableNames.contains(TableName.valueOf(snapshot.getTable()))) {
4293 tableSnapshots.add(snapshot);
4294 }
4295 }
4296 return tableSnapshots;
4297 }
4298
4299
4300
4301
4302
4303
4304 @Override
4305 public void deleteSnapshot(final byte[] snapshotName) throws IOException {
4306 deleteSnapshot(Bytes.toString(snapshotName));
4307 }
4308
4309
4310
4311
4312
4313
4314 @Override
4315 public void deleteSnapshot(final String snapshotName) throws IOException {
4316
4317 TableName.isLegalFullyQualifiedTableName(Bytes.toBytes(snapshotName));
4318
4319 executeCallable(new MasterCallable<Void>(getConnection()) {
4320 @Override
4321 public Void call(int callTimeout) throws ServiceException {
4322 HBaseRpcController controller = rpcControllerFactory.newController();
4323 controller.setCallTimeout(callTimeout);
4324 master.deleteSnapshot(controller,
4325 DeleteSnapshotRequest.newBuilder().
4326 setSnapshot(SnapshotDescription.newBuilder().setName(snapshotName).build()).build()
4327 );
4328 return null;
4329 }
4330 });
4331 }
4332
4333
4334
4335
4336
4337
4338 @Override
4339 public void deleteSnapshots(final String regex) throws IOException {
4340 deleteSnapshots(Pattern.compile(regex));
4341 }
4342
4343
4344
4345
4346
4347
4348 @Override
4349 public void deleteSnapshots(final Pattern pattern) throws IOException {
4350 List<SnapshotDescription> snapshots = listSnapshots(pattern);
4351 for (final SnapshotDescription snapshot : snapshots) {
4352 try {
4353 internalDeleteSnapshot(snapshot);
4354 } catch (IOException ex) {
4355 LOG.info(
4356 "Failed to delete snapshot " + snapshot.getName() + " for table " + snapshot.getTable(),
4357 ex);
4358 }
4359 }
4360 }
4361
4362 private void internalDeleteSnapshot(final SnapshotDescription snapshot) throws IOException {
4363 executeCallable(new MasterCallable<Void>(getConnection()) {
4364 @Override
4365 public Void call(int callTimeout) throws ServiceException {
4366 HBaseRpcController controller = rpcControllerFactory.newController();
4367 controller.setCallTimeout(callTimeout);
4368 this.master.deleteSnapshot(controller, DeleteSnapshotRequest.newBuilder()
4369 .setSnapshot(snapshot).build());
4370 return null;
4371 }
4372 });
4373 }
4374
4375
4376
4377
4378
4379
4380
4381
4382 @Override
4383 public void deleteTableSnapshots(String tableNameRegex, String snapshotNameRegex)
4384 throws IOException {
4385 deleteTableSnapshots(Pattern.compile(tableNameRegex), Pattern.compile(snapshotNameRegex));
4386 }
4387
4388
4389
4390
4391
4392
4393
4394
4395 @Override
4396 public void deleteTableSnapshots(Pattern tableNamePattern, Pattern snapshotNamePattern)
4397 throws IOException {
4398 List<SnapshotDescription> snapshots = listTableSnapshots(tableNamePattern, snapshotNamePattern);
4399 for (SnapshotDescription snapshot : snapshots) {
4400 try {
4401 internalDeleteSnapshot(snapshot);
4402 LOG.debug("Successfully deleted snapshot: " + snapshot.getName());
4403 } catch (IOException e) {
4404 LOG.error("Failed to delete snapshot: " + snapshot.getName(), e);
4405 }
4406 }
4407 }
4408
4409
4410
4411
4412
4413
4414 @Override
4415 public void setQuota(final QuotaSettings quota) throws IOException {
4416 executeCallable(new MasterCallable<Void>(getConnection()) {
4417 @Override
4418 public Void call(int callTimeout) throws ServiceException {
4419 HBaseRpcController controller = rpcControllerFactory.newController();
4420 controller.setCallTimeout(callTimeout);
4421 this.master.setQuota(controller, QuotaSettings.buildSetQuotaRequestProto(quota));
4422 return null;
4423 }
4424 });
4425 }
4426
4427
4428
4429
4430
4431
4432
4433 @Override
4434 public QuotaRetriever getQuotaRetriever(final QuotaFilter filter) throws IOException {
4435 return QuotaRetriever.open(conf, filter);
4436 }
4437
4438 private <V> V executeCallable(MasterCallable<V> callable) throws IOException {
4439 return executeCallable(callable, rpcCallerFactory, operationTimeout, rpcTimeout);
4440 }
4441
4442 private static <V> V executeCallable(MasterCallable<V> callable,
4443 RpcRetryingCallerFactory rpcCallerFactory, int operationTimeout, int rpcTimeout)
4444 throws IOException {
4445 RpcRetryingCaller<V> caller = rpcCallerFactory.newCaller(rpcTimeout);
4446 try {
4447 return caller.callWithRetries(callable, operationTimeout);
4448 } finally {
4449 callable.close();
4450 }
4451 }
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474 @Override
4475 public CoprocessorRpcChannel coprocessorService() {
4476 return new MasterCoprocessorRpcChannel(connection);
4477 }
4478
4479
4480
4481
4482 private static class ThrowableAbortable implements Abortable {
4483
4484 @Override
4485 public void abort(String why, Throwable e) {
4486 throw new RuntimeException(why, e);
4487 }
4488
4489 @Override
4490 public boolean isAborted() {
4491 return true;
4492 }
4493 }
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517 @Override
4518 public CoprocessorRpcChannel coprocessorService(ServerName sn) {
4519 return new RegionServerCoprocessorRpcChannel(connection, sn);
4520 }
4521
4522 @Override
4523 public void updateConfiguration(ServerName server) throws IOException {
4524 try {
4525 this.connection.getAdmin(server).updateConfiguration(null,
4526 UpdateConfigurationRequest.getDefaultInstance());
4527 } catch (ServiceException e) {
4528 throw ProtobufUtil.getRemoteException(e);
4529 }
4530 }
4531
4532 @Override
4533 public void updateConfiguration() throws IOException {
4534 for (ServerName server : this.getClusterStatus().getServers()) {
4535 updateConfiguration(server);
4536 }
4537
4538 updateConfiguration(this.getClusterStatus().getMaster());
4539
4540 for (ServerName server : this.getClusterStatus().getBackupMasters()) {
4541 updateConfiguration(server);
4542 }
4543 }
4544
4545 @Override
4546 public int getMasterInfoPort() throws IOException {
4547
4548 ConnectionManager.HConnectionImplementation connection =
4549 (ConnectionManager.HConnectionImplementation)this.connection;
4550 ZooKeeperKeepAliveConnection zkw = connection.getKeepAliveZooKeeperWatcher();
4551 try {
4552 return MasterAddressTracker.getMasterInfoPort(zkw);
4553 } catch (KeeperException e) {
4554 throw new IOException("Failed to get master info port from MasterAddressTracker", e);
4555 }
4556 }
4557
4558 @Override
4559 public long getLastMajorCompactionTimestamp(final TableName tableName) throws IOException {
4560 return executeCallable(new MasterCallable<Long>(getConnection()) {
4561 @Override
4562 public Long call(int callTimeout) throws ServiceException {
4563 HBaseRpcController controller = rpcControllerFactory.newController();
4564 controller.setCallTimeout(callTimeout);
4565 MajorCompactionTimestampRequest req =
4566 MajorCompactionTimestampRequest.newBuilder()
4567 .setTableName(ProtobufUtil.toProtoTableName(tableName)).build();
4568 return master.getLastMajorCompactionTimestamp(controller, req).getCompactionTimestamp();
4569 }
4570 });
4571 }
4572
4573 @Override
4574 public long getLastMajorCompactionTimestampForRegion(final byte[] regionName) throws IOException {
4575 return executeCallable(new MasterCallable<Long>(getConnection()) {
4576 @Override
4577 public Long call(int callTimeout) throws ServiceException {
4578 HBaseRpcController controller = rpcControllerFactory.newController();
4579 controller.setCallTimeout(callTimeout);
4580 MajorCompactionTimestampForRegionRequest req =
4581 MajorCompactionTimestampForRegionRequest
4582 .newBuilder()
4583 .setRegion(
4584 RequestConverter
4585 .buildRegionSpecifier(RegionSpecifierType.REGION_NAME, regionName)).build();
4586 return master.getLastMajorCompactionTimestampForRegion(controller, req)
4587 .getCompactionTimestamp();
4588 }
4589 });
4590 }
4591
4592
4593
4594
4595
4596
4597 @InterfaceAudience.Private
4598 @InterfaceStability.Evolving
4599 protected static class ProcedureFuture<V> implements Future<V> {
4600 private ExecutionException exception = null;
4601 private boolean procResultFound = false;
4602 private boolean done = false;
4603 private boolean cancelled = false;
4604 private boolean waitForOpResult = false;
4605 private V result = null;
4606
4607 private final HBaseAdmin admin;
4608 private final Long procId;
4609
4610 public ProcedureFuture(final HBaseAdmin admin, final Long procId) {
4611 this.admin = admin;
4612 this.procId = procId;
4613 }
4614
4615 public ProcedureFuture(final HBaseAdmin admin, final Long procId,
4616 final boolean waitForOpResult) {
4617 this.admin = admin;
4618 this.procId = procId;
4619 this.waitForOpResult = waitForOpResult;
4620 }
4621
4622 @Override
4623 public boolean cancel(boolean mayInterruptIfRunning) {
4624 AbortProcedureRequest abortProcRequest = AbortProcedureRequest.newBuilder()
4625 .setProcId(procId).setMayInterruptIfRunning(mayInterruptIfRunning).build();
4626 try {
4627 cancelled = abortProcedureResult(abortProcRequest).getIsProcedureAborted();
4628 if (cancelled) {
4629 done = true;
4630 }
4631 } catch (IOException e) {
4632
4633
4634
4635 LOG.warn(
4636 "Cancelling the procedure with procId=" + procId + " throws exception " + e.getMessage(),
4637 e);
4638 cancelled = false;
4639 }
4640 return cancelled;
4641 }
4642
4643 @Override
4644 public boolean isCancelled() {
4645 return cancelled;
4646 }
4647
4648 protected AbortProcedureResponse abortProcedureResult(
4649 final AbortProcedureRequest request) throws IOException {
4650 return admin.executeCallable(new MasterCallable<AbortProcedureResponse>(
4651 admin.getConnection()) {
4652 @Override
4653 public AbortProcedureResponse call(int callTimeout) throws ServiceException {
4654 HBaseRpcController controller = admin.getRpcControllerFactory().newController();
4655 controller.setCallTimeout(callTimeout);
4656 return master.abortProcedure(controller, request);
4657 }
4658 });
4659 }
4660
4661 @Override
4662 public V get() throws InterruptedException, ExecutionException {
4663
4664 throw new UnsupportedOperationException();
4665 }
4666
4667 @Override
4668 public V get(long timeout, TimeUnit unit)
4669 throws InterruptedException, ExecutionException, TimeoutException {
4670 if (!done) {
4671 long deadlineTs = EnvironmentEdgeManager.currentTime() + unit.toMillis(timeout);
4672 try {
4673 try {
4674
4675 if (procId != null) {
4676 result = waitProcedureResult(procId, deadlineTs);
4677 }
4678
4679 if (!procResultFound || waitForOpResult) {
4680 result = waitOperationResult(deadlineTs);
4681 }
4682 result = postOperationResult(result, deadlineTs);
4683 done = true;
4684 } catch (IOException e) {
4685 result = postOpeartionFailure(e, deadlineTs);
4686 done = true;
4687 }
4688 } catch (IOException e) {
4689 exception = new ExecutionException(e);
4690 done = true;
4691 }
4692 }
4693 if (exception != null) {
4694 throw exception;
4695 }
4696 return result;
4697 }
4698
4699 @Override
4700 public boolean isDone() {
4701 return done;
4702 }
4703
4704 protected HBaseAdmin getAdmin() {
4705 return admin;
4706 }
4707
4708 private V waitProcedureResult(long procId, long deadlineTs)
4709 throws IOException, TimeoutException, InterruptedException {
4710 GetProcedureResultRequest request = GetProcedureResultRequest.newBuilder()
4711 .setProcId(procId)
4712 .build();
4713
4714 int tries = 0;
4715 IOException serviceEx = null;
4716 while (EnvironmentEdgeManager.currentTime() < deadlineTs) {
4717 GetProcedureResultResponse response = null;
4718 try {
4719
4720 response = getProcedureResult(request);
4721 } catch (IOException e) {
4722 serviceEx = unwrapException(e);
4723
4724
4725 LOG.warn("failed to get the procedure result procId=" + procId, serviceEx);
4726
4727
4728 if (serviceEx instanceof DoNotRetryIOException ||
4729 serviceEx instanceof NeedUnmanagedConnectionException) {
4730
4731
4732
4733
4734 LOG.warn("Proc-v2 is unsupported on this master: " + serviceEx.getMessage(), serviceEx);
4735 procResultFound = false;
4736 waitForOpResult = false;
4737 return null;
4738 }
4739 }
4740
4741
4742 if (response != null && response.getState() != GetProcedureResultResponse.State.RUNNING) {
4743 procResultFound = response.getState() != GetProcedureResultResponse.State.NOT_FOUND;
4744 return convertResult(response);
4745 }
4746
4747 try {
4748 Thread.sleep(getAdmin().getPauseTime(tries++));
4749 } catch (InterruptedException e) {
4750 throw new InterruptedException(
4751 "Interrupted while waiting for the result of proc " + procId);
4752 }
4753 }
4754 if (serviceEx != null) {
4755 throw serviceEx;
4756 } else {
4757 throw new TimeoutException("The procedure " + procId + " is still running");
4758 }
4759 }
4760
4761 private static IOException unwrapException(IOException e) {
4762 if (e instanceof RemoteException) {
4763 return ((RemoteException)e).unwrapRemoteException();
4764 }
4765 return e;
4766 }
4767
4768 protected GetProcedureResultResponse getProcedureResult(final GetProcedureResultRequest request)
4769 throws IOException {
4770 return admin.executeCallable(new MasterCallable<GetProcedureResultResponse>(
4771 admin.getConnection()) {
4772 @Override
4773 public GetProcedureResultResponse call(int callTimeout) throws ServiceException {
4774 return master.getProcedureResult(null, request);
4775 }
4776 });
4777 }
4778
4779
4780
4781
4782
4783
4784 protected V convertResult(final GetProcedureResultResponse response) throws IOException {
4785 if (response.hasException()) {
4786 throw ForeignExceptionUtil.toIOException(response.getException());
4787 }
4788 return null;
4789 }
4790
4791
4792
4793
4794
4795
4796
4797 protected V waitOperationResult(final long deadlineTs)
4798 throws IOException, TimeoutException {
4799 return null;
4800 }
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810 protected V postOperationResult(final V result, final long deadlineTs)
4811 throws IOException, TimeoutException {
4812 return result;
4813 }
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824 protected V postOpeartionFailure(final IOException exception, final long deadlineTs)
4825 throws IOException, TimeoutException {
4826 throw exception;
4827 }
4828
4829 protected interface WaitForStateCallable {
4830 boolean checkState(int tries) throws IOException;
4831 void throwInterruptedException() throws InterruptedIOException;
4832 void throwTimeoutException(long elapsed) throws TimeoutException;
4833 }
4834
4835 protected void waitForState(final long deadlineTs, final WaitForStateCallable callable)
4836 throws IOException, TimeoutException {
4837 int tries = 0;
4838 IOException serverEx = null;
4839 long startTime = EnvironmentEdgeManager.currentTime();
4840 while (EnvironmentEdgeManager.currentTime() < deadlineTs) {
4841 serverEx = null;
4842 try {
4843 if (callable.checkState(tries)) {
4844 return;
4845 }
4846 } catch (IOException e) {
4847 serverEx = e;
4848 }
4849 try {
4850 Thread.sleep(getAdmin().getPauseTime(tries++));
4851 } catch (InterruptedException e) {
4852 callable.throwInterruptedException();
4853 }
4854 }
4855 if (serverEx != null) {
4856 throw unwrapException(serverEx);
4857 } else {
4858 callable.throwTimeoutException(EnvironmentEdgeManager.currentTime() - startTime);
4859 }
4860 }
4861 }
4862
4863 @Override
4864 public List<SecurityCapability> getSecurityCapabilities() throws IOException {
4865 try {
4866 return executeCallable(new MasterCallable<List<SecurityCapability>>(getConnection()) {
4867 @Override
4868 public List<SecurityCapability> call(int callTimeout) throws ServiceException {
4869 HBaseRpcController controller = rpcControllerFactory.newController();
4870 controller.setCallTimeout(callTimeout);
4871 SecurityCapabilitiesRequest req = SecurityCapabilitiesRequest.newBuilder().build();
4872 return ProtobufUtil.toSecurityCapabilityList(
4873 master.getSecurityCapabilities(controller, req).getCapabilitiesList());
4874 }
4875 });
4876 } catch (IOException e) {
4877 if (e instanceof RemoteException) {
4878 e = ((RemoteException)e).unwrapRemoteException();
4879 }
4880 throw e;
4881 }
4882 }
4883
4884 @Override
4885 public boolean[] setSplitOrMergeEnabled(final boolean enabled, final boolean synchronous,
4886 final MasterSwitchType... switchTypes)
4887 throws IOException {
4888 return executeCallable(new MasterCallable<boolean[]>(getConnection()) {
4889 @Override
4890 public boolean[] call(int callTimeout) throws ServiceException {
4891 MasterProtos.SetSplitOrMergeEnabledResponse response = master.setSplitOrMergeEnabled(null,
4892 RequestConverter.buildSetSplitOrMergeEnabledRequest(enabled, synchronous, switchTypes));
4893 boolean[] result = new boolean[switchTypes.length];
4894 int i = 0;
4895 for (Boolean prevValue : response.getPrevValueList()) {
4896 result[i++] = prevValue;
4897 }
4898 return result;
4899 }
4900 });
4901 }
4902
4903 @Override
4904 public boolean isSplitOrMergeEnabled(final MasterSwitchType switchType) throws IOException {
4905 return executeCallable(new MasterCallable<Boolean>(getConnection()) {
4906 @Override
4907 public Boolean call(int callTimeout) throws ServiceException {
4908 return master.isSplitOrMergeEnabled(null,
4909 RequestConverter.buildIsSplitOrMergeEnabledRequest(switchType)).getEnabled();
4910 }
4911 });
4912 }
4913
4914 @Override
4915 public List<ServerName> listDeadServers() throws IOException {
4916 return new ArrayList<>(getClusterStatus().getDeadServerNames());
4917 }
4918
4919 @Override
4920 public List<ServerName> clearDeadServers(final List<ServerName> servers) throws IOException {
4921 if (servers == null || servers.size() == 0) {
4922 throw new IllegalArgumentException("servers cannot be null or empty");
4923 }
4924 return executeCallable(new MasterCallable<List<ServerName>>(getConnection()) {
4925 @Override
4926 public List<ServerName> call(int callTimeout) throws Exception {
4927 ClearDeadServersRequest req = RequestConverter.buildClearDeadServersRequest(servers);
4928 return ProtobufUtil.toServerNameList(
4929 master.clearDeadServers(null, req).getServerNameList());
4930 }
4931 });
4932 }
4933
4934
4935 private RpcControllerFactory getRpcControllerFactory() {
4936 return rpcControllerFactory;
4937 }
4938 }