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