View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.replication;
19  
20  import static org.junit.Assert.assertArrayEquals;
21  
22  import java.util.concurrent.BlockingQueue;
23  import java.util.concurrent.LinkedBlockingQueue;
24  import java.util.concurrent.TimeUnit;
25  import java.util.concurrent.TimeoutException;
26  import org.apache.hadoop.hbase.Cell;
27  import org.apache.hadoop.hbase.CellUtil;
28  import org.apache.hadoop.hbase.HBaseTestingUtility;
29  import org.apache.hadoop.hbase.TableName;
30  import org.apache.hadoop.hbase.client.Put;
31  import org.apache.hadoop.hbase.client.Table;
32  import org.apache.hadoop.hbase.client.replication.ReplicationAdmin;
33  import org.apache.hadoop.hbase.testclassification.MediumTests;
34  import org.apache.hadoop.hbase.testclassification.ReplicationTests;
35  import org.apache.hadoop.hbase.util.Bytes;
36  import org.apache.hadoop.hbase.wal.WAL;
37  import org.junit.AfterClass;
38  import org.junit.BeforeClass;
39  import org.junit.Test;
40  import org.junit.experimental.categories.Category;
41  import org.slf4j.Logger;
42  import org.slf4j.LoggerFactory;
43  
44  /**
45   * Confirm that the empty replication endpoint can work.
46   */
47  @Category({ ReplicationTests.class, MediumTests.class })
48  public class TestVerifyCellsReplicationEndpoint {
49  
50    private static final Logger LOG =
51      LoggerFactory.getLogger(TestVerifyCellsReplicationEndpoint.class);
52  
53    private static final HBaseTestingUtility UTIL = new HBaseTestingUtility();
54  
55    private static final TableName TABLE_NAME = TableName.valueOf("empty");
56  
57    private static final byte[] CF = Bytes.toBytes("family");
58  
59    private static final byte[] CQ = Bytes.toBytes("qualifier");
60  
61    private static final String PEER_ID = "empty";
62  
63    private static final BlockingQueue<Cell> CELLS = new LinkedBlockingQueue<>();
64  
65    public static final class EndpointForTest extends VerifyWALEntriesReplicationEndpoint {
66  
67      @Override
68      public boolean replicate(ReplicateContext replicateContext) {
69        LOG.info(replicateContext.getEntries().toString());
70        for (WAL.Entry entry: replicateContext.getEntries()) {
71          CELLS.addAll(entry.getEdit().getCells());
72        }
73        return super.replicate(replicateContext);
74      }
75    }
76  
77    @BeforeClass
78    public static void setUp() throws Exception {
79      UTIL.startMiniCluster(3);
80      // notice that we do not need to set replication scope here, EmptyReplicationEndpoint take all
81      // edits no matter what the replications scope is.
82      ReplicationPeerConfig peerConfig = new ReplicationPeerConfig();
83      peerConfig.setClusterKey("zk1:8888:/hbase");
84      peerConfig.setReplicationEndpointImpl(EndpointForTest.class.getName());
85      UTIL.createTable(TABLE_NAME, CF);
86      try (ReplicationAdmin replAdmin = new ReplicationAdmin(UTIL.getConfiguration())) {
87        replAdmin.addPeer(PEER_ID, peerConfig);
88      }
89    }
90  
91    @AfterClass
92    public static void tearDown() throws Exception {
93      UTIL.shutdownMiniCluster();
94    }
95  
96    @Test
97    public void test() throws Exception {
98      try (Table table = UTIL.getConnection().getTable(TABLE_NAME)) {
99        for (int i = 0; i < 100; i++) {
100         table.put(new Put(Bytes.toBytes(i)).addColumn(CF, CQ, Bytes.toBytes(i)));
101       }
102     }
103     long lastNoCellTime = -1;
104     for (int i = 0; i < 100;) {
105       Cell cell = CELLS.poll();
106       if (cell == null) {
107         if (lastNoCellTime < 0) {
108           lastNoCellTime = System.nanoTime();
109         } else {
110           if (System.nanoTime() - lastNoCellTime >= TimeUnit.SECONDS.toNanos(30)) {
111             throw new TimeoutException("Timeout waiting for wal edit");
112           }
113         }
114         Thread.sleep(1000);
115         continue;
116       }
117       lastNoCellTime = -1;
118       if (!Bytes.equals(CF, CellUtil.cloneFamily(cell))) {
119         // meta edits, such as open/close/flush, etc. skip
120         continue;
121       }
122       assertArrayEquals(Bytes.toBytes(i), CellUtil.cloneRow(cell));
123       assertArrayEquals(CQ, CellUtil.cloneQualifier(cell));
124       assertArrayEquals(Bytes.toBytes(i), CellUtil.cloneValue(cell));
125       i++;
126     }
127   }
128 }