001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase; 019 020import static org.apache.hadoop.hbase.ChoreService.CHORE_SERVICE_INITIAL_POOL_SIZE; 021import static org.apache.hadoop.hbase.ChoreService.DEFAULT_CHORE_SERVICE_INITIAL_POOL_SIZE; 022import static org.apache.hadoop.hbase.HConstants.DEFAULT_HBASE_SPLIT_COORDINATED_BY_ZK; 023import static org.apache.hadoop.hbase.HConstants.HBASE_SPLIT_WAL_COORDINATED_BY_ZK; 024 025import com.google.errorprone.annotations.RestrictedApi; 026import io.opentelemetry.api.trace.Span; 027import io.opentelemetry.api.trace.StatusCode; 028import io.opentelemetry.context.Scope; 029import java.io.IOException; 030import java.lang.management.MemoryType; 031import java.net.BindException; 032import java.net.InetAddress; 033import java.net.InetSocketAddress; 034import java.util.concurrent.atomic.AtomicBoolean; 035import javax.servlet.http.HttpServlet; 036import org.apache.commons.lang3.StringUtils; 037import org.apache.commons.lang3.SystemUtils; 038import org.apache.hadoop.conf.Configuration; 039import org.apache.hadoop.fs.FileSystem; 040import org.apache.hadoop.fs.Path; 041import org.apache.hadoop.hbase.client.AsyncClusterConnection; 042import org.apache.hadoop.hbase.client.ClusterConnectionFactory; 043import org.apache.hadoop.hbase.client.Connection; 044import org.apache.hadoop.hbase.client.ConnectionFactory; 045import org.apache.hadoop.hbase.client.ConnectionRegistryEndpoint; 046import org.apache.hadoop.hbase.conf.ConfigurationManager; 047import org.apache.hadoop.hbase.conf.ConfigurationObserver; 048import org.apache.hadoop.hbase.coordination.ZkCoordinatedStateManager; 049import org.apache.hadoop.hbase.coprocessor.CoprocessorHost; 050import org.apache.hadoop.hbase.executor.ExecutorService; 051import org.apache.hadoop.hbase.fs.HFileSystem; 052import org.apache.hadoop.hbase.http.InfoServer; 053import org.apache.hadoop.hbase.io.util.MemorySizeUtil; 054import org.apache.hadoop.hbase.ipc.RpcServerInterface; 055import org.apache.hadoop.hbase.master.HMaster; 056import org.apache.hadoop.hbase.master.MasterCoprocessorHost; 057import org.apache.hadoop.hbase.namequeues.NamedQueueRecorder; 058import org.apache.hadoop.hbase.regionserver.ChunkCreator; 059import org.apache.hadoop.hbase.regionserver.HeapMemoryManager; 060import org.apache.hadoop.hbase.regionserver.MemStoreLAB; 061import org.apache.hadoop.hbase.regionserver.RegionServerCoprocessorHost; 062import org.apache.hadoop.hbase.regionserver.ShutdownHook; 063import org.apache.hadoop.hbase.security.Superusers; 064import org.apache.hadoop.hbase.security.User; 065import org.apache.hadoop.hbase.security.UserProvider; 066import org.apache.hadoop.hbase.security.access.AccessChecker; 067import org.apache.hadoop.hbase.security.access.ZKPermissionWatcher; 068import org.apache.hadoop.hbase.trace.TraceUtil; 069import org.apache.hadoop.hbase.unsafe.HBasePlatformDependent; 070import org.apache.hadoop.hbase.util.Addressing; 071import org.apache.hadoop.hbase.util.CommonFSUtils; 072import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 073import org.apache.hadoop.hbase.util.FSTableDescriptors; 074import org.apache.hadoop.hbase.util.NettyEventLoopGroupConfig; 075import org.apache.hadoop.hbase.util.Pair; 076import org.apache.hadoop.hbase.util.Sleeper; 077import org.apache.hadoop.hbase.zookeeper.ClusterStatusTracker; 078import org.apache.hadoop.hbase.zookeeper.ZKAuthentication; 079import org.apache.hadoop.hbase.zookeeper.ZKWatcher; 080import org.apache.yetus.audience.InterfaceAudience; 081import org.slf4j.Logger; 082import org.slf4j.LoggerFactory; 083 084/** 085 * Base class for hbase services, such as master or region server. 086 */ 087@InterfaceAudience.Private 088public abstract class HBaseServerBase<R extends HBaseRpcServicesBase<?>> extends Thread 089 implements Server, ConfigurationObserver, ConnectionRegistryEndpoint { 090 091 private static final Logger LOG = LoggerFactory.getLogger(HBaseServerBase.class); 092 093 protected final Configuration conf; 094 095 // Go down hard. Used if file system becomes unavailable and also in 096 // debugging and unit tests. 097 protected final AtomicBoolean abortRequested = new AtomicBoolean(false); 098 099 // Set when a report to the master comes back with a message asking us to 100 // shutdown. Also set by call to stop when debugging or running unit tests 101 // of HRegionServer in isolation. 102 protected volatile boolean stopped = false; 103 104 // Only for testing 105 private boolean isShutdownHookInstalled = false; 106 107 /** 108 * This servers startcode. 109 */ 110 protected final long startcode; 111 112 protected final UserProvider userProvider; 113 114 // zookeeper connection and watcher 115 protected final ZKWatcher zooKeeper; 116 117 /** 118 * The server name the Master sees us as. Its made from the hostname the master passes us, port, 119 * and server startcode. Gets set after registration against Master. 120 */ 121 protected ServerName serverName; 122 123 protected final R rpcServices; 124 125 /** 126 * hostname specified by hostname config 127 */ 128 protected final String useThisHostnameInstead; 129 130 /** 131 * Provide online slow log responses from ringbuffer 132 */ 133 protected final NamedQueueRecorder namedQueueRecorder; 134 135 /** 136 * Configuration manager is used to register/deregister and notify the configuration observers 137 * when the regionserver is notified that there was a change in the on disk configs. 138 */ 139 protected final ConfigurationManager configurationManager; 140 141 /** 142 * ChoreService used to schedule tasks that we want to run periodically 143 */ 144 protected final ChoreService choreService; 145 146 // Instance of the hbase executor executorService. 147 protected final ExecutorService executorService; 148 149 // Cluster Status Tracker 150 protected final ClusterStatusTracker clusterStatusTracker; 151 152 protected final CoordinatedStateManager csm; 153 154 // Info server. Default access so can be used by unit tests. REGIONSERVER 155 // is name of the webapp and the attribute name used stuffing this instance 156 // into web context. 157 protected InfoServer infoServer; 158 159 protected HFileSystem dataFs; 160 161 protected HFileSystem walFs; 162 163 protected Path dataRootDir; 164 165 protected Path walRootDir; 166 167 protected final int msgInterval; 168 169 // A sleeper that sleeps for msgInterval. 170 protected final Sleeper sleeper; 171 172 /** 173 * Go here to get table descriptors. 174 */ 175 protected TableDescriptors tableDescriptors; 176 177 /** 178 * The asynchronous cluster connection to be shared by services. 179 */ 180 protected AsyncClusterConnection asyncClusterConnection; 181 182 /** 183 * Cache for the meta region replica's locations. Also tracks their changes to avoid stale cache 184 * entries. Used for serving ClientMetaService. 185 */ 186 protected final MetaRegionLocationCache metaRegionLocationCache; 187 188 protected final NettyEventLoopGroupConfig eventLoopGroupConfig; 189 190 private void setupSignalHandlers() { 191 if (!SystemUtils.IS_OS_WINDOWS) { 192 HBasePlatformDependent.handle("HUP", (number, name) -> { 193 try { 194 updateConfiguration(); 195 } catch (IOException e) { 196 LOG.error("Problem while reloading configuration", e); 197 } 198 }); 199 } 200 } 201 202 /** 203 * Setup our cluster connection if not already initialized. 204 */ 205 protected final synchronized void setupClusterConnection() throws IOException { 206 if (asyncClusterConnection == null) { 207 InetSocketAddress localAddress = 208 new InetSocketAddress(rpcServices.getSocketAddress().getAddress(), 0); 209 User user = userProvider.getCurrent(); 210 asyncClusterConnection = 211 ClusterConnectionFactory.createAsyncClusterConnection(this, conf, localAddress, user); 212 } 213 } 214 215 protected final void initializeFileSystem() throws IOException { 216 // Get fs instance used by this RS. Do we use checksum verification in the hbase? If hbase 217 // checksum verification enabled, then automatically switch off hdfs checksum verification. 218 boolean useHBaseChecksum = conf.getBoolean(HConstants.HBASE_CHECKSUM_VERIFICATION, true); 219 String walDirUri = CommonFSUtils.getDirUri(this.conf, 220 new Path(conf.get(CommonFSUtils.HBASE_WAL_DIR, conf.get(HConstants.HBASE_DIR)))); 221 // set WAL's uri 222 if (walDirUri != null) { 223 CommonFSUtils.setFsDefault(this.conf, walDirUri); 224 } 225 // init the WALFs 226 this.walFs = new HFileSystem(this.conf, useHBaseChecksum); 227 this.walRootDir = CommonFSUtils.getWALRootDir(this.conf); 228 // Set 'fs.defaultFS' to match the filesystem on hbase.rootdir else 229 // underlying hadoop hdfs accessors will be going against wrong filesystem 230 // (unless all is set to defaults). 231 String rootDirUri = 232 CommonFSUtils.getDirUri(this.conf, new Path(conf.get(HConstants.HBASE_DIR))); 233 if (rootDirUri != null) { 234 CommonFSUtils.setFsDefault(this.conf, rootDirUri); 235 } 236 // init the filesystem 237 this.dataFs = new HFileSystem(this.conf, useHBaseChecksum); 238 this.dataRootDir = CommonFSUtils.getRootDir(this.conf); 239 int tableDescriptorParallelLoadThreads = 240 conf.getInt("hbase.tabledescriptor.parallel.load.threads", 0); 241 this.tableDescriptors = new FSTableDescriptors(this.dataFs, this.dataRootDir, 242 !canUpdateTableDescriptor(), cacheTableDescriptor(), tableDescriptorParallelLoadThreads); 243 } 244 245 public HBaseServerBase(Configuration conf, String name) throws IOException { 246 super(name); // thread name 247 final Span span = TraceUtil.createSpan("HBaseServerBase.cxtor"); 248 try (Scope ignored = span.makeCurrent()) { 249 this.conf = conf; 250 this.eventLoopGroupConfig = 251 NettyEventLoopGroupConfig.setup(conf, getClass().getSimpleName() + "-EventLoopGroup"); 252 this.startcode = EnvironmentEdgeManager.currentTime(); 253 this.userProvider = UserProvider.instantiate(conf); 254 this.msgInterval = conf.getInt("hbase.regionserver.msginterval", 3 * 1000); 255 this.sleeper = new Sleeper(this.msgInterval, this); 256 this.namedQueueRecorder = createNamedQueueRecord(); 257 this.rpcServices = createRpcServices(); 258 useThisHostnameInstead = getUseThisHostnameInstead(conf); 259 InetSocketAddress addr = rpcServices.getSocketAddress(); 260 261 // if use-ip is enabled, we will use ip to expose Master/RS service for client, 262 // see HBASE-27304 for details. 263 boolean useIp = conf.getBoolean(HConstants.HBASE_SERVER_USEIP_ENABLED_KEY, 264 HConstants.HBASE_SERVER_USEIP_ENABLED_DEFAULT); 265 String isaHostName = 266 useIp ? addr.getAddress().getHostAddress() : addr.getAddress().getHostName(); 267 String hostName = 268 StringUtils.isBlank(useThisHostnameInstead) ? isaHostName : useThisHostnameInstead; 269 serverName = ServerName.valueOf(hostName, addr.getPort(), this.startcode); 270 // login the zookeeper client principal (if using security) 271 ZKAuthentication.loginClient(this.conf, HConstants.ZK_CLIENT_KEYTAB_FILE, 272 HConstants.ZK_CLIENT_KERBEROS_PRINCIPAL, hostName); 273 // login the server principal (if using secure Hadoop) 274 login(userProvider, hostName); 275 // init superusers and add the server principal (if using security) 276 // or process owner as default super user. 277 Superusers.initialize(conf); 278 zooKeeper = 279 new ZKWatcher(conf, getProcessName() + ":" + addr.getPort(), this, canCreateBaseZNode()); 280 281 this.configurationManager = new ConfigurationManager(); 282 setupSignalHandlers(); 283 284 initializeFileSystem(); 285 286 int choreServiceInitialSize = 287 conf.getInt(CHORE_SERVICE_INITIAL_POOL_SIZE, DEFAULT_CHORE_SERVICE_INITIAL_POOL_SIZE); 288 this.choreService = new ChoreService(getName(), choreServiceInitialSize, true); 289 this.executorService = new ExecutorService(getName()); 290 291 this.metaRegionLocationCache = new MetaRegionLocationCache(zooKeeper); 292 293 if (clusterMode()) { 294 if ( 295 conf.getBoolean(HBASE_SPLIT_WAL_COORDINATED_BY_ZK, DEFAULT_HBASE_SPLIT_COORDINATED_BY_ZK) 296 ) { 297 csm = new ZkCoordinatedStateManager(this); 298 } else { 299 csm = null; 300 } 301 clusterStatusTracker = new ClusterStatusTracker(zooKeeper, this); 302 clusterStatusTracker.start(); 303 } else { 304 csm = null; 305 clusterStatusTracker = null; 306 } 307 putUpWebUI(); 308 span.setStatus(StatusCode.OK); 309 } catch (Throwable t) { 310 TraceUtil.setError(span, t); 311 throw t; 312 } finally { 313 span.end(); 314 } 315 } 316 317 /** 318 * Puts up the webui. 319 */ 320 private void putUpWebUI() throws IOException { 321 int port = 322 this.conf.getInt(HConstants.REGIONSERVER_INFO_PORT, HConstants.DEFAULT_REGIONSERVER_INFOPORT); 323 String addr = this.conf.get("hbase.regionserver.info.bindAddress", "0.0.0.0"); 324 325 if (this instanceof HMaster) { 326 port = conf.getInt(HConstants.MASTER_INFO_PORT, HConstants.DEFAULT_MASTER_INFOPORT); 327 addr = this.conf.get("hbase.master.info.bindAddress", "0.0.0.0"); 328 } 329 // -1 is for disabling info server 330 if (port < 0) { 331 return; 332 } 333 334 if (!Addressing.isLocalAddress(InetAddress.getByName(addr))) { 335 String msg = "Failed to start http info server. Address " + addr 336 + " does not belong to this host. Correct configuration parameter: " 337 + "hbase.regionserver.info.bindAddress"; 338 LOG.error(msg); 339 throw new IOException(msg); 340 } 341 // check if auto port bind enabled 342 boolean auto = this.conf.getBoolean(HConstants.REGIONSERVER_INFO_PORT_AUTO, false); 343 while (true) { 344 try { 345 this.infoServer = new InfoServer(getProcessName(), addr, port, false, this.conf); 346 infoServer.addPrivilegedServlet("dump", "/dump", getDumpServlet()); 347 configureInfoServer(infoServer); 348 this.infoServer.start(); 349 break; 350 } catch (BindException e) { 351 if (!auto) { 352 // auto bind disabled throw BindException 353 LOG.error("Failed binding http info server to port: " + port); 354 throw e; 355 } 356 // auto bind enabled, try to use another port 357 LOG.info("Failed binding http info server to port: " + port); 358 port++; 359 LOG.info("Retry starting http info server with port: " + port); 360 } 361 } 362 port = this.infoServer.getPort(); 363 conf.setInt(HConstants.REGIONSERVER_INFO_PORT, port); 364 int masterInfoPort = 365 conf.getInt(HConstants.MASTER_INFO_PORT, HConstants.DEFAULT_MASTER_INFOPORT); 366 conf.setInt("hbase.master.info.port.orig", masterInfoPort); 367 conf.setInt(HConstants.MASTER_INFO_PORT, port); 368 } 369 370 /** 371 * Sets the abort state if not already set. 372 * @return True if abortRequested set to True successfully, false if an abort is already in 373 * progress. 374 */ 375 protected final boolean setAbortRequested() { 376 return abortRequested.compareAndSet(false, true); 377 } 378 379 @Override 380 public boolean isStopped() { 381 return stopped; 382 } 383 384 @Override 385 public boolean isAborted() { 386 return abortRequested.get(); 387 } 388 389 @Override 390 public Configuration getConfiguration() { 391 return conf; 392 } 393 394 @Override 395 public AsyncClusterConnection getAsyncClusterConnection() { 396 return asyncClusterConnection; 397 } 398 399 @Override 400 public ZKWatcher getZooKeeper() { 401 return zooKeeper; 402 } 403 404 protected final void shutdownChore(ScheduledChore chore) { 405 if (chore != null) { 406 chore.shutdown(); 407 } 408 } 409 410 protected final void initializeMemStoreChunkCreator(HeapMemoryManager hMemManager) { 411 if (MemStoreLAB.isEnabled(conf)) { 412 // MSLAB is enabled. So initialize MemStoreChunkPool 413 // By this time, the MemstoreFlusher is already initialized. We can get the global limits from 414 // it. 415 Pair<Long, MemoryType> pair = MemorySizeUtil.getGlobalMemStoreSize(conf); 416 long globalMemStoreSize = pair.getFirst(); 417 boolean offheap = pair.getSecond() == MemoryType.NON_HEAP; 418 // When off heap memstore in use, take full area for chunk pool. 419 float poolSizePercentage = offheap 420 ? 1.0F 421 : conf.getFloat(MemStoreLAB.CHUNK_POOL_MAXSIZE_KEY, MemStoreLAB.POOL_MAX_SIZE_DEFAULT); 422 float initialCountPercentage = conf.getFloat(MemStoreLAB.CHUNK_POOL_INITIALSIZE_KEY, 423 MemStoreLAB.POOL_INITIAL_SIZE_DEFAULT); 424 int chunkSize = conf.getInt(MemStoreLAB.CHUNK_SIZE_KEY, MemStoreLAB.CHUNK_SIZE_DEFAULT); 425 float indexChunkSizePercent = conf.getFloat(MemStoreLAB.INDEX_CHUNK_SIZE_PERCENTAGE_KEY, 426 MemStoreLAB.INDEX_CHUNK_SIZE_PERCENTAGE_DEFAULT); 427 // init the chunkCreator 428 ChunkCreator.initialize(chunkSize, offheap, globalMemStoreSize, poolSizePercentage, 429 initialCountPercentage, hMemManager, indexChunkSizePercent); 430 } 431 } 432 433 protected abstract void stopChores(); 434 435 protected final void stopChoreService() { 436 // clean up the scheduled chores 437 if (choreService != null) { 438 LOG.info("Shutdown chores and chore service"); 439 stopChores(); 440 // cancel the remaining scheduled chores (in case we missed out any) 441 // TODO: cancel will not cleanup the chores, so we need make sure we do not miss any 442 choreService.shutdown(); 443 } 444 } 445 446 protected final void stopExecutorService() { 447 if (executorService != null) { 448 LOG.info("Shutdown executor service"); 449 executorService.shutdown(); 450 } 451 } 452 453 protected final void closeClusterConnection() { 454 if (asyncClusterConnection != null) { 455 LOG.info("Close async cluster connection"); 456 try { 457 this.asyncClusterConnection.close(); 458 } catch (IOException e) { 459 // Although the {@link Closeable} interface throws an {@link 460 // IOException}, in reality, the implementation would never do that. 461 LOG.warn("Attempt to close server's AsyncClusterConnection failed.", e); 462 } 463 } 464 } 465 466 protected final void stopInfoServer() { 467 if (this.infoServer != null) { 468 LOG.info("Stop info server"); 469 try { 470 this.infoServer.stop(); 471 } catch (Exception e) { 472 LOG.error("Failed to stop infoServer", e); 473 } 474 } 475 } 476 477 protected final void closeZooKeeper() { 478 if (this.zooKeeper != null) { 479 LOG.info("Close zookeeper"); 480 this.zooKeeper.close(); 481 } 482 } 483 484 protected final void closeTableDescriptors() { 485 if (this.tableDescriptors != null) { 486 LOG.info("Close table descriptors"); 487 try { 488 this.tableDescriptors.close(); 489 } catch (IOException e) { 490 LOG.debug("Failed to close table descriptors gracefully", e); 491 } 492 } 493 } 494 495 /** 496 * In order to register ShutdownHook, this method is called when HMaster and HRegionServer are 497 * started. For details, please refer to HBASE-26951 498 */ 499 protected final void installShutdownHook() { 500 ShutdownHook.install(conf, dataFs, this, Thread.currentThread()); 501 isShutdownHookInstalled = true; 502 } 503 504 @RestrictedApi(explanation = "Should only be called in tests", link = "", 505 allowedOnPath = ".*/src/test/.*") 506 public boolean isShutdownHookInstalled() { 507 return isShutdownHookInstalled; 508 } 509 510 @Override 511 public ServerName getServerName() { 512 return serverName; 513 } 514 515 @Override 516 public ChoreService getChoreService() { 517 return choreService; 518 } 519 520 /** Returns Return table descriptors implementation. */ 521 public TableDescriptors getTableDescriptors() { 522 return this.tableDescriptors; 523 } 524 525 public ExecutorService getExecutorService() { 526 return executorService; 527 } 528 529 public AccessChecker getAccessChecker() { 530 return rpcServices.getAccessChecker(); 531 } 532 533 public ZKPermissionWatcher getZKPermissionWatcher() { 534 return rpcServices.getZkPermissionWatcher(); 535 } 536 537 @Override 538 public CoordinatedStateManager getCoordinatedStateManager() { 539 return csm; 540 } 541 542 @Override 543 public Connection createConnection(Configuration conf) throws IOException { 544 User user = UserProvider.instantiate(conf).getCurrent(); 545 return ConnectionFactory.createConnection(conf, null, user); 546 } 547 548 /** Returns Return the rootDir. */ 549 public Path getDataRootDir() { 550 return dataRootDir; 551 } 552 553 @Override 554 public FileSystem getFileSystem() { 555 return dataFs; 556 } 557 558 /** Returns Return the walRootDir. */ 559 public Path getWALRootDir() { 560 return walRootDir; 561 } 562 563 /** Returns Return the walFs. */ 564 public FileSystem getWALFileSystem() { 565 return walFs; 566 } 567 568 /** Returns True if the cluster is up. */ 569 public boolean isClusterUp() { 570 return !clusterMode() || this.clusterStatusTracker.isClusterUp(); 571 } 572 573 /** Returns time stamp in millis of when this server was started */ 574 public long getStartcode() { 575 return this.startcode; 576 } 577 578 public InfoServer getInfoServer() { 579 return infoServer; 580 } 581 582 public int getMsgInterval() { 583 return msgInterval; 584 } 585 586 /** 587 * get NamedQueue Provider to add different logs to ringbuffer 588 */ 589 public NamedQueueRecorder getNamedQueueRecorder() { 590 return this.namedQueueRecorder; 591 } 592 593 public RpcServerInterface getRpcServer() { 594 return rpcServices.getRpcServer(); 595 } 596 597 public NettyEventLoopGroupConfig getEventLoopGroupConfig() { 598 return eventLoopGroupConfig; 599 } 600 601 public R getRpcServices() { 602 return rpcServices; 603 } 604 605 @RestrictedApi(explanation = "Should only be called in tests", link = "", 606 allowedOnPath = ".*/src/test/.*") 607 public MetaRegionLocationCache getMetaRegionLocationCache() { 608 return this.metaRegionLocationCache; 609 } 610 611 @RestrictedApi(explanation = "Should only be called in tests", link = "", 612 allowedOnPath = ".*/src/test/.*") 613 public ConfigurationManager getConfigurationManager() { 614 return configurationManager; 615 } 616 617 /** 618 * Reload the configuration from disk. 619 */ 620 public void updateConfiguration() throws IOException { 621 LOG.info("Reloading the configuration from disk."); 622 // Reload the configuration from disk. 623 preUpdateConfiguration(); 624 conf.reloadConfiguration(); 625 configurationManager.notifyAllObservers(conf); 626 postUpdateConfiguration(); 627 } 628 629 private void preUpdateConfiguration() throws IOException { 630 CoprocessorHost<?, ?> coprocessorHost = getCoprocessorHost(); 631 if (coprocessorHost instanceof RegionServerCoprocessorHost) { 632 ((RegionServerCoprocessorHost) coprocessorHost).preUpdateConfiguration(conf); 633 } else if (coprocessorHost instanceof MasterCoprocessorHost) { 634 ((MasterCoprocessorHost) coprocessorHost).preUpdateConfiguration(conf); 635 } 636 } 637 638 private void postUpdateConfiguration() throws IOException { 639 CoprocessorHost<?, ?> coprocessorHost = getCoprocessorHost(); 640 if (coprocessorHost instanceof RegionServerCoprocessorHost) { 641 ((RegionServerCoprocessorHost) coprocessorHost).postUpdateConfiguration(conf); 642 } else if (coprocessorHost instanceof MasterCoprocessorHost) { 643 ((MasterCoprocessorHost) coprocessorHost).postUpdateConfiguration(conf); 644 } 645 } 646 647 @Override 648 public String toString() { 649 return getServerName().toString(); 650 } 651 652 protected abstract CoprocessorHost<?, ?> getCoprocessorHost(); 653 654 protected abstract boolean canCreateBaseZNode(); 655 656 protected abstract String getProcessName(); 657 658 protected abstract R createRpcServices() throws IOException; 659 660 protected abstract String getUseThisHostnameInstead(Configuration conf) throws IOException; 661 662 protected abstract void login(UserProvider user, String host) throws IOException; 663 664 protected abstract NamedQueueRecorder createNamedQueueRecord(); 665 666 protected abstract void configureInfoServer(InfoServer infoServer); 667 668 protected abstract Class<? extends HttpServlet> getDumpServlet(); 669 670 protected abstract boolean canUpdateTableDescriptor(); 671 672 protected abstract boolean cacheTableDescriptor(); 673 674 protected abstract boolean clusterMode(); 675}