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