001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.replication;
019
020import static org.junit.Assert.assertFalse;
021import static org.junit.Assert.assertTrue;
022
023import java.util.List;
024import java.util.Map;
025import org.apache.hadoop.hbase.HBaseClassTestRule;
026import org.apache.hadoop.hbase.TableName;
027import org.apache.hadoop.hbase.testclassification.ClientTests;
028import org.apache.hadoop.hbase.testclassification.SmallTests;
029import org.apache.hadoop.hbase.util.BuilderStyleTest;
030import org.apache.hadoop.hbase.util.Bytes;
031import org.junit.ClassRule;
032import org.junit.Test;
033import org.junit.experimental.categories.Category;
034
035import org.apache.hbase.thirdparty.com.google.common.collect.Lists;
036import org.apache.hbase.thirdparty.com.google.common.collect.Maps;
037import org.apache.hbase.thirdparty.com.google.common.collect.Sets;
038
039@Category({ ClientTests.class, SmallTests.class })
040public class TestReplicationPeerConfig {
041
042  @ClassRule
043  public static final HBaseClassTestRule CLASS_RULE =
044    HBaseClassTestRule.forClass(TestReplicationPeerConfig.class);
045
046  private static final String NAMESPACE_REPLICATE = "replicate";
047  private static final String NAMESPACE_OTHER = "other";
048  private static final TableName TABLE_A = TableName.valueOf(NAMESPACE_REPLICATE, "testA");
049  private static final TableName TABLE_B = TableName.valueOf(NAMESPACE_REPLICATE, "testB");
050  private static final byte[] FAMILY1 = Bytes.toBytes("cf1");
051  private static final byte[] FAMILY2 = Bytes.toBytes("cf2");
052
053  @Test
054  public void testClassMethodsAreBuilderStyle() {
055    /*
056     * ReplicationPeerConfig should have a builder style setup where setXXX/addXXX methods can be
057     * chainable together: . For example: ReplicationPeerConfig htd = new ReplicationPeerConfig()
058     * .setFoo(foo) .setBar(bar) .setBuz(buz) This test ensures that all methods starting with "set"
059     * returns the declaring object
060     */
061
062    BuilderStyleTest.assertClassesAreBuilderStyle(ReplicationPeerConfig.class);
063  }
064
065  @Test
066  public void testNeedToReplicateWithReplicatingAll() {
067    // 1. replication_all flag is true, no namespaces and table-cfs config
068    ReplicationPeerConfig peerConfig = new ReplicationPeerConfig.ReplicationPeerConfigBuilderImpl()
069      .setReplicateAllUserTables(true).build();
070    assertTrue(peerConfig.needToReplicate(TABLE_A));
071
072    // 2. replicate_all flag is true, and config in excludedTableCfs
073    // Exclude empty table-cfs map
074    peerConfig = new ReplicationPeerConfig.ReplicationPeerConfigBuilderImpl()
075      .setReplicateAllUserTables(true).setExcludeTableCFsMap(Maps.newHashMap()).build();
076    assertTrue(peerConfig.needToReplicate(TABLE_A));
077
078    // Exclude table B
079    Map<TableName, List<String>> tableCfs = Maps.newHashMap();
080    tableCfs.put(TABLE_B, null);
081    peerConfig = new ReplicationPeerConfig.ReplicationPeerConfigBuilderImpl()
082      .setReplicateAllUserTables(true).setExcludeTableCFsMap(tableCfs).build();
083    assertTrue(peerConfig.needToReplicate(TABLE_A));
084    assertFalse(peerConfig.needToReplicate(TABLE_B));
085
086    // 3. replicate_all flag is true, and config in excludeNamespaces
087    // Exclude empty namespace set
088    peerConfig = new ReplicationPeerConfig.ReplicationPeerConfigBuilderImpl()
089      .setReplicateAllUserTables(true).setExcludeNamespaces(Sets.newHashSet()).build();
090    assertTrue(peerConfig.needToReplicate(TABLE_A));
091
092    // Exclude namespace other
093    peerConfig =
094      new ReplicationPeerConfig.ReplicationPeerConfigBuilderImpl().setReplicateAllUserTables(true)
095        .setExcludeNamespaces(Sets.newHashSet(NAMESPACE_OTHER)).build();
096    assertTrue(peerConfig.needToReplicate(TABLE_A));
097
098    // Exclude namespace replication
099    peerConfig =
100      new ReplicationPeerConfig.ReplicationPeerConfigBuilderImpl().setReplicateAllUserTables(true)
101        .setExcludeNamespaces(Sets.newHashSet(NAMESPACE_REPLICATE)).build();
102    assertFalse(peerConfig.needToReplicate(TABLE_A));
103
104    // 4. replicate_all flag is true, and config excludeNamespaces and excludedTableCfs both
105    // Namespaces config doesn't conflict with table-cfs config
106    tableCfs = Maps.newHashMap();
107    tableCfs.put(TABLE_A, null);
108    peerConfig = new ReplicationPeerConfig.ReplicationPeerConfigBuilderImpl()
109      .setReplicateAllUserTables(true).setExcludeNamespaces(Sets.newHashSet(NAMESPACE_REPLICATE))
110      .setExcludeTableCFsMap(tableCfs).build();
111    assertFalse(peerConfig.needToReplicate(TABLE_A));
112
113    // Namespaces config conflicts with table-cfs config
114    tableCfs = Maps.newHashMap();
115    tableCfs.put(TABLE_A, null);
116    peerConfig = new ReplicationPeerConfig.ReplicationPeerConfigBuilderImpl()
117      .setReplicateAllUserTables(true).setExcludeTableCFsMap(tableCfs)
118      .setExcludeNamespaces(Sets.newHashSet(NAMESPACE_OTHER)).build();
119    assertFalse(peerConfig.needToReplicate(TABLE_A));
120    assertTrue(peerConfig.needToReplicate(TABLE_B));
121
122    tableCfs = Maps.newHashMap();
123    tableCfs.put(TABLE_B, null);
124    peerConfig = new ReplicationPeerConfig.ReplicationPeerConfigBuilderImpl()
125      .setReplicateAllUserTables(true).setExcludeTableCFsMap(tableCfs)
126      .setExcludeNamespaces(Sets.newHashSet(NAMESPACE_REPLICATE)).build();
127    assertFalse(peerConfig.needToReplicate(TABLE_A));
128    assertFalse(peerConfig.needToReplicate(TABLE_B));
129  }
130
131  @Test
132  public void testNeedToReplicateWithoutReplicatingAll() {
133    ReplicationPeerConfig peerConfig;
134    Map<TableName, List<String>> tableCfs;
135
136    // 1. replication_all flag is false, no namespaces and table-cfs config
137    peerConfig = new ReplicationPeerConfig.ReplicationPeerConfigBuilderImpl()
138      .setReplicateAllUserTables(false).build();
139    assertFalse(peerConfig.needToReplicate(TABLE_A));
140
141    // 2. replicate_all flag is false, and only config table-cfs in peer
142    // Set empty table-cfs map
143    peerConfig = new ReplicationPeerConfig.ReplicationPeerConfigBuilderImpl()
144      .setReplicateAllUserTables(false).setTableCFsMap(Maps.newHashMap()).build();
145    assertFalse(peerConfig.needToReplicate(TABLE_A));
146
147    // Set table B
148    tableCfs = Maps.newHashMap();
149    tableCfs.put(TABLE_B, null);
150    peerConfig = new ReplicationPeerConfig.ReplicationPeerConfigBuilderImpl()
151      .setReplicateAllUserTables(false).setTableCFsMap(tableCfs).build();
152    assertFalse(peerConfig.needToReplicate(TABLE_A));
153    assertTrue(peerConfig.needToReplicate(TABLE_B));
154
155    // 3. replication_all flag is false, and only config namespace in peer
156    // Set empty namespace set
157    peerConfig = new ReplicationPeerConfig.ReplicationPeerConfigBuilderImpl()
158      .setReplicateAllUserTables(false).setNamespaces(Sets.newHashSet()).build();
159    assertFalse(peerConfig.needToReplicate(TABLE_A));
160
161    // Set namespace other
162    peerConfig = new ReplicationPeerConfig.ReplicationPeerConfigBuilderImpl()
163      .setReplicateAllUserTables(false).setNamespaces(Sets.newHashSet(NAMESPACE_OTHER)).build();
164    assertFalse(peerConfig.needToReplicate(TABLE_A));
165
166    // Set namespace replication
167    peerConfig = new ReplicationPeerConfig.ReplicationPeerConfigBuilderImpl()
168      .setReplicateAllUserTables(false).setNamespaces(Sets.newHashSet(NAMESPACE_REPLICATE)).build();
169    assertTrue(peerConfig.needToReplicate(TABLE_A));
170
171    // 4. replicate_all flag is false, and config namespaces and table-cfs both
172    // Namespaces config doesn't conflict with table-cfs config
173    tableCfs = Maps.newHashMap();
174    tableCfs.put(TABLE_A, null);
175    peerConfig =
176      new ReplicationPeerConfig.ReplicationPeerConfigBuilderImpl().setReplicateAllUserTables(false)
177        .setTableCFsMap(tableCfs).setNamespaces(Sets.newHashSet(NAMESPACE_REPLICATE)).build();
178    assertTrue(peerConfig.needToReplicate(TABLE_A));
179
180    // Namespaces config conflicts with table-cfs config
181    tableCfs = Maps.newHashMap();
182    tableCfs.put(TABLE_A, null);
183    peerConfig =
184      new ReplicationPeerConfig.ReplicationPeerConfigBuilderImpl().setReplicateAllUserTables(false)
185        .setTableCFsMap(tableCfs).setNamespaces(Sets.newHashSet(NAMESPACE_OTHER)).build();
186    assertTrue(peerConfig.needToReplicate(TABLE_A));
187
188    tableCfs = Maps.newHashMap();
189    tableCfs.put(TABLE_B, null);
190    peerConfig =
191      new ReplicationPeerConfig.ReplicationPeerConfigBuilderImpl().setReplicateAllUserTables(false)
192        .setNamespaces(Sets.newHashSet(NAMESPACE_REPLICATE)).setTableCFsMap(tableCfs).build();
193    assertTrue(peerConfig.needToReplicate(TABLE_A));
194  }
195
196  @Test
197  public void testNeedToReplicateCFWithReplicatingAll() {
198    Map<TableName, List<String>> excludeTableCfs = Maps.newHashMap();
199    excludeTableCfs.put(TABLE_A, null);
200    ReplicationPeerConfig peerConfig = new ReplicationPeerConfig.ReplicationPeerConfigBuilderImpl()
201      .setReplicateAllUserTables(true).setExcludeTableCFsMap(excludeTableCfs).build();
202    assertFalse(peerConfig.needToReplicate(TABLE_A));
203    assertFalse(peerConfig.needToReplicate(TABLE_A, FAMILY1));
204    assertFalse(peerConfig.needToReplicate(TABLE_A, FAMILY2));
205
206    excludeTableCfs = Maps.newHashMap();
207    excludeTableCfs.put(TABLE_A, Lists.newArrayList());
208    peerConfig = new ReplicationPeerConfig.ReplicationPeerConfigBuilderImpl()
209      .setReplicateAllUserTables(true).setExcludeTableCFsMap(excludeTableCfs).build();
210    assertFalse(peerConfig.needToReplicate(TABLE_A));
211    assertFalse(peerConfig.needToReplicate(TABLE_A, FAMILY1));
212    assertFalse(peerConfig.needToReplicate(TABLE_A, FAMILY2));
213
214    excludeTableCfs = Maps.newHashMap();
215    excludeTableCfs.put(TABLE_A, Lists.newArrayList(Bytes.toString(FAMILY1)));
216    peerConfig = new ReplicationPeerConfig.ReplicationPeerConfigBuilderImpl()
217      .setReplicateAllUserTables(true).setExcludeTableCFsMap(excludeTableCfs).build();
218    assertTrue(peerConfig.needToReplicate(TABLE_A));
219    assertFalse(peerConfig.needToReplicate(TABLE_A, FAMILY1));
220    assertTrue(peerConfig.needToReplicate(TABLE_A, FAMILY2));
221  }
222
223  @Test
224  public void testNeedToReplicateCFWithoutReplicatingAll() {
225    Map<TableName, List<String>> tableCfs = Maps.newHashMap();
226    tableCfs.put(TABLE_A, null);
227    ReplicationPeerConfig peerConfig = new ReplicationPeerConfig.ReplicationPeerConfigBuilderImpl()
228      .setReplicateAllUserTables(false).setTableCFsMap(tableCfs).build();
229    assertTrue(peerConfig.needToReplicate(TABLE_A));
230    assertTrue(peerConfig.needToReplicate(TABLE_A, FAMILY1));
231    assertTrue(peerConfig.needToReplicate(TABLE_A, FAMILY2));
232
233    tableCfs = Maps.newHashMap();
234    tableCfs.put(TABLE_A, Lists.newArrayList());
235    peerConfig = new ReplicationPeerConfig.ReplicationPeerConfigBuilderImpl()
236      .setReplicateAllUserTables(false).setTableCFsMap(tableCfs).build();
237    assertTrue(peerConfig.needToReplicate(TABLE_A));
238    assertTrue(peerConfig.needToReplicate(TABLE_A, FAMILY1));
239    assertTrue(peerConfig.needToReplicate(TABLE_A, FAMILY2));
240
241    tableCfs = Maps.newHashMap();
242    tableCfs.put(TABLE_A, Lists.newArrayList(Bytes.toString(FAMILY1)));
243    peerConfig = new ReplicationPeerConfig.ReplicationPeerConfigBuilderImpl()
244      .setReplicateAllUserTables(false).setTableCFsMap(tableCfs).build();
245    assertTrue(peerConfig.needToReplicate(TABLE_A));
246    assertTrue(peerConfig.needToReplicate(TABLE_A, FAMILY1));
247    assertFalse(peerConfig.needToReplicate(TABLE_A, FAMILY2));
248  }
249}