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.rsgroup; 019 020import com.google.protobuf.ServiceException; 021import java.io.IOException; 022import java.util.ArrayList; 023import java.util.EnumSet; 024import java.util.List; 025import java.util.Map; 026import java.util.Set; 027import java.util.stream.Collectors; 028import org.apache.hadoop.hbase.ClusterMetrics; 029import org.apache.hadoop.hbase.ServerName; 030import org.apache.hadoop.hbase.TableName; 031import org.apache.hadoop.hbase.TableNotFoundException; 032import org.apache.hadoop.hbase.client.Admin; 033import org.apache.hadoop.hbase.client.BalanceRequest; 034import org.apache.hadoop.hbase.client.BalanceResponse; 035import org.apache.hadoop.hbase.client.Connection; 036import org.apache.hadoop.hbase.net.Address; 037import org.apache.hadoop.hbase.protobuf.ProtobufUtil; 038import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos; 039import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.NameStringPair; 040import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos; 041import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.AddRSGroupRequest; 042import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoOfServerRequest; 043import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoOfServerResponse; 044import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoOfTableRequest; 045import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoOfTableResponse; 046import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoRequest; 047import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoResponse; 048import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.ListRSGroupInfosRequest; 049import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.MoveServersAndTablesRequest; 050import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.MoveServersRequest; 051import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.MoveTablesRequest; 052import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.RSGroupAdminService; 053import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.RemoveRSGroupRequest; 054import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.RemoveServersRequest; 055import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.RenameRSGroupRequest; 056import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.UpdateRSGroupConfigRequest; 057import org.apache.hadoop.hbase.protobuf.generated.RSGroupProtos; 058import org.apache.yetus.audience.InterfaceAudience; 059 060import org.apache.hbase.thirdparty.com.google.common.collect.Sets; 061 062/** 063 * Client used for managing region server group information. 064 */ 065@InterfaceAudience.Private 066public class RSGroupAdminClient implements RSGroupAdmin { 067 private RSGroupAdminService.BlockingInterface stub; 068 private Admin admin; 069 070 public RSGroupAdminClient(Connection conn) throws IOException { 071 admin = conn.getAdmin(); 072 stub = RSGroupAdminService.newBlockingStub(admin.coprocessorService()); 073 } 074 075 @Override 076 public RSGroupInfo getRSGroupInfo(String groupName) throws IOException { 077 try { 078 GetRSGroupInfoResponse resp = stub.getRSGroupInfo(null, 079 GetRSGroupInfoRequest.newBuilder().setRSGroupName(groupName).build()); 080 if (resp.hasRSGroupInfo()) { 081 return RSGroupProtobufUtil.toGroupInfo(resp.getRSGroupInfo()); 082 } 083 return null; 084 } catch (ServiceException e) { 085 throw ProtobufUtil.handleRemoteException(e); 086 } 087 } 088 089 @Override 090 public RSGroupInfo getRSGroupInfoOfTable(TableName tableName) throws IOException { 091 GetRSGroupInfoOfTableRequest request = GetRSGroupInfoOfTableRequest.newBuilder() 092 .setTableName(ProtobufUtil.toProtoTableName(tableName)).build(); 093 try { 094 GetRSGroupInfoOfTableResponse resp = stub.getRSGroupInfoOfTable(null, request); 095 if (resp.hasRSGroupInfo()) { 096 return RSGroupProtobufUtil.toGroupInfo(resp.getRSGroupInfo()); 097 } 098 return null; 099 } catch (ServiceException e) { 100 throw ProtobufUtil.handleRemoteException(e); 101 } 102 } 103 104 @Override 105 public void moveServers(Set<Address> servers, String targetGroup) throws IOException { 106 Set<HBaseProtos.ServerName> hostPorts = Sets.newHashSet(); 107 for (Address el : servers) { 108 hostPorts.add(HBaseProtos.ServerName.newBuilder().setHostName(el.getHostname()) 109 .setPort(el.getPort()).build()); 110 } 111 MoveServersRequest request = 112 MoveServersRequest.newBuilder().setTargetGroup(targetGroup).addAllServers(hostPorts).build(); 113 try { 114 stub.moveServers(null, request); 115 } catch (ServiceException e) { 116 throw ProtobufUtil.handleRemoteException(e); 117 } 118 } 119 120 @Override 121 public void moveTables(Set<TableName> tables, String targetGroup) throws IOException { 122 MoveTablesRequest.Builder builder = MoveTablesRequest.newBuilder().setTargetGroup(targetGroup); 123 for (TableName tableName : tables) { 124 builder.addTableName(ProtobufUtil.toProtoTableName(tableName)); 125 if (!admin.tableExists(tableName)) { 126 throw new TableNotFoundException(tableName); 127 } 128 } 129 try { 130 stub.moveTables(null, builder.build()); 131 } catch (ServiceException e) { 132 throw ProtobufUtil.handleRemoteException(e); 133 } 134 } 135 136 @Override 137 public void addRSGroup(String groupName) throws IOException { 138 AddRSGroupRequest request = AddRSGroupRequest.newBuilder().setRSGroupName(groupName).build(); 139 try { 140 stub.addRSGroup(null, request); 141 } catch (ServiceException e) { 142 throw ProtobufUtil.handleRemoteException(e); 143 } 144 } 145 146 @Override 147 public void removeRSGroup(String name) throws IOException { 148 RemoveRSGroupRequest request = RemoveRSGroupRequest.newBuilder().setRSGroupName(name).build(); 149 try { 150 stub.removeRSGroup(null, request); 151 } catch (ServiceException e) { 152 throw ProtobufUtil.handleRemoteException(e); 153 } 154 } 155 156 @Override 157 public BalanceResponse balanceRSGroup(String groupName, BalanceRequest request) 158 throws IOException { 159 try { 160 RSGroupAdminProtos.BalanceRSGroupRequest req = 161 RSGroupProtobufUtil.createBalanceRSGroupRequest(groupName, request); 162 return RSGroupProtobufUtil.toBalanceResponse(stub.balanceRSGroup(null, req)); 163 } catch (ServiceException e) { 164 throw ProtobufUtil.handleRemoteException(e); 165 } 166 } 167 168 @Override 169 public List<RSGroupInfo> listRSGroups() throws IOException { 170 try { 171 List<RSGroupProtos.RSGroupInfo> resp = stub 172 .listRSGroupInfos(null, ListRSGroupInfosRequest.getDefaultInstance()).getRSGroupInfoList(); 173 List<RSGroupInfo> result = new ArrayList<>(resp.size()); 174 for (RSGroupProtos.RSGroupInfo entry : resp) { 175 result.add(RSGroupProtobufUtil.toGroupInfo(entry)); 176 } 177 return result; 178 } catch (ServiceException e) { 179 throw ProtobufUtil.handleRemoteException(e); 180 } 181 } 182 183 @Override 184 public RSGroupInfo getRSGroupOfServer(Address hostPort) throws IOException { 185 GetRSGroupInfoOfServerRequest request = 186 GetRSGroupInfoOfServerRequest.newBuilder().setServer(HBaseProtos.ServerName.newBuilder() 187 .setHostName(hostPort.getHostname()).setPort(hostPort.getPort()).build()).build(); 188 try { 189 GetRSGroupInfoOfServerResponse resp = stub.getRSGroupInfoOfServer(null, request); 190 if (resp.hasRSGroupInfo()) { 191 return RSGroupProtobufUtil.toGroupInfo(resp.getRSGroupInfo()); 192 } 193 return null; 194 } catch (ServiceException e) { 195 throw ProtobufUtil.handleRemoteException(e); 196 } 197 } 198 199 @Override 200 public void moveServersAndTables(Set<Address> servers, Set<TableName> tables, String targetGroup) 201 throws IOException { 202 MoveServersAndTablesRequest.Builder builder = 203 MoveServersAndTablesRequest.newBuilder().setTargetGroup(targetGroup); 204 for (Address el : servers) { 205 builder.addServers(HBaseProtos.ServerName.newBuilder().setHostName(el.getHostname()) 206 .setPort(el.getPort()).build()); 207 } 208 for (TableName tableName : tables) { 209 builder.addTableName(ProtobufUtil.toProtoTableName(tableName)); 210 if (!admin.tableExists(tableName)) { 211 throw new TableNotFoundException(tableName); 212 } 213 } 214 try { 215 stub.moveServersAndTables(null, builder.build()); 216 } catch (ServiceException e) { 217 throw ProtobufUtil.handleRemoteException(e); 218 } 219 } 220 221 @Override 222 public void removeServers(Set<Address> servers) throws IOException { 223 Set<HBaseProtos.ServerName> hostPorts = Sets.newHashSet(); 224 for (Address el : servers) { 225 hostPorts.add(HBaseProtos.ServerName.newBuilder().setHostName(el.getHostname()) 226 .setPort(el.getPort()).build()); 227 } 228 RemoveServersRequest request = 229 RemoveServersRequest.newBuilder().addAllServers(hostPorts).build(); 230 try { 231 stub.removeServers(null, request); 232 } catch (ServiceException e) { 233 throw ProtobufUtil.handleRemoteException(e); 234 } 235 } 236 237 @Override 238 public void renameRSGroup(String oldName, String newName) throws IOException { 239 RenameRSGroupRequest request = RenameRSGroupRequest.newBuilder().setOldRsgroupName(oldName) 240 .setNewRsgroupName(newName).build(); 241 try { 242 stub.renameRSGroup(null, request); 243 } catch (ServiceException e) { 244 throw ProtobufUtil.handleRemoteException(e); 245 } 246 } 247 248 @Override 249 public void updateRSGroupConfig(String groupName, Map<String, String> configuration) 250 throws IOException { 251 UpdateRSGroupConfigRequest.Builder builder = 252 UpdateRSGroupConfigRequest.newBuilder().setGroupName(groupName); 253 if (configuration != null) { 254 configuration.entrySet().forEach(e -> builder.addConfiguration( 255 NameStringPair.newBuilder().setName(e.getKey()).setValue(e.getValue()).build())); 256 } 257 try { 258 stub.updateRSGroupConfig(null, builder.build()); 259 } catch (ServiceException e) { 260 throw ProtobufUtil.handleRemoteException(e); 261 } 262 } 263 264 @Override 265 public void updateConfiguration(String groupName) throws IOException { 266 RSGroupInfo rsGroupInfo = getRSGroupInfo(groupName); 267 if (rsGroupInfo == null) { 268 throw new IllegalArgumentException("RSGroup does not exist: " + groupName); 269 } 270 ClusterMetrics status = admin.getClusterMetrics(EnumSet.of(ClusterMetrics.Option.SERVERS_NAME)); 271 List<ServerName> groupServers = status.getServersName().stream() 272 .filter(s -> rsGroupInfo.containsServer(s.getAddress())).collect(Collectors.toList()); 273 for (ServerName server : groupServers) { 274 admin.updateConfiguration(server); 275 } 276 } 277}