1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase;
20
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertFalse;
23 import static org.junit.Assert.assertNull;
24 import static org.junit.Assert.assertTrue;
25
26 import com.google.protobuf.RpcController;
27 import com.google.protobuf.ServiceException;
28
29 import java.io.IOException;
30 import java.net.ConnectException;
31
32 import org.apache.commons.logging.Log;
33 import org.apache.commons.logging.LogFactory;
34 import org.apache.hadoop.conf.Configuration;
35 import org.apache.hadoop.hbase.client.ClusterConnection;
36 import org.apache.hadoop.hbase.client.HConnection;
37 import org.apache.hadoop.hbase.client.HConnectionTestingUtility;
38 import org.apache.hadoop.hbase.ipc.HBaseRpcController;
39 import org.apache.hadoop.hbase.ipc.RpcControllerFactory;
40 import org.apache.hadoop.hbase.ipc.ServerNotRunningYetException;
41 import org.apache.hadoop.hbase.master.RegionState;
42 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos;
43 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetRegionInfoRequest;
44 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos;
45 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.GetRequest;
46 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.GetResponse;
47 import org.apache.hadoop.hbase.testclassification.MediumTests;
48 import org.apache.hadoop.hbase.util.Threads;
49 import org.apache.hadoop.hbase.zookeeper.MetaTableLocator;
50 import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
51 import org.apache.zookeeper.KeeperException;
52 import org.junit.After;
53 import org.junit.AfterClass;
54 import org.junit.Before;
55 import org.junit.BeforeClass;
56 import org.junit.Test;
57 import org.junit.experimental.categories.Category;
58 import org.mockito.Mockito;
59
60
61
62
63 @Category(MediumTests.class)
64 public class TestMetaTableLocator {
65 private static final Log LOG = LogFactory.getLog(TestMetaTableLocator.class);
66 private static final HBaseTestingUtility UTIL = new HBaseTestingUtility();
67 private static final ServerName SN =
68 ServerName.valueOf("example.org", 1234, System.currentTimeMillis());
69 private ZooKeeperWatcher watcher;
70 private Abortable abortable;
71
72 @BeforeClass public static void beforeClass() throws Exception {
73
74 UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 3);
75 UTIL.startMiniZKCluster();
76 }
77
78 @AfterClass public static void afterClass() throws IOException {
79 UTIL.getZkCluster().shutdown();
80 }
81
82 @Before public void before() throws IOException {
83 this.abortable = new Abortable() {
84 @Override
85 public void abort(String why, Throwable e) {
86 LOG.info(why, e);
87 }
88
89 @Override
90 public boolean isAborted() {
91 return false;
92 }
93 };
94 this.watcher = new ZooKeeperWatcher(UTIL.getConfiguration(),
95 this.getClass().getSimpleName(), this.abortable, true);
96 }
97
98 @After public void after() {
99 try {
100
101
102 new MetaTableLocator().deleteMetaLocation(this.watcher);
103 } catch (KeeperException e) {
104 LOG.warn("Unable to delete hbase:meta location", e);
105 }
106
107 this.watcher.close();
108 }
109
110
111
112
113 @Test public void testMetaLookup()
114 throws IOException, InterruptedException, ServiceException, KeeperException {
115 final ClientProtos.ClientService.BlockingInterface client =
116 Mockito.mock(ClientProtos.ClientService.BlockingInterface.class);
117
118 Mockito.when(client.get((RpcController)Mockito.any(), (GetRequest)Mockito.any())).
119 thenReturn(GetResponse.newBuilder().build());
120
121 final MetaTableLocator mtl = new MetaTableLocator();
122 assertNull(mtl.getMetaRegionLocation(this.watcher));
123 for (RegionState.State state : RegionState.State.values()) {
124 if (state.equals(RegionState.State.OPEN))
125 continue;
126 MetaTableLocator.setMetaLocation(this.watcher, SN, state);
127 assertNull(mtl.getMetaRegionLocation(this.watcher));
128 assertEquals(state, MetaTableLocator.getMetaRegionState(this.watcher).getState());
129 }
130 MetaTableLocator.setMetaLocation(this.watcher, SN, RegionState.State.OPEN);
131 assertEquals(mtl.getMetaRegionLocation(this.watcher), SN);
132 assertEquals(RegionState.State.OPEN,
133 MetaTableLocator.getMetaRegionState(this.watcher).getState());
134
135 mtl.deleteMetaLocation(this.watcher);
136 assertNull(MetaTableLocator.getMetaRegionState(this.watcher).getServerName());
137 assertEquals(MetaTableLocator.getMetaRegionState(this.watcher).getState(),
138 RegionState.State.OFFLINE);
139 assertNull(mtl.getMetaRegionLocation(this.watcher));
140 }
141
142
143
144
145
146
147
148
149 @Test public void testInterruptWaitOnMeta()
150 throws IOException, InterruptedException, ServiceException {
151 final ClientProtos.ClientService.BlockingInterface client =
152 Mockito.mock(ClientProtos.ClientService.BlockingInterface.class);
153
154 Mockito.when(client.get((RpcController)Mockito.any(), (GetRequest)Mockito.any())).
155 thenReturn(GetResponse.newBuilder().build());
156
157 final MetaTableLocator mtl = new MetaTableLocator();
158 ServerName meta = new MetaTableLocator().getMetaRegionLocation(this.watcher);
159 assertNull(meta);
160 Thread t = new Thread() {
161 @Override
162 public void run() {
163 try {
164 mtl.waitMetaRegionLocation(watcher);
165 } catch (InterruptedException e) {
166 throw new RuntimeException("Interrupted", e);
167 }
168 }
169 };
170 t.start();
171 while (!t.isAlive())
172 Threads.sleep(1);
173 Threads.sleep(1);
174 assertTrue(t.isAlive());
175 mtl.stop();
176
177 t.join();
178 }
179
180 private void testVerifyMetaRegionLocationWithException(Exception ex)
181 throws IOException, InterruptedException, KeeperException, ServiceException {
182
183 final ClientProtos.ClientService.BlockingInterface implementation =
184 Mockito.mock(ClientProtos.ClientService.BlockingInterface.class);
185
186 ClusterConnection connection = mockConnection(null, implementation);
187
188
189 Mockito.when(implementation.get((RpcController) Mockito.any(), (GetRequest) Mockito.any())).
190 thenThrow(new ServiceException(ex));
191
192 long timeout = UTIL.getConfiguration().
193 getLong("hbase.catalog.verification.timeout", 1000);
194 MetaTableLocator.setMetaLocation(this.watcher, SN, RegionState.State.OPENING);
195 assertFalse(new MetaTableLocator().verifyMetaRegionLocation(
196 connection, watcher, timeout));
197
198 MetaTableLocator.setMetaLocation(this.watcher, SN, RegionState.State.OPEN);
199 assertFalse(new MetaTableLocator().verifyMetaRegionLocation(
200 connection, watcher, timeout));
201 }
202
203
204
205
206
207
208
209
210 @Test
211 public void testGetMetaServerConnectionFails()
212 throws IOException, InterruptedException, KeeperException, ServiceException {
213 testVerifyMetaRegionLocationWithException(new ConnectException("Connection refused"));
214 }
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230 @Test
231 public void testVerifyMetaRegionServerNotRunning()
232 throws IOException, InterruptedException, KeeperException, ServiceException {
233 testVerifyMetaRegionLocationWithException(new ServerNotRunningYetException("mock"));
234 }
235
236
237
238
239
240
241
242
243 @Test
244 public void testVerifyMetaRegionLocationFails()
245 throws IOException, InterruptedException, KeeperException, ServiceException {
246 ClusterConnection connection = Mockito.mock(ClusterConnection.class);
247 ServiceException connectException =
248 new ServiceException(new ConnectException("Connection refused"));
249 final AdminProtos.AdminService.BlockingInterface implementation =
250 Mockito.mock(AdminProtos.AdminService.BlockingInterface.class);
251 Mockito.when(implementation.getRegionInfo((RpcController)Mockito.any(),
252 (GetRegionInfoRequest)Mockito.any())).thenThrow(connectException);
253 Mockito.when(connection.getAdmin(Mockito.any(ServerName.class))).
254 thenReturn(implementation);
255 RpcControllerFactory controllerFactory = Mockito.mock(RpcControllerFactory.class);
256 Mockito.when(controllerFactory.newController()).thenReturn(
257 Mockito.mock(HBaseRpcController.class));
258 Mockito.when(connection.getRpcControllerFactory()).thenReturn(controllerFactory);
259
260 ServerName sn = ServerName.valueOf("example.com", 1234, System.currentTimeMillis());
261 MetaTableLocator.setMetaLocation(this.watcher,
262 sn,
263 RegionState.State.OPENING);
264 assertFalse(new MetaTableLocator().verifyMetaRegionLocation(connection, watcher, 100));
265 MetaTableLocator.setMetaLocation(this.watcher, sn, RegionState.State.OPEN);
266 assertFalse(new MetaTableLocator().verifyMetaRegionLocation(connection, watcher, 100));
267 }
268
269 @Test (expected = NotAllMetaRegionsOnlineException.class)
270 public void testTimeoutWaitForMeta()
271 throws IOException, InterruptedException {
272 new MetaTableLocator().waitMetaRegionLocation(watcher, 100);
273 }
274
275
276
277
278
279
280
281 @Test public void testNoTimeoutWaitForMeta()
282 throws IOException, InterruptedException, KeeperException {
283 final MetaTableLocator mtl = new MetaTableLocator();
284 ServerName hsa = mtl.getMetaRegionLocation(watcher);
285 assertNull(hsa);
286
287
288 Thread t = new WaitOnMetaThread();
289 startWaitAliveThenWaitItLives(t, 1);
290
291 MetaTableLocator.setMetaLocation(this.watcher, SN, RegionState.State.OPEN);
292 hsa = SN;
293
294 t.join();
295
296 assertTrue(mtl.getMetaRegionLocation(watcher).equals(hsa));
297 }
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312 private ClusterConnection mockConnection(final AdminProtos.AdminService.BlockingInterface admin,
313 final ClientProtos.ClientService.BlockingInterface client)
314 throws IOException {
315 ClusterConnection connection =
316 HConnectionTestingUtility.getMockedConnection(UTIL.getConfiguration());
317 Mockito.doNothing().when(connection).close();
318
319 final HRegionLocation anyLocation = new HRegionLocation(HRegionInfo.FIRST_META_REGIONINFO, SN);
320 Mockito.when(connection.getRegionLocation((TableName) Mockito.any(),
321 (byte[]) Mockito.any(), Mockito.anyBoolean())).
322 thenReturn(anyLocation);
323 Mockito.when(connection.locateRegion((TableName) Mockito.any(),
324 (byte[]) Mockito.any())).
325 thenReturn(anyLocation);
326 if (admin != null) {
327
328 Mockito.when(connection.getAdmin(Mockito.any(ServerName.class))).
329 thenReturn(admin);
330 }
331 if (client != null) {
332
333 Mockito.when(connection.getClient(Mockito.any(ServerName.class))).
334 thenReturn(client);
335 }
336 return connection;
337 }
338
339 private void startWaitAliveThenWaitItLives(final Thread t, final int ms) {
340 t.start();
341 while(!t.isAlive()) {
342
343 }
344
345 Threads.sleep(ms);
346 assertTrue("Assert " + t.getName() + " still waiting", t.isAlive());
347 }
348
349
350
351
352 class WaitOnMetaThread extends Thread {
353
354 WaitOnMetaThread() {
355 super("WaitOnMeta");
356 }
357
358 @Override
359 public void run() {
360 try {
361 doWaiting();
362 } catch (InterruptedException e) {
363 throw new RuntimeException("Failed wait", e);
364 }
365 LOG.info("Exiting " + getName());
366 }
367
368 void doWaiting() throws InterruptedException {
369 try {
370 while (new MetaTableLocator().waitMetaRegionLocation(watcher, 10000) == null);
371 } catch (NotAllMetaRegionsOnlineException e) {
372
373 }
374 }
375 }
376 }