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.regionserver; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertNull; 022import static org.junit.Assert.assertTrue; 023 024import java.net.InetAddress; 025import java.net.NetworkInterface; 026import java.util.Enumeration; 027import java.util.List; 028import java.util.Locale; 029import org.apache.hadoop.conf.Configuration; 030import org.apache.hadoop.hbase.HBaseClassTestRule; 031import org.apache.hadoop.hbase.HBaseConfiguration; 032import org.apache.hadoop.hbase.HBaseTestingUtility; 033import org.apache.hadoop.hbase.StartMiniClusterOption; 034import org.apache.hadoop.hbase.master.LoadBalancer; 035import org.apache.hadoop.hbase.testclassification.MediumTests; 036import org.apache.hadoop.hbase.testclassification.RegionServerTests; 037import org.apache.hadoop.hbase.zookeeper.ZKUtil; 038import org.apache.hadoop.hbase.zookeeper.ZKWatcher; 039import org.junit.After; 040import org.junit.Before; 041import org.junit.ClassRule; 042import org.junit.Test; 043import org.junit.experimental.categories.Category; 044import org.slf4j.Logger; 045import org.slf4j.LoggerFactory; 046 047/** 048 * Tests for the hostname specification by region server 049 */ 050@Category({RegionServerTests.class, MediumTests.class}) 051public class TestRegionServerHostname { 052 053 @ClassRule 054 public static final HBaseClassTestRule CLASS_RULE = 055 HBaseClassTestRule.forClass(TestRegionServerHostname.class); 056 057 private static final Logger LOG = LoggerFactory.getLogger(TestRegionServerHostname.class); 058 059 private HBaseTestingUtility TEST_UTIL; 060 061 private static final int NUM_MASTERS = 1; 062 private static final int NUM_RS = 1; 063 064 @Before 065 public void setup() { 066 Configuration conf = HBaseConfiguration.create(); 067 TEST_UTIL = new HBaseTestingUtility(conf); 068 } 069 070 @After 071 public void teardown() throws Exception { 072 TEST_UTIL.shutdownMiniCluster(); 073 } 074 075 @Test 076 public void testInvalidRegionServerHostnameAbortsServer() throws Exception { 077 String invalidHostname = "hostAddr.invalid"; 078 TEST_UTIL.getConfiguration().set(HRegionServer.RS_HOSTNAME_KEY, invalidHostname); 079 HRegionServer hrs = null; 080 try { 081 hrs = new HRegionServer(TEST_UTIL.getConfiguration()); 082 } catch (IllegalArgumentException iae) { 083 assertTrue(iae.getMessage(), 084 iae.getMessage().contains("Failed resolve of " + invalidHostname) || 085 iae.getMessage().contains("Problem binding to " + invalidHostname)); 086 } 087 assertNull("Failed to validate against invalid hostname", hrs); 088 } 089 090 @Test 091 public void testRegionServerHostname() throws Exception { 092 Enumeration<NetworkInterface> netInterfaceList = NetworkInterface.getNetworkInterfaces(); 093 while (netInterfaceList.hasMoreElements()) { 094 NetworkInterface ni = netInterfaceList.nextElement(); 095 Enumeration<InetAddress> addrList = ni.getInetAddresses(); 096 // iterate through host addresses and use each as hostname 097 while (addrList.hasMoreElements()) { 098 InetAddress addr = addrList.nextElement(); 099 if (addr.isLoopbackAddress() || addr.isLinkLocalAddress() || addr.isMulticastAddress() || 100 !addr.isSiteLocalAddress()) { 101 continue; 102 } 103 String hostName = addr.getHostName(); 104 LOG.info("Found " + hostName + " on " + ni + ", addr=" + addr); 105 106 TEST_UTIL.getConfiguration().set(HRegionServer.MASTER_HOSTNAME_KEY, hostName); 107 TEST_UTIL.getConfiguration().set(HRegionServer.RS_HOSTNAME_KEY, hostName); 108 StartMiniClusterOption option = StartMiniClusterOption.builder() 109 .numMasters(NUM_MASTERS).numRegionServers(NUM_RS).numDataNodes(NUM_RS).build(); 110 TEST_UTIL.startMiniCluster(option); 111 try { 112 ZKWatcher zkw = TEST_UTIL.getZooKeeperWatcher(); 113 List<String> servers = ZKUtil.listChildrenNoWatch(zkw, zkw.getZNodePaths().rsZNode); 114 // there would be NUM_RS+1 children - one for the master 115 assertTrue(servers.size() == 116 NUM_RS + (LoadBalancer.isTablesOnMaster(TEST_UTIL.getConfiguration())? 1: 0)); 117 for (String server : servers) { 118 assertTrue("From zookeeper: " + server + " hostname: " + hostName, 119 server.startsWith(hostName.toLowerCase(Locale.ROOT)+",")); 120 } 121 zkw.close(); 122 } finally { 123 TEST_UTIL.shutdownMiniCluster(); 124 } 125 } 126 } 127 } 128 129 @Test 130 public void testConflictRegionServerHostnameConfigurationsAbortServer() throws Exception { 131 Enumeration<NetworkInterface> netInterfaceList = NetworkInterface.getNetworkInterfaces(); 132 while (netInterfaceList.hasMoreElements()) { 133 NetworkInterface ni = netInterfaceList.nextElement(); 134 Enumeration<InetAddress> addrList = ni.getInetAddresses(); 135 // iterate through host addresses and use each as hostname 136 while (addrList.hasMoreElements()) { 137 InetAddress addr = addrList.nextElement(); 138 if (addr.isLoopbackAddress() || addr.isLinkLocalAddress() || addr.isMulticastAddress()) { 139 continue; 140 } 141 String hostName = addr.getHostName(); 142 LOG.info("Found " + hostName + " on " + ni); 143 144 TEST_UTIL.getConfiguration().set(HRegionServer.MASTER_HOSTNAME_KEY, hostName); 145 // "hbase.regionserver.hostname" and "hbase.regionserver.hostname.disable.master.reversedns" 146 // are mutually exclusive. Exception should be thrown if both are used. 147 TEST_UTIL.getConfiguration().set(HRegionServer.RS_HOSTNAME_KEY, hostName); 148 TEST_UTIL.getConfiguration().setBoolean(HRegionServer.RS_HOSTNAME_DISABLE_MASTER_REVERSEDNS_KEY, true); 149 try { 150 StartMiniClusterOption option = StartMiniClusterOption.builder() 151 .numMasters(NUM_MASTERS).numRegionServers(NUM_RS).numDataNodes(NUM_RS).build(); 152 TEST_UTIL.startMiniCluster(option); 153 } catch (Exception e) { 154 Throwable t1 = e.getCause(); 155 Throwable t2 = t1.getCause(); 156 assertTrue(t1.getMessage()+" - "+t2.getMessage(), t2.getMessage().contains( 157 HRegionServer.RS_HOSTNAME_DISABLE_MASTER_REVERSEDNS_KEY + " and " + HRegionServer.RS_HOSTNAME_KEY + 158 " are mutually exclusive")); 159 return; 160 } finally { 161 TEST_UTIL.shutdownMiniCluster(); 162 } 163 assertTrue("Failed to validate against conflict hostname configurations", false); 164 } 165 } 166 } 167 168 @Test 169 public void testRegionServerHostnameReportedToMaster() throws Exception { 170 TEST_UTIL.getConfiguration().setBoolean(HRegionServer.RS_HOSTNAME_DISABLE_MASTER_REVERSEDNS_KEY, 171 true); 172 StartMiniClusterOption option = StartMiniClusterOption.builder() 173 .numMasters(NUM_MASTERS).numRegionServers(NUM_RS).numDataNodes(NUM_RS).build(); 174 TEST_UTIL.startMiniCluster(option); 175 boolean tablesOnMaster = LoadBalancer.isTablesOnMaster(TEST_UTIL.getConfiguration()); 176 int expectedRS = NUM_RS + (tablesOnMaster? 1: 0); 177 try (ZKWatcher zkw = TEST_UTIL.getZooKeeperWatcher()) { 178 List<String> servers = ZKUtil.listChildrenNoWatch(zkw, zkw.getZNodePaths().rsZNode); 179 assertEquals(expectedRS, servers.size()); 180 } 181 } 182}