1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.client;
19
20 import static org.apache.hadoop.hbase.HConstants.META_REPLICAS_NUM;
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertFalse;
23 import static org.junit.Assert.assertTrue;
24
25 import com.google.common.base.Joiner;
26 import com.google.common.base.Preconditions;
27 import com.google.common.collect.ImmutableSet;
28 import com.google.protobuf.RpcController;
29 import java.io.IOException;
30 import java.net.SocketTimeoutException;
31 import java.util.ArrayList;
32 import java.util.Arrays;
33 import java.util.Collections;
34 import java.util.Comparator;
35 import java.util.List;
36 import org.apache.hadoop.conf.Configuration;
37 import org.apache.hadoop.hbase.HBaseTestingUtility;
38 import org.apache.hadoop.hbase.HConstants;
39 import org.apache.hadoop.hbase.HRegionLocation;
40 import org.apache.hadoop.hbase.ServerName;
41 import org.apache.hadoop.hbase.TableName;
42 import org.apache.hadoop.hbase.Waiter;
43 import org.apache.hadoop.hbase.exceptions.MasterRegistryFetchException;
44 import org.apache.hadoop.hbase.master.HMaster;
45 import org.apache.hadoop.hbase.testclassification.ClientTests;
46 import org.apache.hadoop.hbase.testclassification.MediumTests;
47 import org.junit.AfterClass;
48 import org.junit.BeforeClass;
49 import org.junit.Test;
50 import org.junit.experimental.categories.Category;
51
52 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ClientMetaService;
53 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetClusterIdRequest;
54 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetClusterIdResponse;
55
56 @Category({ MediumTests.class, ClientTests.class })
57 public class TestMasterRegistry {
58
59 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
60
61 private static final int META_REPLICA_COUNT = 3;
62
63 @BeforeClass
64 public static void setUp() throws Exception {
65 TEST_UTIL.getConfiguration().setInt(META_REPLICAS_NUM, META_REPLICA_COUNT);
66 TEST_UTIL.startMiniCluster(3, 3);
67 }
68
69 @AfterClass
70 public static void tearDown() throws Exception {
71 TEST_UTIL.shutdownMiniCluster();
72 }
73
74 private static class ExceptionInjectorRegistry extends MasterRegistry {
75 @Override
76 public String getClusterId() throws IOException {
77 GetClusterIdResponse resp = doCall(new Callable<GetClusterIdResponse>() {
78 @Override
79 public GetClusterIdResponse call(ClientMetaService.Interface stub, RpcController controller)
80 throws IOException {
81 throw new SocketTimeoutException("Injected exception.");
82 }
83 });
84 return resp.getClusterId();
85 }
86 }
87
88
89
90
91
92 private static String generateDummyMastersList(int size) {
93 List<String> masters = new ArrayList<>();
94 for (int i = 0; i < size; i++) {
95 masters.add(" localhost" + (i % 2 == 0 ? ":" + (1000 + i) : ""));
96 }
97 return Joiner.on(",").join(masters);
98 }
99
100
101
102
103 @Test
104 public void testMasterAddressParsing() throws IOException {
105 Configuration conf = new Configuration(TEST_UTIL.getConfiguration());
106 int numMasters = 10;
107 conf.set(HConstants.MASTER_ADDRS_KEY, generateDummyMastersList(numMasters));
108 List<ServerName> parsedMasters = new ArrayList<>(MasterRegistry.parseMasterAddrs(conf));
109
110 assertEquals(numMasters / 2 + 1, parsedMasters.size());
111
112 Collections.sort(parsedMasters, new Comparator<ServerName>() {
113 @Override
114 public int compare(ServerName sn1, ServerName sn2) {
115 return sn1.getPort() - sn2.getPort();
116 }
117 });
118 for (int i = 0; i < parsedMasters.size(); i++) {
119 ServerName sn = parsedMasters.get(i);
120 assertEquals("localhost", sn.getHostname());
121 if (i == parsedMasters.size() - 1) {
122
123 assertEquals(HConstants.DEFAULT_MASTER_PORT, sn.getPort());
124 } else {
125 assertEquals(1000 + (2 * i), sn.getPort());
126 }
127 }
128 }
129
130 @Test
131 public void testRegistryRPCs() throws Exception {
132 HMaster activeMaster = TEST_UTIL.getHBaseCluster().getMaster();
133 final MasterRegistry registry = new MasterRegistry();
134 try {
135 registry.init(TEST_UTIL.getConnection());
136
137
138 TEST_UTIL.waitFor(10000, new Waiter.Predicate<Exception>() {
139 @Override
140 public boolean evaluate() throws Exception {
141 return registry.getMetaRegionLocations().size() == META_REPLICA_COUNT;
142 }
143 });
144 assertEquals(registry.getClusterId(), activeMaster.getClusterId());
145 assertEquals(registry.getActiveMaster(), activeMaster.getServerName());
146 assertTrue(registry.isTableOnlineState(TableName.META_TABLE_NAME, true));
147 assertFalse(registry.isTableOnlineState(TableName.META_TABLE_NAME, false));
148 List<HRegionLocation> metaLocations =
149 Arrays.asList(registry.getMetaRegionLocations().getRegionLocations());
150 List<HRegionLocation> actualMetaLocations =
151 activeMaster.getMetaRegionLocationCache().getMetaRegionLocations();
152 Collections.sort(metaLocations);
153 Collections.sort(actualMetaLocations);
154 assertEquals(actualMetaLocations, metaLocations);
155 int numRs = registry.getCurrentNrHRS();
156 assertEquals(TEST_UTIL.getMiniHBaseCluster().getLiveRegionServerThreads().size(), numRs);
157 } finally {
158 registry.close();
159 }
160 }
161
162
163
164
165
166 @Test
167 public void testDynamicMasterConfigurationRefresh() throws Exception {
168 Configuration conf = TEST_UTIL.getConnection().getConfiguration();
169 String currentMasterAddrs = Preconditions.checkNotNull(conf.get(HConstants.MASTER_ADDRS_KEY));
170 HMaster activeMaster = TEST_UTIL.getHBaseCluster().getMaster();
171
172 ServerName badServer = ServerName.valueOf("localhost", 1234, -1);
173 conf.set(HConstants.MASTER_ADDRS_KEY, badServer.toShortString() + "," + currentMasterAddrs);
174
175 conf.setLong(MasterAddressRefresher.MIN_SECS_BETWEEN_REFRESHES, 0);
176 final ExceptionInjectorRegistry registry = new ExceptionInjectorRegistry();
177 try {
178 registry.init(TEST_UTIL.getConnection());
179 final ImmutableSet<String> masters = registry.getParsedMasterServers();
180 assertTrue(masters.contains(badServer.toString()));
181
182 try {
183 registry.getClusterId();
184 } catch (MasterRegistryFetchException e) {
185
186 }
187
188
189 TEST_UTIL.waitFor(5000,
190 new Waiter.Predicate<Exception>() {
191 @Override
192 public boolean evaluate() throws Exception {
193 return !registry.getParsedMasterServers().equals(masters);
194 }
195 });
196
197 final ImmutableSet<String> newMasters = registry.getParsedMasterServers();
198
199 assertEquals(3, newMasters.size());
200 assertFalse(newMasters.contains(badServer.toString()));
201
202 activeMaster.stopMaster();
203 TEST_UTIL.waitFor(10000,
204 new Waiter.Predicate<Exception>() {
205 @Override
206 public boolean evaluate() {
207 return TEST_UTIL.getMiniHBaseCluster().getLiveMasterThreads().size() == 2;
208 }
209 });
210 TEST_UTIL.getMiniHBaseCluster().waitForActiveAndReadyMaster(10000);
211
212 try {
213 registry.getClusterId();
214 } catch (MasterRegistryFetchException e) {
215
216 }
217
218 TEST_UTIL.waitFor(10000, new Waiter.Predicate<Exception>() {
219 @Override
220 public boolean evaluate() throws Exception {
221 return registry.getMasters().size() == 2;
222 }
223 });
224 TEST_UTIL.waitFor(20000, new Waiter.Predicate<Exception>() {
225 @Override
226 public boolean evaluate() throws Exception {
227 return registry.getParsedMasterServers().size() == 2;
228 }
229 });
230 final ImmutableSet<String> newMasters2 = registry.getParsedMasterServers();
231 assertEquals(2, newMasters2.size());
232 assertFalse(newMasters2.contains(activeMaster.getServerName().toString()));
233 } finally {
234 registry.close();
235
236 TEST_UTIL.getMiniHBaseCluster().startMaster();
237 }
238 }
239 }