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