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