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.assertNotNull;
23 import static org.junit.Assert.assertNull;
24
25 import java.io.IOException;
26 import java.util.concurrent.ExecutorService;
27 import java.util.concurrent.Executors;
28 import java.util.concurrent.Future;
29
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.apache.hadoop.conf.Configuration;
33 import org.apache.hadoop.fs.FileSystem;
34 import org.apache.hadoop.fs.Path;
35 import org.apache.hadoop.hbase.CoordinatedStateManager;
36 import org.apache.hadoop.hbase.MiniHBaseCluster;
37 import org.apache.hadoop.hbase.TableName;
38 import org.apache.hadoop.hbase.Waiter;
39 import org.apache.hadoop.hbase.Waiter.Predicate;
40 import org.apache.hadoop.hbase.HBaseConfiguration;
41 import org.apache.hadoop.hbase.HBaseTestingUtility;
42 import org.apache.hadoop.hbase.HConstants;
43 import org.apache.hadoop.hbase.KeyValue;
44 import org.apache.hadoop.hbase.client.replication.ReplicationAdmin;
45 import org.apache.hadoop.hbase.regionserver.HRegionServer;
46 import org.apache.hadoop.hbase.replication.regionserver.Replication;
47 import org.apache.hadoop.hbase.replication.regionserver.ReplicationSourceManager;
48 import org.apache.hadoop.hbase.testclassification.MediumTests;
49 import org.apache.hadoop.hbase.wal.WAL;
50 import org.apache.hadoop.hbase.wal.WALProvider;
51 import org.apache.hadoop.hbase.wal.WALFactory;
52 import org.apache.hadoop.hbase.wal.WALKey;
53 import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
54 import org.apache.hadoop.hbase.replication.regionserver.HBaseInterClusterReplicationEndpoint;
55 import org.apache.hadoop.hbase.replication.regionserver.ReplicationSource;
56 import org.apache.hadoop.hbase.util.Bytes;
57
58 import org.junit.AfterClass;
59 import org.junit.BeforeClass;
60 import org.junit.Test;
61 import org.junit.experimental.categories.Category;
62
63 import static org.mockito.Mockito.mock;
64
65 @Category(MediumTests.class)
66 public class TestReplicationSource {
67
68 private static final Log LOG =
69 LogFactory.getLog(TestReplicationSource.class);
70 private final static HBaseTestingUtility TEST_UTIL =
71 new HBaseTestingUtility();
72 private final static HBaseTestingUtility TEST_UTIL_PEER =
73 new HBaseTestingUtility();
74 private static FileSystem FS;
75 private static Path oldLogDir;
76 private static Path logDir;
77 private static Configuration conf = TEST_UTIL.getConfiguration();
78
79
80
81
82 @BeforeClass
83 public static void setUpBeforeClass() throws Exception {
84 TEST_UTIL.startMiniDFSCluster(1);
85 FS = TEST_UTIL.getDFSCluster().getFileSystem();
86 Path rootDir = TEST_UTIL.createRootDir();
87 oldLogDir = new Path(rootDir, HConstants.HREGION_OLDLOGDIR_NAME);
88 if (FS.exists(oldLogDir)) FS.delete(oldLogDir, true);
89 logDir = new Path(rootDir, HConstants.HREGION_LOGDIR_NAME);
90 if (FS.exists(logDir)) FS.delete(logDir, true);
91 }
92
93 @AfterClass
94 public static void tearDownAfterClass() throws Exception {
95 TEST_UTIL_PEER.shutdownMiniHBaseCluster();
96 TEST_UTIL.shutdownMiniHBaseCluster();
97 TEST_UTIL.shutdownMiniDFSCluster();
98 }
99
100
101
102
103
104
105
106 @Test
107 public void testLogMoving() throws Exception{
108 Path logPath = new Path(logDir, "log");
109 if (!FS.exists(logDir)) FS.mkdirs(logDir);
110 if (!FS.exists(oldLogDir)) FS.mkdirs(oldLogDir);
111 WALProvider.Writer writer = WALFactory.createWALWriter(FS, logPath,
112 TEST_UTIL.getConfiguration());
113 for(int i = 0; i < 3; i++) {
114 byte[] b = Bytes.toBytes(Integer.toString(i));
115 KeyValue kv = new KeyValue(b,b,b);
116 WALEdit edit = new WALEdit();
117 edit.add(kv);
118 WALKey key = new WALKey(b, TableName.valueOf(b), 0, 0,
119 HConstants.DEFAULT_CLUSTER_ID);
120 writer.append(new WAL.Entry(key, edit));
121 writer.sync();
122 }
123 writer.close();
124
125 WAL.Reader reader = WALFactory.createReader(FS, logPath, TEST_UTIL.getConfiguration());
126 WAL.Entry entry = reader.next();
127 assertNotNull(entry);
128
129 Path oldLogPath = new Path(oldLogDir, "log");
130 FS.rename(logPath, oldLogPath);
131
132 entry = reader.next();
133 assertNotNull(entry);
134
135 entry = reader.next();
136 entry = reader.next();
137
138 assertNull(entry);
139 reader.close();
140 }
141
142
143
144
145 @Test
146 public void testTerminateTimeout() throws Exception {
147 final ReplicationSource source = new ReplicationSource();
148 ReplicationEndpoint replicationEndpoint = new HBaseInterClusterReplicationEndpoint() {
149 @Override
150 protected void doStart() {
151 notifyStarted();
152 }
153
154 @Override
155 protected void doStop() {
156
157
158 }
159 };
160 replicationEndpoint.start();
161 ReplicationPeers mockPeers = mock(ReplicationPeers.class);
162 Configuration testConf = HBaseConfiguration.create();
163 testConf.setInt("replication.source.maxretriesmultiplier", 1);
164 source.init(testConf, null, null, null, mockPeers, null, "testPeer", null, replicationEndpoint,
165 null);
166 ExecutorService executor = Executors.newSingleThreadExecutor();
167 final Future<?> future = executor.submit(new Runnable() {
168
169 @Override
170 public void run() {
171 source.terminate("testing source termination");
172 }
173 });
174 long sleepForRetries = testConf.getLong("replication.source.sleepforretries", 1000);
175 Waiter.waitFor(testConf, sleepForRetries * 2, new Predicate<Exception>() {
176
177 @Override
178 public boolean evaluate() throws Exception {
179 return future.isDone();
180 }
181
182 });
183
184 }
185
186
187
188
189
190
191 @Test
192 public void testServerShutdownRecoveredQueue() throws Exception {
193 try {
194
195 conf.set("hbase.wal.provider", "defaultProvider");
196 conf.setInt("replication.sleep.before.failover", 2000);
197
198 conf.set(HConstants.REGION_SERVER_IMPL, ShutdownDelayRegionServer.class.getName());
199 MiniHBaseCluster cluster = TEST_UTIL.startMiniCluster(2);
200 TEST_UTIL_PEER.startMiniCluster(1);
201
202 HRegionServer serverA = cluster.getRegionServer(0);
203 final ReplicationSourceManager managerA =
204 ((Replication) serverA.getReplicationSourceService()).getReplicationManager();
205 HRegionServer serverB = cluster.getRegionServer(1);
206 final ReplicationSourceManager managerB =
207 ((Replication) serverB.getReplicationSourceService()).getReplicationManager();
208 final ReplicationAdmin replicationAdmin = new ReplicationAdmin(TEST_UTIL.getConfiguration());
209
210 final String peerId = "TestPeer";
211 replicationAdmin.addPeer(peerId,
212 new ReplicationPeerConfig().setClusterKey(TEST_UTIL_PEER.getClusterKey()), null);
213
214 Waiter.waitFor(conf, 20000, new Waiter.Predicate<Exception>() {
215 @Override public boolean evaluate() throws Exception {
216 return !(managerA.getSources().isEmpty() || managerB.getSources().isEmpty());
217 }
218 });
219
220
221
222 replicationAdmin.disablePeer(peerId);
223
224
225
226 cluster.stopRegionServer(serverA.getServerName());
227 Waiter.waitFor(conf, 20000, new Waiter.Predicate<Exception>() {
228 @Override public boolean evaluate() throws Exception {
229 return managerB.getOldSources().size() == 1;
230 }
231 });
232
233 final HRegionServer serverC = cluster.startRegionServer().getRegionServer();
234 serverC.waitForServerOnline();
235 Waiter.waitFor(conf, 20000, new Waiter.Predicate<Exception>() {
236 @Override public boolean evaluate() throws Exception {
237 return serverC.getReplicationSourceService() != null;
238 }
239 });
240 final ReplicationSourceManager managerC =
241 ((Replication) serverC.getReplicationSourceService()).getReplicationManager();
242
243 assertEquals(0, managerC.getOldSources().size());
244
245
246
247
248
249 cluster.stopRegionServer(serverB.getServerName());
250 Waiter.waitFor(conf, 20000, new Waiter.Predicate<Exception>() {
251 @Override public boolean evaluate() throws Exception {
252 return managerC.getOldSources().size() == 2;
253 }
254 });
255 replicationAdmin.enablePeer(peerId);
256 Waiter.waitFor(conf, 20000, new Waiter.Predicate<Exception>() {
257 @Override public boolean evaluate() throws Exception {
258 return managerC.getOldSources().size() == 0;
259 }
260 });
261 } finally {
262 conf.set(HConstants.REGION_SERVER_IMPL, HRegionServer.class.getName());
263 }
264 }
265
266
267
268
269 public static class ShutdownDelayRegionServer extends HRegionServer {
270 public ShutdownDelayRegionServer(Configuration conf) throws IOException, InterruptedException {
271 super(conf);
272 }
273
274 public ShutdownDelayRegionServer(Configuration conf, CoordinatedStateManager csm)
275 throws IOException, InterruptedException {
276 super(conf, csm);
277 }
278
279 @Override
280 protected void stopServiceThreads() {
281
282
283 LOG.info("Adding a delay to the regionserver shutdown");
284 try {
285 Thread.sleep(2000);
286 } catch (InterruptedException ex) {
287 LOG.error("Interrupted while sleeping");
288 }
289 super.stopServiceThreads();
290 }
291 }
292 }
293