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