1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.replication;
20
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertTrue;
23 import static org.junit.Assert.fail;
24
25 import java.util.ArrayList;
26 import java.util.List;
27 import java.util.concurrent.atomic.AtomicInteger;
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.ClusterId;
33 import org.apache.hadoop.hbase.HBaseTestingUtility;
34 import org.apache.hadoop.hbase.HConstants;
35 import org.apache.hadoop.hbase.testclassification.MediumTests;
36 import org.apache.hadoop.hbase.Server;
37 import org.apache.hadoop.hbase.ServerName;
38 import org.apache.hadoop.hbase.catalog.CatalogTracker;
39 import org.apache.hadoop.hbase.zookeeper.ZKClusterId;
40 import org.apache.hadoop.hbase.zookeeper.ZKUtil;
41 import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
42 import org.junit.AfterClass;
43 import org.junit.Before;
44 import org.junit.BeforeClass;
45 import org.junit.Test;
46 import org.junit.experimental.categories.Category;
47
48
49
50
51
52
53
54
55 @Category(MediumTests.class)
56 public class TestReplicationTrackerZKImpl {
57
58 private static final Log LOG = LogFactory.getLog(TestReplicationTrackerZKImpl.class);
59
60 private static Configuration conf;
61 private static HBaseTestingUtility utility;
62
63
64 private ZooKeeperWatcher zkw;
65 private ReplicationPeers rp;
66 private ReplicationTracker rt;
67 private AtomicInteger rsRemovedCount;
68 private String rsRemovedData;
69 private AtomicInteger plChangedCount;
70 private List<String> plChangedData;
71 private AtomicInteger peerRemovedCount;
72 private String peerRemovedData;
73
74 @BeforeClass
75 public static void setUpBeforeClass() throws Exception {
76 utility = new HBaseTestingUtility();
77 utility.startMiniZKCluster();
78 conf = utility.getConfiguration();
79 ZooKeeperWatcher zk = HBaseTestingUtility.getZooKeeperWatcher(utility);
80 ZKUtil.createWithParents(zk, zk.rsZNode);
81 }
82
83 @Before
84 public void setUp() throws Exception {
85 zkw = HBaseTestingUtility.getZooKeeperWatcher(utility);
86 String fakeRs1 = ZKUtil.joinZNode(zkw.rsZNode, "hostname1.example.org:1234");
87 try {
88 ZKClusterId.setClusterId(zkw, new ClusterId());
89 rp = ReplicationFactory.getReplicationPeers(zkw, conf, zkw);
90 rp.init();
91 rt = ReplicationFactory.getReplicationTracker(zkw, rp, conf, zkw, new DummyServer(fakeRs1));
92 } catch (Exception e) {
93 fail("Exception during test setup: " + e);
94 }
95 rsRemovedCount = new AtomicInteger(0);
96 rsRemovedData = "";
97 plChangedCount = new AtomicInteger(0);
98 plChangedData = new ArrayList<String>();
99 peerRemovedCount = new AtomicInteger(0);
100 peerRemovedData = "";
101 }
102
103 @AfterClass
104 public static void tearDownAfterClass() throws Exception {
105 utility.shutdownMiniZKCluster();
106 }
107
108 @Test
109 public void testGetListOfRegionServers() throws Exception {
110
111 assertEquals(0, rt.getListOfRegionServers().size());
112
113
114 ZKUtil.createWithParents(zkw, ZKUtil.joinZNode(zkw.rsZNode, "hostname1.example.org:1234"));
115 assertEquals(1, rt.getListOfRegionServers().size());
116
117
118 ZKUtil.createWithParents(zkw, ZKUtil.joinZNode(zkw.rsZNode, "hostname2.example.org:1234"));
119 assertEquals(2, rt.getListOfRegionServers().size());
120
121
122 ZKUtil.deleteNode(zkw, ZKUtil.joinZNode(zkw.rsZNode, "hostname2.example.org:1234"));
123 assertEquals(1, rt.getListOfRegionServers().size());
124
125
126 ZKUtil.deleteNode(zkw, ZKUtil.joinZNode(zkw.rsZNode, "hostname1.example.org:1234"));
127 assertEquals(0, rt.getListOfRegionServers().size());
128 }
129
130 @Test(timeout = 30000)
131 public void testRegionServerRemovedEvent() throws Exception {
132 ZKUtil.createAndWatch(zkw, ZKUtil.joinZNode(zkw.rsZNode, "hostname2.example.org:1234"),
133 HConstants.EMPTY_BYTE_ARRAY);
134 rt.registerListener(new DummyReplicationListener());
135
136 ZKUtil.deleteNode(zkw, ZKUtil.joinZNode(zkw.rsZNode, "hostname2.example.org:1234"));
137
138 while (rsRemovedCount.get() < 1) {
139 Thread.sleep(5);
140 }
141 assertEquals("hostname2.example.org:1234", rsRemovedData);
142 }
143
144 @Test(timeout = 30000)
145 public void testPeerRemovedEvent() throws Exception {
146 rp.addPeer("5", new ReplicationPeerConfig().setClusterKey(utility.getClusterKey()), null);
147 rt.registerListener(new DummyReplicationListener());
148 rp.removePeer("5");
149
150 while (peerRemovedCount.get() < 1) {
151 Thread.sleep(5);
152 }
153 assertEquals("5", peerRemovedData);
154 }
155
156 @Test(timeout = 30000)
157 public void testPeerListChangedEvent() throws Exception {
158
159 rp.addPeer("5", new ReplicationPeerConfig().setClusterKey(utility.getClusterKey()), null);
160 zkw.getRecoverableZooKeeper().getZooKeeper().getChildren("/hbase/replication/peers/5", true);
161 rt.registerListener(new DummyReplicationListener());
162 rp.disablePeer("5");
163 ZKUtil.deleteNode(zkw, "/hbase/replication/peers/5/peer-state");
164
165 int tmp = plChangedCount.get();
166 while (plChangedCount.get() <= tmp) {
167 Thread.sleep(5);
168 }
169 assertEquals(1, plChangedData.size());
170 assertTrue(plChangedData.contains("5"));
171
172
173
174 rp.removePeer("5");
175 }
176
177 @Test(timeout = 30000)
178 public void testPeerNameControl() throws Exception {
179 int exists = 0;
180 int hyphen = 0;
181 rp.addPeer("6", new ReplicationPeerConfig().setClusterKey(utility.getClusterKey()), null);
182
183 try{
184 rp.addPeer("6", new ReplicationPeerConfig().setClusterKey(utility.getClusterKey()), null);
185 }catch(IllegalArgumentException e){
186 exists++;
187 }
188
189 try{
190 rp.addPeer("6-ec2", new ReplicationPeerConfig().setClusterKey(utility.getClusterKey()), null);
191 }catch(IllegalArgumentException e){
192 hyphen++;
193 }
194 assertEquals(1, exists);
195 assertEquals(1, hyphen);
196
197
198 rp.removePeer("6");
199 }
200
201 private class DummyReplicationListener implements ReplicationListener {
202
203 @Override
204 public void regionServerRemoved(String regionServer) {
205 rsRemovedData = regionServer;
206 rsRemovedCount.getAndIncrement();
207 LOG.debug("Received regionServerRemoved event: " + regionServer);
208 }
209
210 @Override
211 public void peerRemoved(String peerId) {
212 peerRemovedData = peerId;
213 peerRemovedCount.getAndIncrement();
214 LOG.debug("Received peerRemoved event: " + peerId);
215 }
216
217 @Override
218 public void peerListChanged(List<String> peerIds) {
219 plChangedData.clear();
220 plChangedData.addAll(peerIds);
221 plChangedCount.getAndIncrement();
222 LOG.debug("Received peerListChanged event");
223 }
224 }
225
226 private class DummyServer implements Server {
227 private String serverName;
228 private boolean isAborted = false;
229 private boolean isStopped = false;
230
231 public DummyServer(String serverName) {
232 this.serverName = serverName;
233 }
234
235 @Override
236 public Configuration getConfiguration() {
237 return conf;
238 }
239
240 @Override
241 public ZooKeeperWatcher getZooKeeper() {
242 return zkw;
243 }
244
245 @Override
246 public CatalogTracker getCatalogTracker() {
247 return null;
248 }
249
250 @Override
251 public ServerName getServerName() {
252 return ServerName.valueOf(this.serverName);
253 }
254
255 @Override
256 public void abort(String why, Throwable e) {
257 LOG.info("Aborting " + serverName);
258 this.isAborted = true;
259 }
260
261 @Override
262 public boolean isAborted() {
263 return this.isAborted;
264 }
265
266 @Override
267 public void stop(String why) {
268 this.isStopped = true;
269 }
270
271 @Override
272 public boolean isStopped() {
273 return this.isStopped;
274 }
275 }
276 }
277