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 */ 018 019package org.apache.hadoop.hbase.rsgroup; 020 021import com.google.protobuf.RpcCallback; 022import com.google.protobuf.RpcController; 023import com.google.protobuf.Service; 024 025import java.io.IOException; 026import java.util.Collections; 027import java.util.HashSet; 028import java.util.List; 029import java.util.Optional; 030import java.util.Set; 031import java.util.stream.Collectors; 032 033import org.apache.hadoop.hbase.CoprocessorEnvironment; 034import org.apache.hadoop.hbase.HBaseIOException; 035import org.apache.hadoop.hbase.HConstants; 036import org.apache.hadoop.hbase.MasterNotRunningException; 037import org.apache.hadoop.hbase.NamespaceDescriptor; 038import org.apache.hadoop.hbase.PleaseHoldException; 039import org.apache.hadoop.hbase.ServerName; 040import org.apache.hadoop.hbase.TableName; 041import org.apache.hadoop.hbase.client.RegionInfo; 042import org.apache.hadoop.hbase.client.SnapshotDescription; 043import org.apache.hadoop.hbase.client.TableDescriptor; 044import org.apache.hadoop.hbase.constraint.ConstraintException; 045import org.apache.hadoop.hbase.coprocessor.CoreCoprocessor; 046import org.apache.hadoop.hbase.coprocessor.HasMasterServices; 047import org.apache.hadoop.hbase.coprocessor.MasterCoprocessor; 048import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment; 049import org.apache.hadoop.hbase.coprocessor.MasterObserver; 050import org.apache.hadoop.hbase.coprocessor.ObserverContext; 051import org.apache.hadoop.hbase.ipc.CoprocessorRpcUtils; 052import org.apache.hadoop.hbase.ipc.RpcServer; 053import org.apache.hadoop.hbase.master.MasterServices; 054import org.apache.hadoop.hbase.net.Address; 055import org.apache.hadoop.hbase.protobuf.ProtobufUtil; 056import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos; 057import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos; 058import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.AddRSGroupRequest; 059import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.AddRSGroupResponse; 060import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.BalanceRSGroupRequest; 061import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.BalanceRSGroupResponse; 062import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoOfServerRequest; 063import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoOfServerResponse; 064import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoOfTableRequest; 065import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoOfTableResponse; 066import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoRequest; 067import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoResponse; 068import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.ListRSGroupInfosRequest; 069import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.ListRSGroupInfosResponse; 070import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.MoveServersAndTablesRequest; 071import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.MoveServersAndTablesResponse; 072import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.MoveServersRequest; 073import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.MoveServersResponse; 074import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.MoveTablesRequest; 075import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.MoveTablesResponse; 076import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.RSGroupAdminService; 077import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.RemoveRSGroupRequest; 078import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.RemoveRSGroupResponse; 079import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.RemoveServersRequest; 080import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.RemoveServersResponse; 081import org.apache.hadoop.hbase.protobuf.generated.TableProtos; 082import org.apache.hadoop.hbase.security.User; 083import org.apache.hadoop.hbase.security.UserProvider; 084import org.apache.hadoop.hbase.security.access.AccessChecker; 085import org.apache.hadoop.hbase.security.access.Permission.Action; 086import org.apache.hadoop.hbase.zookeeper.ZKWatcher; 087import org.apache.yetus.audience.InterfaceAudience; 088import org.slf4j.Logger; 089import org.slf4j.LoggerFactory; 090import org.apache.hbase.thirdparty.com.google.common.collect.Sets; 091 092// TODO: Encapsulate MasterObserver functions into separate subclass. 093@CoreCoprocessor 094@InterfaceAudience.Private 095public class RSGroupAdminEndpoint implements MasterCoprocessor, MasterObserver { 096 private static final Logger LOG = LoggerFactory.getLogger(RSGroupAdminEndpoint.class); 097 098 private MasterServices master = null; 099 // Only instance of RSGroupInfoManager. RSGroup aware load balancers ask for this instance on 100 // their setup. 101 private RSGroupInfoManager groupInfoManager; 102 private RSGroupAdminServer groupAdminServer; 103 private final RSGroupAdminService groupAdminService = new RSGroupAdminServiceImpl(); 104 private AccessChecker accessChecker; 105 106 /** Provider for mapping principal names to Users */ 107 private UserProvider userProvider; 108 109 @Override 110 public void start(CoprocessorEnvironment env) throws IOException { 111 if (!(env instanceof HasMasterServices)) { 112 throw new IOException("Does not implement HMasterServices"); 113 } 114 115 master = ((HasMasterServices)env).getMasterServices(); 116 groupInfoManager = RSGroupInfoManagerImpl.getInstance(master); 117 groupAdminServer = new RSGroupAdminServer(master, groupInfoManager); 118 Class<?> clazz = 119 master.getConfiguration().getClass(HConstants.HBASE_MASTER_LOADBALANCER_CLASS, null); 120 if (!RSGroupableBalancer.class.isAssignableFrom(clazz)) { 121 throw new IOException("Configured balancer does not support RegionServer groups."); 122 } 123 ZKWatcher zk = ((HasMasterServices)env).getMasterServices().getZooKeeper(); 124 accessChecker = new AccessChecker(env.getConfiguration(), zk); 125 126 // set the user-provider. 127 this.userProvider = UserProvider.instantiate(env.getConfiguration()); 128 } 129 130 @Override 131 public void stop(CoprocessorEnvironment env) { 132 accessChecker.stop(); 133 } 134 135 @Override 136 public Iterable<Service> getServices() { 137 return Collections.singleton(groupAdminService); 138 } 139 140 @Override 141 public Optional<MasterObserver> getMasterObserver() { 142 return Optional.of(this); 143 } 144 145 RSGroupInfoManager getGroupInfoManager() { 146 return groupInfoManager; 147 } 148 149 /** 150 * Implementation of RSGroupAdminService defined in RSGroupAdmin.proto. 151 * This class calls {@link RSGroupAdminServer} for actual work, converts result to protocol 152 * buffer response, handles exceptions if any occurred and then calls the {@code RpcCallback} with 153 * the response. 154 */ 155 private class RSGroupAdminServiceImpl extends RSGroupAdminProtos.RSGroupAdminService { 156 @Override 157 public void getRSGroupInfo(RpcController controller, 158 GetRSGroupInfoRequest request, RpcCallback<GetRSGroupInfoResponse> done) { 159 GetRSGroupInfoResponse.Builder builder = GetRSGroupInfoResponse.newBuilder(); 160 String groupName = request.getRSGroupName(); 161 LOG.info(master.getClientIdAuditPrefix() + " initiates rsgroup info retrieval, group=" 162 + groupName); 163 try { 164 checkPermission("getRSGroupInfo"); 165 RSGroupInfo rsGroupInfo = groupAdminServer.getRSGroupInfo(groupName); 166 if (rsGroupInfo != null) { 167 builder.setRSGroupInfo(RSGroupProtobufUtil.toProtoGroupInfo(rsGroupInfo)); 168 } 169 } catch (IOException e) { 170 CoprocessorRpcUtils.setControllerException(controller, e); 171 } 172 done.run(builder.build()); 173 } 174 175 @Override 176 public void getRSGroupInfoOfTable(RpcController controller, 177 GetRSGroupInfoOfTableRequest request, RpcCallback<GetRSGroupInfoOfTableResponse> done) { 178 GetRSGroupInfoOfTableResponse.Builder builder = GetRSGroupInfoOfTableResponse.newBuilder(); 179 TableName tableName = ProtobufUtil.toTableName(request.getTableName()); 180 LOG.info(master.getClientIdAuditPrefix() + " initiates rsgroup info retrieval, table=" 181 + tableName); 182 try { 183 checkPermission("getRSGroupInfoOfTable"); 184 RSGroupInfo RSGroupInfo = groupAdminServer.getRSGroupInfoOfTable(tableName); 185 if (RSGroupInfo != null) { 186 builder.setRSGroupInfo(RSGroupProtobufUtil.toProtoGroupInfo(RSGroupInfo)); 187 } 188 } catch (IOException e) { 189 CoprocessorRpcUtils.setControllerException(controller, e); 190 } 191 done.run(builder.build()); 192 } 193 194 @Override 195 public void moveServers(RpcController controller, MoveServersRequest request, 196 RpcCallback<MoveServersResponse> done) { 197 MoveServersResponse.Builder builder = MoveServersResponse.newBuilder(); 198 Set<Address> hostPorts = Sets.newHashSet(); 199 for (HBaseProtos.ServerName el : request.getServersList()) { 200 hostPorts.add(Address.fromParts(el.getHostName(), el.getPort())); 201 } 202 LOG.info(master.getClientIdAuditPrefix() + " move servers " + hostPorts +" to rsgroup " 203 + request.getTargetGroup()); 204 try { 205 if (master.getMasterCoprocessorHost() != null) { 206 master.getMasterCoprocessorHost().preMoveServers(hostPorts, request.getTargetGroup()); 207 } 208 checkPermission("moveServers"); 209 groupAdminServer.moveServers(hostPorts, request.getTargetGroup()); 210 if (master.getMasterCoprocessorHost() != null) { 211 master.getMasterCoprocessorHost().postMoveServers(hostPorts, request.getTargetGroup()); 212 } 213 } catch (IOException e) { 214 CoprocessorRpcUtils.setControllerException(controller, e); 215 } 216 done.run(builder.build()); 217 } 218 219 @Override 220 public void moveTables(RpcController controller, MoveTablesRequest request, 221 RpcCallback<MoveTablesResponse> done) { 222 MoveTablesResponse.Builder builder = MoveTablesResponse.newBuilder(); 223 Set<TableName> tables = new HashSet<>(request.getTableNameList().size()); 224 for (TableProtos.TableName tableName : request.getTableNameList()) { 225 tables.add(ProtobufUtil.toTableName(tableName)); 226 } 227 LOG.info(master.getClientIdAuditPrefix() + " move tables " + tables +" to rsgroup " 228 + request.getTargetGroup()); 229 try { 230 if (master.getMasterCoprocessorHost() != null) { 231 master.getMasterCoprocessorHost().preMoveTables(tables, request.getTargetGroup()); 232 } 233 checkPermission("moveTables"); 234 groupAdminServer.moveTables(tables, request.getTargetGroup()); 235 if (master.getMasterCoprocessorHost() != null) { 236 master.getMasterCoprocessorHost().postMoveTables(tables, request.getTargetGroup()); 237 } 238 } catch (IOException e) { 239 CoprocessorRpcUtils.setControllerException(controller, e); 240 } 241 done.run(builder.build()); 242 } 243 244 @Override 245 public void addRSGroup(RpcController controller, AddRSGroupRequest request, 246 RpcCallback<AddRSGroupResponse> done) { 247 AddRSGroupResponse.Builder builder = AddRSGroupResponse.newBuilder(); 248 LOG.info(master.getClientIdAuditPrefix() + " add rsgroup " + request.getRSGroupName()); 249 try { 250 if (master.getMasterCoprocessorHost() != null) { 251 master.getMasterCoprocessorHost().preAddRSGroup(request.getRSGroupName()); 252 } 253 checkPermission("addRSGroup"); 254 groupAdminServer.addRSGroup(request.getRSGroupName()); 255 if (master.getMasterCoprocessorHost() != null) { 256 master.getMasterCoprocessorHost().postAddRSGroup(request.getRSGroupName()); 257 } 258 } catch (IOException e) { 259 CoprocessorRpcUtils.setControllerException(controller, e); 260 } 261 done.run(builder.build()); 262 } 263 264 @Override 265 public void removeRSGroup(RpcController controller, 266 RemoveRSGroupRequest request, RpcCallback<RemoveRSGroupResponse> done) { 267 RemoveRSGroupResponse.Builder builder = 268 RemoveRSGroupResponse.newBuilder(); 269 LOG.info(master.getClientIdAuditPrefix() + " remove rsgroup " + request.getRSGroupName()); 270 try { 271 if (master.getMasterCoprocessorHost() != null) { 272 master.getMasterCoprocessorHost().preRemoveRSGroup(request.getRSGroupName()); 273 } 274 checkPermission("removeRSGroup"); 275 groupAdminServer.removeRSGroup(request.getRSGroupName()); 276 if (master.getMasterCoprocessorHost() != null) { 277 master.getMasterCoprocessorHost().postRemoveRSGroup(request.getRSGroupName()); 278 } 279 } catch (IOException e) { 280 CoprocessorRpcUtils.setControllerException(controller, e); 281 } 282 done.run(builder.build()); 283 } 284 285 @Override 286 public void balanceRSGroup(RpcController controller, 287 BalanceRSGroupRequest request, RpcCallback<BalanceRSGroupResponse> done) { 288 BalanceRSGroupResponse.Builder builder = BalanceRSGroupResponse.newBuilder(); 289 LOG.info(master.getClientIdAuditPrefix() + " balance rsgroup, group=" 290 + request.getRSGroupName()); 291 try { 292 if (master.getMasterCoprocessorHost() != null) { 293 master.getMasterCoprocessorHost().preBalanceRSGroup(request.getRSGroupName()); 294 } 295 checkPermission("balanceRSGroup"); 296 boolean balancerRan = groupAdminServer.balanceRSGroup(request.getRSGroupName()); 297 builder.setBalanceRan(balancerRan); 298 if (master.getMasterCoprocessorHost() != null) { 299 master.getMasterCoprocessorHost().postBalanceRSGroup(request.getRSGroupName(), 300 balancerRan); 301 } 302 } catch (IOException e) { 303 CoprocessorRpcUtils.setControllerException(controller, e); 304 builder.setBalanceRan(false); 305 } 306 done.run(builder.build()); 307 } 308 309 @Override 310 public void listRSGroupInfos(RpcController controller, 311 ListRSGroupInfosRequest request, RpcCallback<ListRSGroupInfosResponse> done) { 312 ListRSGroupInfosResponse.Builder builder = ListRSGroupInfosResponse.newBuilder(); 313 LOG.info(master.getClientIdAuditPrefix() + " list rsgroup"); 314 try { 315 checkPermission("listRSGroup"); 316 for (RSGroupInfo RSGroupInfo : groupAdminServer.listRSGroups()) { 317 builder.addRSGroupInfo(RSGroupProtobufUtil.toProtoGroupInfo(RSGroupInfo)); 318 } 319 } catch (IOException e) { 320 CoprocessorRpcUtils.setControllerException(controller, e); 321 } 322 done.run(builder.build()); 323 } 324 325 @Override 326 public void getRSGroupInfoOfServer(RpcController controller, 327 GetRSGroupInfoOfServerRequest request, RpcCallback<GetRSGroupInfoOfServerResponse> done) { 328 GetRSGroupInfoOfServerResponse.Builder builder = GetRSGroupInfoOfServerResponse.newBuilder(); 329 Address hp = Address.fromParts(request.getServer().getHostName(), 330 request.getServer().getPort()); 331 LOG.info(master.getClientIdAuditPrefix() + " initiates rsgroup info retrieval, server=" 332 + hp); 333 try { 334 checkPermission("getRSGroupInfoOfServer"); 335 RSGroupInfo info = groupAdminServer.getRSGroupOfServer(hp); 336 if (info != null) { 337 builder.setRSGroupInfo(RSGroupProtobufUtil.toProtoGroupInfo(info)); 338 } 339 } catch (IOException e) { 340 CoprocessorRpcUtils.setControllerException(controller, e); 341 } 342 done.run(builder.build()); 343 } 344 345 @Override 346 public void moveServersAndTables(RpcController controller, 347 MoveServersAndTablesRequest request, RpcCallback<MoveServersAndTablesResponse> done) { 348 MoveServersAndTablesResponse.Builder builder = MoveServersAndTablesResponse.newBuilder(); 349 Set<Address> hostPorts = Sets.newHashSet(); 350 for (HBaseProtos.ServerName el : request.getServersList()) { 351 hostPorts.add(Address.fromParts(el.getHostName(), el.getPort())); 352 } 353 Set<TableName> tables = new HashSet<>(request.getTableNameList().size()); 354 for (TableProtos.TableName tableName : request.getTableNameList()) { 355 tables.add(ProtobufUtil.toTableName(tableName)); 356 } 357 LOG.info(master.getClientIdAuditPrefix() + " move servers " + hostPorts 358 + " and tables " + tables + " to rsgroup" + request.getTargetGroup()); 359 try { 360 if (master.getMasterCoprocessorHost() != null) { 361 master.getMasterCoprocessorHost().preMoveServersAndTables(hostPorts, tables, 362 request.getTargetGroup()); 363 } 364 checkPermission("moveServersAndTables"); 365 groupAdminServer.moveServersAndTables(hostPorts, tables, request.getTargetGroup()); 366 if (master.getMasterCoprocessorHost() != null) { 367 master.getMasterCoprocessorHost().postMoveServersAndTables(hostPorts, tables, 368 request.getTargetGroup()); 369 } 370 } catch (IOException e) { 371 CoprocessorRpcUtils.setControllerException(controller, e); 372 } 373 done.run(builder.build()); 374 } 375 376 @Override 377 public void removeServers(RpcController controller, 378 RemoveServersRequest request, 379 RpcCallback<RemoveServersResponse> done) { 380 RemoveServersResponse.Builder builder = 381 RemoveServersResponse.newBuilder(); 382 Set<Address> servers = Sets.newHashSet(); 383 for (HBaseProtos.ServerName el : request.getServersList()) { 384 servers.add(Address.fromParts(el.getHostName(), el.getPort())); 385 } 386 LOG.info(master.getClientIdAuditPrefix() 387 + " remove decommissioned servers from rsgroup: " + servers); 388 try { 389 if (master.getMasterCoprocessorHost() != null) { 390 master.getMasterCoprocessorHost().preRemoveServers(servers); 391 } 392 checkPermission("removeServers"); 393 groupAdminServer.removeServers(servers); 394 if (master.getMasterCoprocessorHost() != null) { 395 master.getMasterCoprocessorHost().postRemoveServers(servers); 396 } 397 } catch (IOException e) { 398 CoprocessorRpcUtils.setControllerException(controller, e); 399 } 400 done.run(builder.build()); 401 } 402 } 403 404 boolean rsgroupHasServersOnline(TableDescriptor desc) throws IOException { 405 String groupName; 406 try { 407 groupName = 408 master.getClusterSchema().getNamespace(desc.getTableName().getNamespaceAsString()) 409 .getConfigurationValue(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP); 410 if (groupName == null) { 411 groupName = RSGroupInfo.DEFAULT_GROUP; 412 } 413 } catch (MasterNotRunningException | PleaseHoldException e) { 414 LOG.info("Master has not initialized yet; temporarily using default RSGroup '" + 415 RSGroupInfo.DEFAULT_GROUP + "' for deploy of system table"); 416 groupName = RSGroupInfo.DEFAULT_GROUP; 417 } 418 419 RSGroupInfo rsGroupInfo = groupAdminServer.getRSGroupInfo(groupName); 420 if (rsGroupInfo == null) { 421 throw new ConstraintException( 422 "Default RSGroup (" + groupName + ") for this table's " + "namespace does not exist."); 423 } 424 425 for (ServerName onlineServer : master.getServerManager().createDestinationServersList()) { 426 if (rsGroupInfo.getServers().contains(onlineServer.getAddress())) { 427 return true; 428 } 429 } 430 return false; 431 } 432 433 void assignTableToGroup(TableDescriptor desc) throws IOException { 434 String groupName = 435 master.getClusterSchema().getNamespace(desc.getTableName().getNamespaceAsString()) 436 .getConfigurationValue(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP); 437 if (groupName == null) { 438 groupName = RSGroupInfo.DEFAULT_GROUP; 439 } 440 RSGroupInfo rsGroupInfo = groupAdminServer.getRSGroupInfo(groupName); 441 if (rsGroupInfo == null) { 442 throw new ConstraintException("Default RSGroup (" + groupName + ") for this table's " 443 + "namespace does not exist."); 444 } 445 if (!rsGroupInfo.containsTable(desc.getTableName())) { 446 LOG.debug("Pre-moving table " + desc.getTableName() + " to RSGroup " + groupName); 447 groupAdminServer.moveTables(Sets.newHashSet(desc.getTableName()), groupName); 448 } 449 } 450 451 ///////////////////////////////////////////////////////////////////////////// 452 // MasterObserver overrides 453 ///////////////////////////////////////////////////////////////////////////// 454 455 @Override 456 public void preCreateTableAction( 457 final ObserverContext<MasterCoprocessorEnvironment> ctx, 458 final TableDescriptor desc, 459 final RegionInfo[] regions) throws IOException { 460 if (!desc.getTableName().isSystemTable() && !rsgroupHasServersOnline(desc)) { 461 throw new HBaseIOException("No online servers in the rsgroup, which table " + 462 desc.getTableName().getNameAsString() + " belongs to"); 463 } 464 } 465 466 // Assign table to default RSGroup. 467 @Override 468 public void postCreateTable(ObserverContext<MasterCoprocessorEnvironment> ctx, 469 TableDescriptor desc, RegionInfo[] regions) throws IOException { 470 assignTableToGroup(desc); 471 } 472 473 // Remove table from its RSGroup. 474 @Override 475 public void postDeleteTable(ObserverContext<MasterCoprocessorEnvironment> ctx, 476 TableName tableName) throws IOException { 477 try { 478 RSGroupInfo group = groupAdminServer.getRSGroupInfoOfTable(tableName); 479 if (group != null) { 480 LOG.debug(String.format("Removing deleted table '%s' from rsgroup '%s'", tableName, 481 group.getName())); 482 groupAdminServer.moveTables(Sets.newHashSet(tableName), null); 483 } 484 } catch (IOException ex) { 485 LOG.debug("Failed to perform RSGroup information cleanup for table: " + tableName, ex); 486 } 487 } 488 489 @Override 490 public void preCreateNamespace(ObserverContext<MasterCoprocessorEnvironment> ctx, 491 NamespaceDescriptor ns) throws IOException { 492 String group = ns.getConfigurationValue(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP); 493 if(group != null && groupAdminServer.getRSGroupInfo(group) == null) { 494 throw new ConstraintException("Region server group "+group+" does not exit"); 495 } 496 } 497 498 @Override 499 public void preModifyNamespace(ObserverContext<MasterCoprocessorEnvironment> ctx, 500 NamespaceDescriptor ns) throws IOException { 501 preCreateNamespace(ctx, ns); 502 } 503 504 @Override 505 public void preCloneSnapshot(ObserverContext<MasterCoprocessorEnvironment> ctx, 506 SnapshotDescription snapshot, TableDescriptor desc) throws IOException { 507 assignTableToGroup(desc); 508 } 509 510 @Override 511 public void postClearDeadServers(ObserverContext<MasterCoprocessorEnvironment> ctx, 512 List<ServerName> servers, List<ServerName> notClearedServers) 513 throws IOException { 514 Set<Address> clearedServer = servers.stream(). 515 filter(server -> !notClearedServers.contains(server)). 516 map(ServerName::getAddress). 517 collect(Collectors.toSet()); 518 if(!clearedServer.isEmpty()) { 519 groupAdminServer.removeServers(clearedServer); 520 } 521 } 522 523 public void checkPermission(String request) throws IOException { 524 accessChecker.requirePermission(getActiveUser(), request, null, Action.ADMIN); 525 } 526 527 /** 528 * Returns the active user to which authorization checks should be applied. 529 * If we are in the context of an RPC call, the remote user is used, 530 * otherwise the currently logged in user is used. 531 */ 532 private User getActiveUser() throws IOException { 533 // for non-rpc handling, fallback to system user 534 Optional<User> optionalUser = RpcServer.getRequestUser(); 535 if (optionalUser.isPresent()) { 536 return optionalUser.get(); 537 } 538 return userProvider.getCurrent(); 539 } 540}