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  package org.apache.hadoop.hbase.regionserver;
19  
20  import static org.junit.Assert.assertNull;
21  import static org.junit.Assert.assertTrue;
22  
23  import java.net.InetAddress;
24  import java.net.NetworkInterface;
25  import java.util.Enumeration;
26  import java.util.List;
27  
28  import org.apache.commons.logging.Log;
29  import org.apache.commons.logging.LogFactory;
30  import org.apache.hadoop.conf.Configuration;
31  import org.apache.hadoop.hbase.HBaseConfiguration;
32  import org.apache.hadoop.hbase.HBaseTestingUtility;
33  import org.apache.hadoop.hbase.testclassification.MediumTests;
34  import org.apache.hadoop.hbase.util.Threads;
35  import org.apache.hadoop.hbase.zookeeper.ZKUtil;
36  import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
37  import org.junit.After;
38  import org.junit.Before;
39  import org.junit.Test;
40  import org.junit.experimental.categories.Category;
41  
42  /**
43   * Tests for the hostname specification by region server
44   */
45  @Category({MediumTests.class})
46  public class TestRegionServerHostname {
47    private static final Log LOG = LogFactory.getLog(TestRegionServerHostname.class);
48  
49    private HBaseTestingUtility TEST_UTIL;
50  
51    private static final int NUM_MASTERS = 1;
52    private static final int NUM_RS = 1;
53  
54    @Before
55    public void setup() {
56      Configuration conf = HBaseConfiguration.create();
57      TEST_UTIL = new HBaseTestingUtility(conf);
58    }
59  
60    @After
61    public void teardown() throws Exception {
62      TEST_UTIL.shutdownMiniCluster();
63    }
64  
65    @Test(timeout=30000)
66    public void testInvalidRegionServerHostnameAbortsServer() throws Exception {
67      String invalidHostname = "hostAddr.invalid";
68      TEST_UTIL.getConfiguration().set(HRegionServer.RS_HOSTNAME_KEY, invalidHostname);
69      HRegionServer hrs = null;
70      try {
71        hrs = new HRegionServer(TEST_UTIL.getConfiguration(), null);
72      } catch (IllegalArgumentException iae) {
73        assertTrue(iae.getMessage(),
74          iae.getMessage().contains("Failed resolve of " + invalidHostname) ||
75          iae.getMessage().contains("Problem binding to " + invalidHostname));
76      }
77      assertNull("Failed to validate against invalid hostname", hrs);
78    }
79  
80    @Test(timeout=120000)
81    public void testRegionServerHostname() throws Exception {
82      Enumeration<NetworkInterface> netInterfaceList = NetworkInterface.getNetworkInterfaces();
83      while (netInterfaceList.hasMoreElements()) {
84        NetworkInterface ni = netInterfaceList.nextElement();
85        Enumeration<InetAddress> addrList = ni.getInetAddresses();
86        // iterate through host addresses and use each as hostname
87        while (addrList.hasMoreElements()) {
88          InetAddress addr = addrList.nextElement();
89          if (addr.isLoopbackAddress() || addr.isLinkLocalAddress() || addr.isMulticastAddress()) {
90            continue;
91          }
92          String hostName = addr.getHostName();
93          LOG.info("Found " + hostName + " on " + ni);
94          
95          TEST_UTIL.getConfiguration().set(HRegionServer.RS_HOSTNAME_KEY, hostName);
96          TEST_UTIL.startMiniCluster(NUM_MASTERS, NUM_RS);
97          try {
98            ZooKeeperWatcher zkw = TEST_UTIL.getZooKeeperWatcher();
99            List<String> servers = ZKUtil.listChildrenNoWatch(zkw, zkw.rsZNode);
100           while (servers == null) {
101             Threads.sleep(10);
102             servers = ZKUtil.listChildrenNoWatch(zkw, zkw.rsZNode);
103           }
104           assertTrue(servers.size() == NUM_RS);
105           for (String server : servers) {
106             assertTrue(server.startsWith(hostName.toLowerCase()+","));
107           }
108           zkw.close();
109         } finally {
110           TEST_UTIL.shutdownMiniCluster();
111         }
112       }
113     }
114   }
115 
116   @Test(timeout=30000)
117   public void testConflictRegionServerHostnameConfigurationsAbortServer() throws Exception {
118     Enumeration<NetworkInterface> netInterfaceList = NetworkInterface.getNetworkInterfaces();
119     while (netInterfaceList.hasMoreElements()) {
120       NetworkInterface ni = netInterfaceList.nextElement();
121       Enumeration<InetAddress> addrList = ni.getInetAddresses();
122       // iterate through host addresses and use each as hostname
123       while (addrList.hasMoreElements()) {
124         InetAddress addr = addrList.nextElement();
125         if (addr.isLoopbackAddress() || addr.isLinkLocalAddress() || addr.isMulticastAddress()) {
126           continue;
127         }
128         String hostName = addr.getHostName();
129         LOG.info("Found " + hostName + " on " + ni);
130 
131         TEST_UTIL.getConfiguration().set(HRegionServer.MASTER_HOSTNAME_KEY, hostName);
132         // "hbase.regionserver.hostname" and "hbase.regionserver.hostname.disable.master.reversedns"
133         // are mutually exclusive. Exception should be thrown if both are used.
134         TEST_UTIL.getConfiguration().set(HRegionServer.RS_HOSTNAME_KEY, hostName);
135         TEST_UTIL.getConfiguration().setBoolean(HRegionServer.RS_HOSTNAME_DISABLE_MASTER_REVERSEDNS_KEY, true);
136         try {
137           TEST_UTIL.startMiniCluster(NUM_MASTERS, NUM_RS);
138         } catch (Exception e) {
139           Throwable t1 = e.getCause();
140           Throwable t2 = t1.getCause();
141           assertTrue(t1.getMessage()+" - "+t2.getMessage(), t2.getMessage().contains(
142             HRegionServer.RS_HOSTNAME_DISABLE_MASTER_REVERSEDNS_KEY + " and " + HRegionServer.RS_HOSTNAME_KEY +
143             " are mutually exclusive"));
144           return;
145         } finally {
146           TEST_UTIL.shutdownMiniCluster();
147         }
148         assertTrue("Failed to validate against conflict hostname configurations", false);
149       }
150     }
151   }
152 
153   @Test(timeout=30000)
154   public void testRegionServerHostnameReportedToMaster() throws Exception {
155     TEST_UTIL.getConfiguration().setBoolean(HRegionServer.RS_HOSTNAME_DISABLE_MASTER_REVERSEDNS_KEY, true);
156     TEST_UTIL.startMiniCluster(NUM_MASTERS, NUM_RS);
157     try (ZooKeeperWatcher zkw = TEST_UTIL.getZooKeeperWatcher()) {
158       List<String> servers = ZKUtil.listChildrenNoWatch(zkw, zkw.rsZNode);
159       // there would be NUM_RS+1 children - one for the master
160       assertTrue(servers.size() == NUM_RS);
161     }
162   }
163 }