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