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.master;
019
020import static org.apache.hadoop.hbase.HConstants.DEFAULT_HBASE_RPC_TIMEOUT;
021import static org.apache.hadoop.hbase.HConstants.HBASE_RPC_TIMEOUT_KEY;
022import static org.junit.jupiter.api.Assertions.assertEquals;
023
024import java.io.IOException;
025import java.util.ArrayList;
026import java.util.Collections;
027import java.util.List;
028import java.util.concurrent.TimeUnit;
029import org.apache.hadoop.conf.Configuration;
030import org.apache.hadoop.hbase.HBaseTestingUtil;
031import org.apache.hadoop.hbase.HRegionLocation;
032import org.apache.hadoop.hbase.ServerName;
033import org.apache.hadoop.hbase.StartTestingClusterOption;
034import org.apache.hadoop.hbase.ipc.HBaseRpcController;
035import org.apache.hadoop.hbase.ipc.RpcClient;
036import org.apache.hadoop.hbase.ipc.RpcClientFactory;
037import org.apache.hadoop.hbase.ipc.RpcControllerFactory;
038import org.apache.hadoop.hbase.security.User;
039import org.apache.hadoop.hbase.testclassification.MasterTests;
040import org.apache.hadoop.hbase.testclassification.MediumTests;
041import org.apache.hadoop.hbase.util.JVMClusterUtil;
042import org.junit.jupiter.api.AfterAll;
043import org.junit.jupiter.api.BeforeAll;
044import org.junit.jupiter.api.Tag;
045import org.junit.jupiter.api.Test;
046
047import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
048import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.ClientMetaService;
049import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.GetActiveMasterRequest;
050import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.GetActiveMasterResponse;
051import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.GetClusterIdRequest;
052import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.GetClusterIdResponse;
053import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.GetMetaRegionLocationsRequest;
054import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.GetMetaRegionLocationsResponse;
055
056@Tag(MediumTests.TAG)
057@Tag(MasterTests.TAG)
058public class TestClientMetaServiceRPCs {
059
060  // Total number of masters (active + stand by) for the purpose of this test.
061  private static final int MASTER_COUNT = 3;
062  private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
063  private static Configuration conf;
064  private static int rpcTimeout;
065  private static RpcClient rpcClient;
066
067  @BeforeAll
068  public static void setUp() throws Exception {
069    // Start the mini cluster with stand-by masters.
070    StartTestingClusterOption.Builder builder = StartTestingClusterOption.builder();
071    builder.numMasters(MASTER_COUNT).numRegionServers(3);
072    TEST_UTIL.startMiniCluster(builder.build());
073    conf = TEST_UTIL.getConfiguration();
074    rpcTimeout = (int) Math.min(Integer.MAX_VALUE, TimeUnit.MILLISECONDS
075      .toNanos(conf.getLong(HBASE_RPC_TIMEOUT_KEY, DEFAULT_HBASE_RPC_TIMEOUT)));
076    rpcClient = RpcClientFactory.createClient(conf,
077      TEST_UTIL.getMiniHBaseCluster().getMaster().getClusterId());
078  }
079
080  @AfterAll
081  public static void tearDown() throws Exception {
082    if (rpcClient != null) {
083      rpcClient.close();
084    }
085    TEST_UTIL.shutdownMiniCluster();
086  }
087
088  private static ClientMetaService.BlockingInterface getMasterStub(ServerName server)
089    throws IOException {
090    return ClientMetaService
091      .newBlockingStub(rpcClient.createBlockingRpcChannel(server, User.getCurrent(), rpcTimeout));
092  }
093
094  private static HBaseRpcController getRpcController() {
095    return RpcControllerFactory.instantiate(conf).newController();
096  }
097
098  /**
099   * Verifies the cluster ID from all running masters.
100   */
101  @Test
102  public void TestClusterID() throws Exception {
103    HBaseRpcController rpcController = getRpcController();
104    String clusterID = TEST_UTIL.getMiniHBaseCluster().getMaster().getClusterId();
105    int rpcCount = 0;
106    for (JVMClusterUtil.MasterThread masterThread : TEST_UTIL.getMiniHBaseCluster()
107      .getMasterThreads()) {
108      ClientMetaService.BlockingInterface stub =
109        getMasterStub(masterThread.getMaster().getServerName());
110      GetClusterIdResponse resp =
111        stub.getClusterId(rpcController, GetClusterIdRequest.getDefaultInstance());
112      assertEquals(clusterID, resp.getClusterId());
113      rpcCount++;
114    }
115    assertEquals(MASTER_COUNT, rpcCount);
116  }
117
118  /**
119   * Verifies the active master ServerName as seen by all masters.
120   */
121  @Test
122  public void TestActiveMaster() throws Exception {
123    HBaseRpcController rpcController = getRpcController();
124    ServerName activeMaster = TEST_UTIL.getMiniHBaseCluster().getMaster().getServerName();
125    int rpcCount = 0;
126    for (JVMClusterUtil.MasterThread masterThread : TEST_UTIL.getMiniHBaseCluster()
127      .getMasterThreads()) {
128      ClientMetaService.BlockingInterface stub =
129        getMasterStub(masterThread.getMaster().getServerName());
130      GetActiveMasterResponse resp =
131        stub.getActiveMaster(rpcController, GetActiveMasterRequest.getDefaultInstance());
132      assertEquals(activeMaster, ProtobufUtil.toServerName(resp.getServerName()));
133      rpcCount++;
134    }
135    assertEquals(MASTER_COUNT, rpcCount);
136  }
137
138  /**
139   * Verifies that the meta region locations RPC returns consistent results across all masters.
140   */
141  @Test
142  public void TestMetaLocations() throws Exception {
143    HBaseRpcController rpcController = getRpcController();
144    List<HRegionLocation> metaLocations =
145      TEST_UTIL.getMiniHBaseCluster().getMaster().getMetaLocations();
146    Collections.sort(metaLocations);
147    int rpcCount = 0;
148    for (JVMClusterUtil.MasterThread masterThread : TEST_UTIL.getMiniHBaseCluster()
149      .getMasterThreads()) {
150      ClientMetaService.BlockingInterface stub =
151        getMasterStub(masterThread.getMaster().getServerName());
152      GetMetaRegionLocationsResponse resp = stub.getMetaRegionLocations(rpcController,
153        GetMetaRegionLocationsRequest.getDefaultInstance());
154      List<HRegionLocation> result = new ArrayList<>();
155      resp.getMetaLocationsList()
156        .forEach(location -> result.add(ProtobufUtil.toRegionLocation(location)));
157      Collections.sort(result);
158      assertEquals(metaLocations, result);
159      rpcCount++;
160    }
161    assertEquals(MASTER_COUNT, rpcCount);
162  }
163}