View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.apache.hadoop.hbase.client;
20  
21  import static org.junit.Assert.assertEquals;
22  import static org.junit.Assert.assertTrue;
23  
24  import com.google.protobuf.ServiceException;
25  import java.io.IOException;
26  import java.net.UnknownHostException;
27  import java.util.Arrays;
28  import java.util.HashSet;
29  import java.util.List;
30  import java.util.Set;
31  import org.apache.hadoop.hbase.HBaseTestingUtility;
32  import org.apache.hadoop.hbase.HColumnDescriptor;
33  import org.apache.hadoop.hbase.HConstants;
34  import org.apache.hadoop.hbase.HRegionLocation;
35  import org.apache.hadoop.hbase.HTableDescriptor;
36  import org.apache.hadoop.hbase.NotServingRegionException;
37  import org.apache.hadoop.hbase.ServerName;
38  import org.apache.hadoop.hbase.TableName;
39  import org.apache.hadoop.hbase.ipc.HBaseRpcController;
40  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos;
41  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos;
42  import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos;
43  import org.apache.hadoop.hbase.testclassification.ClientTests;
44  import org.apache.hadoop.hbase.testclassification.MediumTests;
45  import org.apache.hadoop.hbase.util.ByteStringer;
46  import org.apache.hadoop.hbase.util.Bytes;
47  import org.junit.AfterClass;
48  import org.junit.BeforeClass;
49  import org.junit.Test;
50  import org.junit.experimental.categories.Category;
51  
52  /**
53   * Tests that we fail fast when hostname resolution is not working and do not cache
54   * unresolved InetSocketAddresses.
55   */
56  @Category({MediumTests.class, ClientTests.class})
57  public class TestConnectionImplementation {
58    private static HBaseTestingUtility testUtil;
59    private static ConnectionManager.HConnectionImplementation conn;
60    private static HBaseProtos.RegionSpecifier specifier;
61  
62    @BeforeClass
63    public static void setupBeforeClass() throws Exception {
64      testUtil = HBaseTestingUtility.createLocalHTU();
65      testUtil.startMiniCluster();
66      conn = (ConnectionManager.HConnectionImplementation) testUtil.getConnection();
67      specifier = HBaseProtos.RegionSpecifier.
68        newBuilder().setValue(ByteStringer.wrap(Bytes.toBytes("region")))
69        .setType(HBaseProtos.RegionSpecifier.RegionSpecifierType.REGION_NAME).build();
70    }
71  
72    @AfterClass
73    public static void teardownAfterClass() throws Exception {
74      conn.close();
75      testUtil.shutdownMiniCluster();
76    }
77  
78    @Test
79    public void testGetAdminBadHostname() throws Exception {
80      // verify that we can get an instance with the cluster hostname
81      ServerName master = testUtil.getHBaseCluster().getMaster().getServerName();
82      HBaseRpcController controller = conn.getRpcControllerFactory().newController();
83  
84      AdminProtos.GetRegionInfoRequest request =
85        AdminProtos.GetRegionInfoRequest.newBuilder().setRegion(specifier).build();
86      AdminProtos.AdminService.BlockingInterface goodAdmin = conn.getAdmin(master);
87      verifyAdminCall(goodAdmin, controller, request, false);
88  
89      // test that we fail to get a client to an unresolvable hostname, which
90      // means it won't be cached
91      ServerName badHost = ServerName
92        .valueOf("unknownhost.invalid:" + HConstants.DEFAULT_MASTER_PORT, System.currentTimeMillis());
93      AdminProtos.AdminService.BlockingInterface badAdmin = conn.getAdmin(badHost);
94      verifyAdminCall(badAdmin, controller, request, true);
95    }
96  
97    private void verifyAdminCall(AdminProtos.AdminService.BlockingInterface admin,
98      HBaseRpcController rpcController, AdminProtos.GetRegionInfoRequest request,
99      boolean shouldHaveHostException) {
100 
101     try {
102       admin.getRegionInfo(rpcController, request);
103     } catch (ServiceException se) {
104       assertEquals(shouldHaveHostException, se.getCause() instanceof UnknownHostException);
105     } catch (Exception e) {
106       assertEquals(!shouldHaveHostException, e instanceof NotServingRegionException);
107     }
108   }
109 
110   @Test
111   public void testGetClientBadHostname()
112     throws Exception {
113     // verify that we can get an instance with the cluster hostname
114     ServerName rs = testUtil.getHBaseCluster().getRegionServer(0).getServerName();
115     HBaseRpcController controller = conn.getRpcControllerFactory().newController();
116     ClientProtos.Get get = ClientProtos.Get.newBuilder()
117       .setRow(ByteStringer.wrap(Bytes.toBytes("r"))).build();
118     ClientProtos.GetRequest request = ClientProtos.GetRequest.newBuilder().setGet(get)
119       .setRegion(specifier).build();
120 
121     ClientProtos.ClientService.BlockingInterface goodClient = conn.getClient(rs);
122     verifyClientCall(goodClient, controller, request, false);
123 
124     ServerName badHost = ServerName
125       .valueOf("unknownhost.invalid:" + HConstants.DEFAULT_REGIONSERVER_PORT,
126         System.currentTimeMillis());
127     ClientProtos.ClientService.BlockingInterface badClient = conn.getClient(badHost);
128     verifyClientCall(badClient, controller, request, true);
129   }
130 
131   private void verifyClientCall(ClientProtos.ClientService.BlockingInterface client,
132     HBaseRpcController rpcController, ClientProtos.GetRequest request,
133     boolean shouldHaveHostException) {
134     try {
135       client.get(rpcController, request);
136     } catch (ServiceException se) {
137       assertEquals(shouldHaveHostException, se.getCause() instanceof UnknownHostException);
138     } catch (Exception e) {
139       assertEquals(!shouldHaveHostException, e instanceof NotServingRegionException);
140     }
141   }
142 
143   @Test
144   public void testLocateRegionsWithRegionReplicas() throws IOException {
145     int regionReplication = 3;
146     byte[] family = Bytes.toBytes("cf");
147     TableName tableName = TableName.valueOf("testLocateRegionsWithRegionReplicas");
148 
149     // Create a table with region replicas
150     HTableDescriptor desc = new HTableDescriptor(tableName);
151     desc.addFamily(new HColumnDescriptor(family));
152     desc.setRegionReplication(regionReplication);
153     testUtil.getConnection().getAdmin().createTable(desc);
154 
155     try (ConnectionManager.HConnectionImplementation con =
156       (ConnectionManager.HConnectionImplementation) ConnectionFactory.
157         createConnection(testUtil.getConfiguration())) {
158 
159       // Get locations of the regions of the table
160       List<HRegionLocation> locations = con.locateRegions(tableName, false, false);
161 
162       // The size of the returned locations should be 3
163       assertEquals(regionReplication, locations.size());
164 
165       // The replicaIds of the returned locations should be 0, 1 and 2
166       Set<Integer> expectedReplicaIds = new HashSet<>(Arrays.asList(0, 1, 2));
167       for (HRegionLocation location : locations) {
168         assertTrue(expectedReplicaIds.remove(location.getRegionInfo().getReplicaId()));
169       }
170     } finally {
171       testUtil.deleteTable(tableName);
172     }
173   }
174 }