1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.regionserver.handler;
19
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertNotNull;
22 import static org.junit.Assert.assertTrue;
23
24 import java.io.IOException;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.apache.hadoop.hbase.HBaseTestingUtility;
29 import org.apache.hadoop.hbase.HConstants;
30 import org.apache.hadoop.hbase.HRegionInfo;
31 import org.apache.hadoop.hbase.HTableDescriptor;
32 import org.apache.hadoop.hbase.testclassification.MediumTests;
33 import org.apache.hadoop.hbase.RegionTransition;
34 import org.apache.hadoop.hbase.Server;
35 import org.apache.hadoop.hbase.TableName;
36 import org.apache.hadoop.hbase.coordination.OpenRegionCoordination;
37 import org.apache.hadoop.hbase.coordination.ZkCoordinatedStateManager;
38 import org.apache.hadoop.hbase.exceptions.DeserializationException;
39 import org.apache.hadoop.hbase.executor.EventType;
40 import org.apache.hadoop.hbase.regionserver.HRegion;
41 import org.apache.hadoop.hbase.regionserver.RegionServerServices;
42 import org.apache.hadoop.hbase.coordination.ZkCloseRegionCoordination;
43 import org.apache.hadoop.hbase.util.Bytes;
44 import org.apache.hadoop.hbase.util.MockServer;
45 import org.apache.hadoop.hbase.zookeeper.ZKAssign;
46 import org.apache.zookeeper.KeeperException;
47 import org.apache.zookeeper.KeeperException.NodeExistsException;
48 import org.junit.AfterClass;
49 import org.junit.Before;
50 import org.junit.BeforeClass;
51 import org.junit.Test;
52 import org.junit.experimental.categories.Category;
53 import org.mockito.Mockito;
54
55
56
57
58 @Category(MediumTests.class)
59 public class TestCloseRegionHandler {
60 static final Log LOG = LogFactory.getLog(TestCloseRegionHandler.class);
61 private final static HBaseTestingUtility HTU = HBaseTestingUtility.createLocalHTU();
62 private static final HTableDescriptor TEST_HTD =
63 new HTableDescriptor(TableName.valueOf("TestCloseRegionHandler"));
64 private HRegionInfo TEST_HRI;
65 private int testIndex = 0;
66
67 @BeforeClass public static void before() throws Exception {
68 HTU.getConfiguration().setBoolean("hbase.assignment.usezk", true);
69 HTU.startMiniZKCluster();
70 }
71
72 @AfterClass public static void after() throws IOException {
73 HTU.shutdownMiniZKCluster();
74 }
75
76
77
78
79
80
81 @Before
82 public void setupHRI() {
83 TEST_HRI = new HRegionInfo(TEST_HTD.getTableName(),
84 Bytes.toBytes(testIndex),
85 Bytes.toBytes(testIndex + 1));
86 testIndex++;
87 }
88
89
90
91
92
93
94
95
96 @Test public void testFailedFlushAborts()
97 throws IOException, NodeExistsException, KeeperException {
98 final Server server = new MockServer(HTU, false);
99 final RegionServerServices rss = HTU.createMockRegionServerService();
100 HTableDescriptor htd = TEST_HTD;
101 final HRegionInfo hri =
102 new HRegionInfo(htd.getTableName(), HConstants.EMPTY_END_ROW,
103 HConstants.EMPTY_END_ROW);
104 HRegion region = HTU.createLocalHRegion(hri, htd);
105 try {
106 assertNotNull(region);
107
108 HRegion spy = Mockito.spy(region);
109 final boolean abort = false;
110 Mockito.when(spy.close(abort)).
111 thenThrow(new IOException("Mocked failed close!"));
112
113
114 rss.addToOnlineRegions(spy);
115
116 assertFalse(server.isStopped());
117
118 ZkCoordinatedStateManager consensusProvider = new ZkCoordinatedStateManager();
119 consensusProvider.initialize(server);
120 consensusProvider.start();
121
122 ZkCloseRegionCoordination.ZkCloseRegionDetails zkCrd =
123 new ZkCloseRegionCoordination.ZkCloseRegionDetails();
124 zkCrd.setPublishStatusInZk(false);
125 zkCrd.setExpectedVersion(-1);
126
127 CloseRegionHandler handler = new CloseRegionHandler(server, rss, hri, false,
128 consensusProvider.getCloseRegionCoordination(), zkCrd);
129 boolean throwable = false;
130 try {
131 handler.process();
132 } catch (Throwable t) {
133 throwable = true;
134 } finally {
135 assertTrue(throwable);
136
137 assertTrue(server.isStopped());
138 }
139 } finally {
140 HRegion.closeHRegion(region);
141 }
142 }
143
144
145
146
147
148
149
150
151 @Test public void testZKClosingNodeVersionMismatch()
152 throws IOException, NodeExistsException, KeeperException, DeserializationException {
153 final Server server = new MockServer(HTU);
154 final RegionServerServices rss = HTU.createMockRegionServerService();
155
156 HTableDescriptor htd = TEST_HTD;
157 final HRegionInfo hri = TEST_HRI;
158
159 ZkCoordinatedStateManager coordinationProvider = new ZkCoordinatedStateManager();
160 coordinationProvider.initialize(server);
161 coordinationProvider.start();
162
163
164 OpenRegion(server, rss, htd, hri, coordinationProvider.getOpenRegionCoordination());
165
166
167
168 int versionOfClosingNode = ZKAssign.createNodeClosing(server.getZooKeeper(),
169 hri, server.getServerName());
170
171
172
173
174
175 ZkCloseRegionCoordination.ZkCloseRegionDetails zkCrd =
176 new ZkCloseRegionCoordination.ZkCloseRegionDetails();
177 zkCrd.setPublishStatusInZk(true);
178 zkCrd.setExpectedVersion(versionOfClosingNode+1);
179
180 CloseRegionHandler handler = new CloseRegionHandler(server, rss, hri, false,
181 coordinationProvider.getCloseRegionCoordination(), zkCrd);
182 handler.process();
183
184
185 RegionTransition rt =
186 RegionTransition.parseFrom(ZKAssign.getData(server.getZooKeeper(), hri.getEncodedName()));
187 assertTrue(rt.getEventType().equals(EventType.M_ZK_REGION_CLOSING ));
188 }
189
190
191
192
193
194
195
196
197 @Test public void testCloseRegion()
198 throws IOException, NodeExistsException, KeeperException, DeserializationException {
199 final Server server = new MockServer(HTU);
200 final RegionServerServices rss = HTU.createMockRegionServerService();
201
202 HTableDescriptor htd = TEST_HTD;
203 HRegionInfo hri = TEST_HRI;
204
205 ZkCoordinatedStateManager coordinationProvider = new ZkCoordinatedStateManager();
206 coordinationProvider.initialize(server);
207 coordinationProvider.start();
208
209
210 OpenRegion(server, rss, htd, hri, coordinationProvider.getOpenRegionCoordination());
211
212
213
214 int versionOfClosingNode = ZKAssign.createNodeClosing(server.getZooKeeper(),
215 hri, server.getServerName());
216
217
218
219
220
221 ZkCloseRegionCoordination.ZkCloseRegionDetails zkCrd =
222 new ZkCloseRegionCoordination.ZkCloseRegionDetails();
223 zkCrd.setPublishStatusInZk(true);
224 zkCrd.setExpectedVersion(versionOfClosingNode);
225
226 CloseRegionHandler handler = new CloseRegionHandler(server, rss, hri, false,
227 coordinationProvider.getCloseRegionCoordination(), zkCrd);
228 handler.process();
229
230 RegionTransition rt = RegionTransition.parseFrom(
231 ZKAssign.getData(server.getZooKeeper(), hri.getEncodedName()));
232 assertTrue(rt.getEventType().equals(EventType.RS_ZK_REGION_CLOSED));
233 }
234
235 private void OpenRegion(Server server, RegionServerServices rss,
236 HTableDescriptor htd, HRegionInfo hri, OpenRegionCoordination coordination)
237 throws IOException, NodeExistsException, KeeperException, DeserializationException {
238
239 ZKAssign.createNodeOffline(server.getZooKeeper(), hri, server.getServerName());
240
241 OpenRegionCoordination.OpenRegionDetails ord =
242 coordination.getDetailsForNonCoordinatedOpening();
243 OpenRegionHandler openHandler =
244 new OpenRegionHandler(server, rss, hri, htd, -1, coordination, ord);
245 rss.getRegionsInTransitionInRS().put(hri.getEncodedNameAsBytes(), Boolean.TRUE);
246 openHandler.process();
247
248 RegionTransition.parseFrom(ZKAssign.getData(server.getZooKeeper(), hri.getEncodedName()));
249
250 ZKAssign.deleteNode(server.getZooKeeper(), hri.getEncodedName(),
251 EventType.RS_ZK_REGION_OPENED, server.getServerName());
252 }
253
254 }
255