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.assertFalse; 022import static org.junit.Assert.assertNull; 023import static org.junit.Assert.assertTrue; 024 025import java.net.InetAddress; 026import java.net.NetworkInterface; 027import java.util.Enumeration; 028import java.util.List; 029import java.util.Locale; 030import org.apache.hadoop.conf.Configuration; 031import org.apache.hadoop.hbase.HBaseClassTestRule; 032import org.apache.hadoop.hbase.HBaseConfiguration; 033import org.apache.hadoop.hbase.HBaseTestingUtil; 034import org.apache.hadoop.hbase.StartTestingClusterOption; 035import org.apache.hadoop.hbase.testclassification.MediumTests; 036import org.apache.hadoop.hbase.testclassification.RegionServerTests; 037import org.apache.hadoop.hbase.util.DNS; 038import org.apache.hadoop.hbase.zookeeper.ZKUtil; 039import org.apache.hadoop.hbase.zookeeper.ZKWatcher; 040import org.junit.After; 041import org.junit.Before; 042import org.junit.ClassRule; 043import org.junit.Test; 044import org.junit.experimental.categories.Category; 045import org.slf4j.Logger; 046import org.slf4j.LoggerFactory; 047 048/** 049 * Tests for the hostname specification by region server 050 */ 051@Category({ RegionServerTests.class, MediumTests.class }) 052public class TestRegionServerHostname { 053 054 @ClassRule 055 public static final HBaseClassTestRule CLASS_RULE = 056 HBaseClassTestRule.forClass(TestRegionServerHostname.class); 057 058 private static final Logger LOG = LoggerFactory.getLogger(TestRegionServerHostname.class); 059 060 private HBaseTestingUtil TEST_UTIL; 061 062 private static final int NUM_MASTERS = 1; 063 private static final int NUM_RS = 1; 064 065 @Before 066 public void setup() { 067 Configuration conf = HBaseConfiguration.create(); 068 TEST_UTIL = new HBaseTestingUtil(conf); 069 } 070 071 @After 072 public void teardown() throws Exception { 073 TEST_UTIL.shutdownMiniCluster(); 074 } 075 076 @Test 077 public void testInvalidRegionServerHostnameAbortsServer() throws Exception { 078 String invalidHostname = "hostAddr.invalid"; 079 TEST_UTIL.getConfiguration().set(DNS.UNSAFE_RS_HOSTNAME_KEY, invalidHostname); 080 HRegionServer hrs = null; 081 try { 082 hrs = new HRegionServer(TEST_UTIL.getConfiguration()); 083 } catch (IllegalArgumentException iae) { 084 assertTrue(iae.getMessage(), 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 ( 100 addr.isLoopbackAddress() || addr.isLinkLocalAddress() || addr.isMulticastAddress() 101 || !addr.isSiteLocalAddress() 102 ) { 103 continue; 104 } 105 String hostName = addr.getHostName(); 106 LOG.info("Found " + hostName + " on " + ni + ", addr=" + addr); 107 108 TEST_UTIL.getConfiguration().set(DNS.MASTER_HOSTNAME_KEY, hostName); 109 TEST_UTIL.getConfiguration().set(DNS.UNSAFE_RS_HOSTNAME_KEY, hostName); 110 StartTestingClusterOption option = StartTestingClusterOption.builder() 111 .numMasters(NUM_MASTERS).numRegionServers(NUM_RS).numDataNodes(NUM_RS).build(); 112 TEST_UTIL.startMiniCluster(option); 113 try { 114 ZKWatcher zkw = TEST_UTIL.getZooKeeperWatcher(); 115 List<String> servers = ZKUtil.listChildrenNoWatch(zkw, zkw.getZNodePaths().rsZNode); 116 assertEquals(NUM_RS, servers.size()); 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 testDeprecatedConfigs() throws Exception { 131 Configuration conf = TEST_UTIL.getConfiguration(); 132 new HRegionServer(conf); 133 conf.setBoolean(HRegionServer.RS_HOSTNAME_DISABLE_MASTER_REVERSEDNS_KEY, false); 134 assertFalse( 135 conf.getBoolean(HRegionServer.UNSAFE_RS_HOSTNAME_DISABLE_MASTER_REVERSEDNS_KEY, true)); 136 conf.setBoolean(HRegionServer.RS_HOSTNAME_DISABLE_MASTER_REVERSEDNS_KEY, true); 137 assertTrue( 138 conf.getBoolean(HRegionServer.UNSAFE_RS_HOSTNAME_DISABLE_MASTER_REVERSEDNS_KEY, false)); 139 conf.setBoolean(HRegionServer.UNSAFE_RS_HOSTNAME_DISABLE_MASTER_REVERSEDNS_KEY, true); 140 assertTrue(conf.getBoolean(HRegionServer.RS_HOSTNAME_DISABLE_MASTER_REVERSEDNS_KEY, false)); 141 conf.setBoolean(HRegionServer.UNSAFE_RS_HOSTNAME_DISABLE_MASTER_REVERSEDNS_KEY, false); 142 assertFalse(conf.getBoolean(HRegionServer.RS_HOSTNAME_DISABLE_MASTER_REVERSEDNS_KEY, true)); 143 144 conf.setBoolean(DNS.RS_HOSTNAME_KEY, false); 145 assertFalse(conf.getBoolean(DNS.UNSAFE_RS_HOSTNAME_KEY, true)); 146 conf.setBoolean(DNS.RS_HOSTNAME_KEY, true); 147 assertTrue(conf.getBoolean(DNS.UNSAFE_RS_HOSTNAME_KEY, false)); 148 conf.setBoolean(DNS.UNSAFE_RS_HOSTNAME_KEY, true); 149 assertTrue(conf.getBoolean(DNS.RS_HOSTNAME_KEY, false)); 150 conf.setBoolean(DNS.UNSAFE_RS_HOSTNAME_KEY, false); 151 assertFalse(conf.getBoolean(DNS.RS_HOSTNAME_KEY, true)); 152 } 153 154 @Test 155 public void testConflictRegionServerHostnameConfigurationsAbortServer() throws Exception { 156 Enumeration<NetworkInterface> netInterfaceList = NetworkInterface.getNetworkInterfaces(); 157 while (netInterfaceList.hasMoreElements()) { 158 NetworkInterface ni = netInterfaceList.nextElement(); 159 Enumeration<InetAddress> addrList = ni.getInetAddresses(); 160 // iterate through host addresses and use each as hostname 161 while (addrList.hasMoreElements()) { 162 InetAddress addr = addrList.nextElement(); 163 if (addr.isLoopbackAddress() || addr.isLinkLocalAddress() || addr.isMulticastAddress()) { 164 continue; 165 } 166 String hostName = addr.getHostName(); 167 LOG.info("Found " + hostName + " on " + ni); 168 169 TEST_UTIL.getConfiguration().set(DNS.MASTER_HOSTNAME_KEY, hostName); 170 // "hbase.unsafe.regionserver.hostname" and 171 // "hbase.unsafe.regionserver.hostname.disable.master.reversedns" 172 // are mutually exclusive. Exception should be thrown if both are used. 173 TEST_UTIL.getConfiguration().set(DNS.UNSAFE_RS_HOSTNAME_KEY, hostName); 174 TEST_UTIL.getConfiguration() 175 .setBoolean(HRegionServer.UNSAFE_RS_HOSTNAME_DISABLE_MASTER_REVERSEDNS_KEY, true); 176 try { 177 StartTestingClusterOption option = StartTestingClusterOption.builder() 178 .numMasters(NUM_MASTERS).numRegionServers(NUM_RS).numDataNodes(NUM_RS).build(); 179 TEST_UTIL.startMiniCluster(option); 180 } catch (Exception e) { 181 Throwable t1 = e.getCause(); 182 Throwable t2 = t1.getCause(); 183 assertTrue(t1.getMessage() + " - " + t2.getMessage(), 184 t2.getMessage().contains(HRegionServer.UNSAFE_RS_HOSTNAME_DISABLE_MASTER_REVERSEDNS_KEY 185 + " and " + DNS.UNSAFE_RS_HOSTNAME_KEY + " are mutually exclusive")); 186 return; 187 } finally { 188 TEST_UTIL.shutdownMiniCluster(); 189 } 190 assertTrue("Failed to validate against conflict hostname configurations", false); 191 } 192 } 193 } 194 195 @Test 196 public void testRegionServerHostnameReportedToMaster() throws Exception { 197 TEST_UTIL.getConfiguration() 198 .setBoolean(HRegionServer.UNSAFE_RS_HOSTNAME_DISABLE_MASTER_REVERSEDNS_KEY, true); 199 StartTestingClusterOption option = StartTestingClusterOption.builder().numMasters(NUM_MASTERS) 200 .numRegionServers(NUM_RS).numDataNodes(NUM_RS).build(); 201 TEST_UTIL.startMiniCluster(option); 202 int expectedRS = NUM_RS; 203 try (ZKWatcher zkw = TEST_UTIL.getZooKeeperWatcher()) { 204 List<String> servers = ZKUtil.listChildrenNoWatch(zkw, zkw.getZNodePaths().rsZNode); 205 assertEquals(expectedRS, servers.size()); 206 } 207 } 208}