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.*;
22
23 import java.util.ArrayList;
24 import java.util.List;
25 import java.util.SortedMap;
26 import java.util.SortedSet;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.apache.hadoop.hbase.ServerName;
31 import org.apache.hadoop.hbase.zookeeper.ZKConfig;
32 import org.apache.zookeeper.KeeperException;
33 import org.junit.Before;
34 import org.junit.Test;
35
36
37
38
39
40 public abstract class TestReplicationStateBasic {
41
42 protected ReplicationQueues rq1;
43 protected ReplicationQueues rq2;
44 protected ReplicationQueues rq3;
45 protected ReplicationQueuesClient rqc;
46 protected String server1 = ServerName.valueOf("hostname1.example.org", 1234, -1L).toString();
47 protected String server2 = ServerName.valueOf("hostname2.example.org", 1234, -1L).toString();
48 protected String server3 = ServerName.valueOf("hostname3.example.org", 1234, -1L).toString();
49 protected ReplicationPeers rp;
50 protected static final String ID_ONE = "1";
51 protected static final String ID_TWO = "2";
52 protected static String KEY_ONE;
53 protected static String KEY_TWO;
54
55
56 protected String OUR_ID = "3";
57 protected String OUR_KEY;
58
59 protected static int zkTimeoutCount;
60 protected static final int ZK_MAX_COUNT = 300;
61 protected static final int ZK_SLEEP_INTERVAL = 100;
62
63 private static final Log LOG = LogFactory.getLog(TestReplicationStateBasic.class);
64
65 @Before
66 public void setUp() {
67 zkTimeoutCount = 0;
68 }
69
70 @Test
71 public void testReplicationQueuesClient() throws ReplicationException, KeeperException {
72 rqc.init();
73
74 assertEquals(0, rqc.getListOfReplicators().size());
75 assertNull(rqc.getLogsInQueue(server1, "qId1"));
76 assertNull(rqc.getAllQueues(server1));
77
78
79
80
81
82 rq1.init(server1);
83 rq2.init(server2);
84 rq1.addLog("qId1", "trash");
85 rq1.removeLog("qId1", "trash");
86 rq1.addLog("qId2", "filename1");
87 rq1.addLog("qId3", "filename2");
88 rq1.addLog("qId3", "filename3");
89 rq2.addLog("trash", "trash");
90 rq2.removeQueue("trash");
91
92 List<String> reps = rqc.getListOfReplicators();
93 assertEquals(2, reps.size());
94 assertTrue(server1, reps.contains(server1));
95 assertTrue(server2, reps.contains(server2));
96
97 assertNull(rqc.getLogsInQueue("bogus", "bogus"));
98 assertNull(rqc.getLogsInQueue(server1, "bogus"));
99 assertEquals(0, rqc.getLogsInQueue(server1, "qId1").size());
100 assertEquals(1, rqc.getLogsInQueue(server1, "qId2").size());
101 assertEquals("filename1", rqc.getLogsInQueue(server1, "qId2").get(0));
102
103 assertNull(rqc.getAllQueues("bogus"));
104 assertEquals(0, rqc.getAllQueues(server2).size());
105 List<String> list = rqc.getAllQueues(server1);
106 assertEquals(3, list.size());
107 assertTrue(list.contains("qId2"));
108 assertTrue(list.contains("qId3"));
109 }
110
111 @Test
112 public void testReplicationQueues() throws ReplicationException {
113 rq1.init(server1);
114 rq2.init(server2);
115 rq3.init(server3);
116
117 rp.init();
118
119
120 assertEquals(3, rq1.getListOfReplicators().size());
121 rq1.removeQueue("bogus");
122 rq1.removeLog("bogus", "bogus");
123 rq1.removeAllQueues();
124 assertNull(rq1.getAllQueues());
125 assertEquals(0, rq1.getLogPosition("bogus", "bogus"));
126 assertNull(rq1.getLogsInQueue("bogus"));
127 assertEquals(0, rq1.claimQueues(ServerName.valueOf("bogus", 1234, -1L).toString()).size());
128
129 rq1.setLogPosition("bogus", "bogus", 5L);
130
131 populateQueues();
132
133 assertEquals(3, rq1.getListOfReplicators().size());
134 assertEquals(0, rq2.getLogsInQueue("qId1").size());
135 assertEquals(5, rq3.getLogsInQueue("qId5").size());
136 assertEquals(0, rq3.getLogPosition("qId1", "filename0"));
137 rq3.setLogPosition("qId5", "filename4", 354L);
138 assertEquals(354L, rq3.getLogPosition("qId5", "filename4"));
139
140 assertEquals(5, rq3.getLogsInQueue("qId5").size());
141 assertEquals(0, rq2.getLogsInQueue("qId1").size());
142 assertEquals(0, rq1.getAllQueues().size());
143 assertEquals(1, rq2.getAllQueues().size());
144 assertEquals(5, rq3.getAllQueues().size());
145
146 assertEquals(0, rq3.claimQueues(server1).size());
147 assertEquals(2, rq3.getListOfReplicators().size());
148
149 SortedMap<String, SortedSet<String>> queues = rq2.claimQueues(server3);
150 assertEquals(5, queues.size());
151 assertEquals(1, rq2.getListOfReplicators().size());
152
153
154 assertEquals(0, rq2.claimQueues(server2).size());
155
156 assertEquals(6, rq2.getAllQueues().size());
157
158 rq2.removeAllQueues();
159
160 assertEquals(0, rq2.getListOfReplicators().size());
161 }
162
163 @Test
164 public void testHfileRefsReplicationQueues() throws ReplicationException, KeeperException {
165 rp.init();
166 rq1.init(server1);
167 rqc.init();
168
169 List<String> files1 = new ArrayList<String>(3);
170 files1.add("file_1");
171 files1.add("file_2");
172 files1.add("file_3");
173 assertNull(rqc.getReplicableHFiles(ID_ONE));
174 assertEquals(0, rqc.getAllPeersFromHFileRefsQueue().size());
175 rp.addPeer(ID_ONE, new ReplicationPeerConfig().setClusterKey(KEY_ONE), null);
176 rq1.addHFileRefs(ID_ONE, files1);
177 assertEquals(1, rqc.getAllPeersFromHFileRefsQueue().size());
178 assertEquals(3, rqc.getReplicableHFiles(ID_ONE).size());
179 List<String> files2 = new ArrayList<>(files1);
180 String removedString = files2.remove(0);
181 rq1.removeHFileRefs(ID_ONE, files2);
182 assertEquals(1, rqc.getReplicableHFiles(ID_ONE).size());
183 files2 = new ArrayList<>(1);
184 files2.add(removedString);
185 rq1.removeHFileRefs(ID_ONE, files2);
186 assertEquals(0, rqc.getReplicableHFiles(ID_ONE).size());
187 rp.removePeer(ID_ONE);
188 }
189
190 @Test
191 public void testRemovePeerForHFileRefs() throws ReplicationException, KeeperException {
192 rq1.init(server1);
193 rqc.init();
194
195 rp.init();
196 rp.addPeer(ID_ONE, new ReplicationPeerConfig().setClusterKey(KEY_ONE), null);
197 rp.addPeer(ID_TWO, new ReplicationPeerConfig().setClusterKey(KEY_TWO), null);
198
199 List<String> files1 = new ArrayList<String>(3);
200 files1.add("file_1");
201 files1.add("file_2");
202 files1.add("file_3");
203 rq1.addHFileRefs(ID_ONE, files1);
204 rq1.addHFileRefs(ID_TWO, files1);
205 assertEquals(2, rqc.getAllPeersFromHFileRefsQueue().size());
206 assertEquals(3, rqc.getReplicableHFiles(ID_ONE).size());
207 assertEquals(3, rqc.getReplicableHFiles(ID_TWO).size());
208
209 rp.removePeer(ID_ONE);
210 assertEquals(1, rqc.getAllPeersFromHFileRefsQueue().size());
211 assertNull(rqc.getReplicableHFiles(ID_ONE));
212 assertEquals(3, rqc.getReplicableHFiles(ID_TWO).size());
213
214 rp.removePeer(ID_TWO);
215 assertEquals(0, rqc.getAllPeersFromHFileRefsQueue().size());
216 assertNull(rqc.getReplicableHFiles(ID_TWO));
217 }
218
219 @Test
220 public void testReplicationPeers() throws Exception {
221 rp.init();
222
223
224 try {
225 rp.removePeer("bogus");
226 fail("Should have thrown an IllegalArgumentException when passed a bogus peerId");
227 } catch (IllegalArgumentException e) {
228 }
229 try {
230 rp.enablePeer("bogus");
231 fail("Should have thrown an IllegalArgumentException when passed a bogus peerId");
232 } catch (IllegalArgumentException e) {
233 }
234 try {
235 rp.disablePeer("bogus");
236 fail("Should have thrown an IllegalArgumentException when passed a bogus peerId");
237 } catch (IllegalArgumentException e) {
238 }
239 try {
240 rp.getStatusOfPeer("bogus");
241 fail("Should have thrown an IllegalArgumentException when passed a bogus peerId");
242 } catch (IllegalArgumentException e) {
243 }
244 assertFalse(rp.peerAdded("bogus"));
245 rp.peerRemoved("bogus");
246
247 assertNull(rp.getPeerConf("bogus"));
248 assertNumberOfPeers(0);
249
250
251 rp.addPeer(ID_ONE, new ReplicationPeerConfig().setClusterKey(KEY_ONE), null);
252 assertNumberOfPeers(1);
253 rp.addPeer(ID_TWO, new ReplicationPeerConfig().setClusterKey(KEY_TWO), null);
254 assertNumberOfPeers(2);
255
256
257 try {
258 rp.getStatusOfPeer(ID_ONE);
259 fail("There are no connected peers, should have thrown an IllegalArgumentException");
260 } catch (IllegalArgumentException e) {
261 }
262 assertEquals(KEY_ONE, ZKConfig.getZooKeeperClusterKey(rp.getPeerConf(ID_ONE).getSecond()));
263 rp.removePeer(ID_ONE);
264 rp.peerRemoved(ID_ONE);
265 assertNumberOfPeers(1);
266
267
268 rp.addPeer(ID_ONE, new ReplicationPeerConfig().setClusterKey(KEY_ONE), null);
269 rp.peerAdded(ID_ONE);
270 assertNumberOfPeers(2);
271 assertTrue(rp.getStatusOfPeer(ID_ONE));
272 rp.disablePeer(ID_ONE);
273 assertConnectedPeerStatus(false, ID_ONE);
274 rp.enablePeer(ID_ONE);
275 assertConnectedPeerStatus(true, ID_ONE);
276
277
278 rp.peerRemoved(ID_ONE);
279 assertNumberOfPeers(2);
280 try {
281 rp.getStatusOfPeer(ID_ONE);
282 fail("There are no connected peers, should have thrown an IllegalArgumentException");
283 } catch (IllegalArgumentException e) {
284 }
285 }
286
287 protected void assertConnectedPeerStatus(boolean status, String peerId) throws Exception {
288
289 if (status != rp.getStatusOfPeerFromBackingStore(peerId)) {
290 fail("ConnectedPeerStatus was " + !status + " but expected " + status + " in ZK");
291 }
292 while (true) {
293 if (status == rp.getStatusOfPeer(peerId)) {
294 return;
295 }
296 if (zkTimeoutCount < ZK_MAX_COUNT) {
297 LOG.debug("ConnectedPeerStatus was " + !status + " but expected " + status
298 + ", sleeping and trying again.");
299 Thread.sleep(ZK_SLEEP_INTERVAL);
300 } else {
301 fail("Timed out waiting for ConnectedPeerStatus to be " + status);
302 }
303 }
304 }
305
306 protected void assertNumberOfPeers(int total) {
307 assertEquals(total, rp.getAllPeerConfigs().size());
308 assertEquals(total, rp.getAllPeerIds().size());
309 assertEquals(total, rp.getAllPeerIds().size());
310 }
311
312
313
314
315
316 protected void populateQueues() throws ReplicationException {
317 rq1.addLog("trash", "trash");
318 rq1.removeQueue("trash");
319
320 rq2.addLog("qId1", "trash");
321 rq2.removeLog("qId1", "trash");
322
323 for (int i = 1; i < 6; i++) {
324 for (int j = 0; j < i; j++) {
325 rq3.addLog("qId" + i, "filename" + j);
326 }
327
328 rp.addPeer("qId" + i, new ReplicationPeerConfig().setClusterKey("bogus" + i), null);
329 }
330 }
331 }
332