001/*
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 *     http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 */
019package org.apache.hadoop.hbase.master;
020
021import static org.apache.hadoop.hbase.HConstants.DEFAULT_HBASE_RPC_TIMEOUT;
022import static org.apache.hadoop.hbase.HConstants.HBASE_RPC_TIMEOUT_KEY;
023import static org.junit.Assert.assertEquals;
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.HBaseClassTestRule;
031import org.apache.hadoop.hbase.HBaseTestingUtility;
032import org.apache.hadoop.hbase.HRegionLocation;
033import org.apache.hadoop.hbase.ServerName;
034import org.apache.hadoop.hbase.StartMiniClusterOption;
035import org.apache.hadoop.hbase.ipc.HBaseRpcController;
036import org.apache.hadoop.hbase.ipc.RpcClient;
037import org.apache.hadoop.hbase.ipc.RpcClientFactory;
038import org.apache.hadoop.hbase.ipc.RpcControllerFactory;
039import org.apache.hadoop.hbase.security.User;
040import org.apache.hadoop.hbase.testclassification.MasterTests;
041import org.apache.hadoop.hbase.testclassification.MediumTests;
042import org.apache.hadoop.hbase.util.JVMClusterUtil;
043import org.junit.AfterClass;
044import org.junit.BeforeClass;
045import org.junit.ClassRule;
046import org.junit.Test;
047import org.junit.experimental.categories.Category;
048import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
049import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ClientMetaService;
050import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetActiveMasterRequest;
051import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetActiveMasterResponse;
052import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetClusterIdRequest;
053import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetClusterIdResponse;
054import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetMetaRegionLocationsRequest;
055import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetMetaRegionLocationsResponse;
056
057@Category({MediumTests.class, MasterTests.class})
058public class TestClientMetaServiceRPCs {
059
060  @ClassRule
061  public static final HBaseClassTestRule CLASS_RULE =
062      HBaseClassTestRule.forClass(TestClientMetaServiceRPCs.class);
063
064  // Total number of masters (active + stand by) for the purpose of this test.
065  private static final int MASTER_COUNT = 3;
066  private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
067  private static Configuration conf;
068  private static int rpcTimeout;
069  private static RpcClient rpcClient;
070
071  @BeforeClass
072  public static void setUp() throws Exception {
073    // Start the mini cluster with stand-by masters.
074    StartMiniClusterOption.Builder builder = StartMiniClusterOption.builder();
075    builder.numMasters(MASTER_COUNT).numRegionServers(3);
076    TEST_UTIL.startMiniCluster(builder.build());
077    conf = TEST_UTIL.getConfiguration();
078    rpcTimeout = (int) Math.min(Integer.MAX_VALUE, TimeUnit.MILLISECONDS.toNanos(
079        conf.getLong(HBASE_RPC_TIMEOUT_KEY, DEFAULT_HBASE_RPC_TIMEOUT)));
080    rpcClient = RpcClientFactory.createClient(conf,
081        TEST_UTIL.getMiniHBaseCluster().getMaster().getClusterId());
082  }
083
084  @AfterClass
085  public static void tearDown() throws Exception {
086    if (rpcClient != null) {
087      rpcClient.close();
088    }
089    TEST_UTIL.shutdownMiniCluster();
090  }
091
092  private static ClientMetaService.BlockingInterface getMasterStub(ServerName server)
093      throws IOException {
094    return ClientMetaService.newBlockingStub(
095        rpcClient.createBlockingRpcChannel(server, User.getCurrent(), rpcTimeout));
096  }
097
098  private static HBaseRpcController getRpcController() {
099    return RpcControllerFactory.instantiate(conf).newController();
100  }
101
102  /**
103   * Verifies the cluster ID from all running masters.
104   */
105  @Test public void TestClusterID() throws Exception {
106    HBaseRpcController rpcController = getRpcController();
107    String clusterID = TEST_UTIL.getMiniHBaseCluster().getMaster().getClusterId();
108    int rpcCount = 0;
109    for (JVMClusterUtil.MasterThread masterThread:
110        TEST_UTIL.getMiniHBaseCluster().getMasterThreads()) {
111      ClientMetaService.BlockingInterface stub =
112          getMasterStub(masterThread.getMaster().getServerName());
113      GetClusterIdResponse resp =
114          stub.getClusterId(rpcController, GetClusterIdRequest.getDefaultInstance());
115      assertEquals(clusterID, resp.getClusterId());
116      rpcCount++;
117    }
118    assertEquals(MASTER_COUNT, rpcCount);
119  }
120
121  /**
122   * Verifies the active master ServerName as seen by all masters.
123   */
124  @Test public void TestActiveMaster() throws Exception {
125    HBaseRpcController rpcController = getRpcController();
126    ServerName activeMaster = TEST_UTIL.getMiniHBaseCluster().getMaster().getServerName();
127    int rpcCount = 0;
128    for (JVMClusterUtil.MasterThread masterThread:
129        TEST_UTIL.getMiniHBaseCluster().getMasterThreads()) {
130      ClientMetaService.BlockingInterface stub =
131          getMasterStub(masterThread.getMaster().getServerName());
132      GetActiveMasterResponse resp =
133          stub.getActiveMaster(rpcController, GetActiveMasterRequest.getDefaultInstance());
134      assertEquals(activeMaster, ProtobufUtil.toServerName(resp.getServerName()));
135      rpcCount++;
136    }
137    assertEquals(MASTER_COUNT, rpcCount);
138  }
139
140  /**
141   * Verifies that the meta region locations RPC returns consistent results across all masters.
142   */
143  @Test public void TestMetaLocations() throws Exception {
144    HBaseRpcController rpcController = getRpcController();
145    List<HRegionLocation> metaLocations = TEST_UTIL.getMiniHBaseCluster().getMaster()
146        .getMetaRegionLocationCache().getMetaRegionLocations().get();
147    Collections.sort(metaLocations);
148    int rpcCount = 0;
149    for (JVMClusterUtil.MasterThread masterThread:
150      TEST_UTIL.getMiniHBaseCluster().getMasterThreads()) {
151      ClientMetaService.BlockingInterface stub =
152          getMasterStub(masterThread.getMaster().getServerName());
153      GetMetaRegionLocationsResponse resp = stub.getMetaRegionLocations(
154          rpcController, GetMetaRegionLocationsRequest.getDefaultInstance());
155      List<HRegionLocation> result = new ArrayList<>();
156      resp.getMetaLocationsList().forEach(
157        location -> result.add(ProtobufUtil.toRegionLocation(location)));
158      Collections.sort(result);
159      assertEquals(metaLocations, result);
160      rpcCount++;
161    }
162    assertEquals(MASTER_COUNT, rpcCount);
163  }
164}