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.assertNull;
021import static org.junit.Assert.assertTrue;
022import static org.mockito.Mockito.mock;
023import static org.mockito.Mockito.when;
024
025import java.util.ArrayList;
026import java.util.HashMap;
027import java.util.HashSet;
028import java.util.List;
029import java.util.Map;
030import java.util.Set;
031import java.util.TreeMap;
032import org.apache.hadoop.hbase.Cell;
033import org.apache.hadoop.hbase.CellComparatorImpl;
034import org.apache.hadoop.hbase.HBaseClassTestRule;
035import org.apache.hadoop.hbase.HConstants;
036import org.apache.hadoop.hbase.KeyValue;
037import org.apache.hadoop.hbase.TableName;
038import org.apache.hadoop.hbase.client.RegionInfoBuilder;
039import org.apache.hadoop.hbase.security.access.PermissionStorage;
040import org.apache.hadoop.hbase.security.visibility.VisibilityConstants;
041import org.apache.hadoop.hbase.testclassification.ReplicationTests;
042import org.apache.hadoop.hbase.testclassification.SmallTests;
043import org.apache.hadoop.hbase.util.Bytes;
044import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
045import org.apache.hadoop.hbase.wal.WAL.Entry;
046import org.apache.hadoop.hbase.wal.WALEdit;
047import org.apache.hadoop.hbase.wal.WALEditInternalHelper;
048import org.apache.hadoop.hbase.wal.WALKeyImpl;
049import org.junit.Assert;
050import org.junit.ClassRule;
051import org.junit.Test;
052import org.junit.experimental.categories.Category;
053
054import org.apache.hbase.thirdparty.com.google.common.collect.Lists;
055
056@Category({ ReplicationTests.class, SmallTests.class })
057public class TestReplicationWALEntryFilters {
058
059  @ClassRule
060  public static final HBaseClassTestRule CLASS_RULE =
061    HBaseClassTestRule.forClass(TestReplicationWALEntryFilters.class);
062
063  static byte[] a = new byte[] { 'a' };
064  static byte[] b = new byte[] { 'b' };
065  static byte[] c = new byte[] { 'c' };
066  static byte[] d = new byte[] { 'd' };
067
068  @Test
069  public void testSystemTableWALEntryFilter() {
070    SystemTableWALEntryFilter filter = new SystemTableWALEntryFilter();
071
072    // meta
073    WALKeyImpl key1 =
074      new WALKeyImpl(RegionInfoBuilder.FIRST_META_REGIONINFO.getEncodedNameAsBytes(),
075        TableName.META_TABLE_NAME, EnvironmentEdgeManager.currentTime());
076    Entry metaEntry = new Entry(key1, null);
077
078    assertNull(filter.filter(metaEntry));
079
080    // user table
081    WALKeyImpl key3 =
082      new WALKeyImpl(new byte[0], TableName.valueOf("foo"), EnvironmentEdgeManager.currentTime());
083    Entry userEntry = new Entry(key3, null);
084
085    assertEquals(userEntry, filter.filter(userEntry));
086
087    // hbase:acl should be allowed through the filter
088    WALKeyImpl key4 =
089      new WALKeyImpl(new byte[0], PermissionStorage.ACL_TABLE_NAME, System.currentTimeMillis());
090    Entry aclEntry = new Entry(key4, null);
091    assertEquals(aclEntry, filter.filter(aclEntry));
092
093    // hbase:labels should be allowed through the filter
094    WALKeyImpl key5 = new WALKeyImpl(new byte[0], VisibilityConstants.LABELS_TABLE_NAME,
095      System.currentTimeMillis());
096    Entry labelsEntry = new Entry(key5, null);
097    assertEquals(labelsEntry, filter.filter(labelsEntry));
098  }
099
100  @Test
101  public void testScopeWALEntryFilter() {
102    WALEntryFilter filter = new ChainWALEntryFilter(new ScopeWALEntryFilter());
103
104    Entry userEntry = createEntry(null, a, b);
105    Entry userEntryA = createEntry(null, a);
106    Entry userEntryB = createEntry(null, b);
107    Entry userEntryEmpty = createEntry(null);
108
109    // no scopes
110    assertNull(filter.filter(userEntry));
111    // now for serial replication, we will not filter out entries without a replication scope since
112    // serial replication still need the sequence id, but the cells will all be filtered out.
113    filter.setSerial(true);
114    assertTrue(filter.filter(userEntry).getEdit().isEmpty());
115    filter.setSerial(false);
116
117    // empty scopes
118    TreeMap<byte[], Integer> scopes = new TreeMap<>(Bytes.BYTES_COMPARATOR);
119    userEntry = createEntry(scopes, a, b);
120    assertNull(filter.filter(userEntry));
121    filter.setSerial(true);
122    assertTrue(filter.filter(userEntry).getEdit().isEmpty());
123    filter.setSerial(false);
124
125    // different scope
126    scopes = new TreeMap<>(Bytes.BYTES_COMPARATOR);
127    scopes.put(c, HConstants.REPLICATION_SCOPE_GLOBAL);
128    userEntry = createEntry(scopes, a, b);
129    // all kvs should be filtered
130    assertEquals(userEntryEmpty, filter.filter(userEntry));
131
132    // local scope
133    scopes = new TreeMap<>(Bytes.BYTES_COMPARATOR);
134    scopes.put(a, HConstants.REPLICATION_SCOPE_LOCAL);
135    userEntry = createEntry(scopes, a, b);
136    assertEquals(userEntryEmpty, filter.filter(userEntry));
137    scopes.put(b, HConstants.REPLICATION_SCOPE_LOCAL);
138    assertEquals(userEntryEmpty, filter.filter(userEntry));
139
140    // only scope a
141    scopes = new TreeMap<>(Bytes.BYTES_COMPARATOR);
142    scopes.put(a, HConstants.REPLICATION_SCOPE_GLOBAL);
143    userEntry = createEntry(scopes, a, b);
144    assertEquals(userEntryA, filter.filter(userEntry));
145    scopes.put(b, HConstants.REPLICATION_SCOPE_LOCAL);
146    assertEquals(userEntryA, filter.filter(userEntry));
147
148    // only scope b
149    scopes = new TreeMap<>(Bytes.BYTES_COMPARATOR);
150    scopes.put(b, HConstants.REPLICATION_SCOPE_GLOBAL);
151    userEntry = createEntry(scopes, a, b);
152    assertEquals(userEntryB, filter.filter(userEntry));
153    scopes.put(a, HConstants.REPLICATION_SCOPE_LOCAL);
154    assertEquals(userEntryB, filter.filter(userEntry));
155
156    // scope a and b
157    scopes = new TreeMap<>(Bytes.BYTES_COMPARATOR);
158    scopes.put(b, HConstants.REPLICATION_SCOPE_GLOBAL);
159    userEntry = createEntry(scopes, a, b);
160    assertEquals(userEntryB, filter.filter(userEntry));
161    scopes.put(a, HConstants.REPLICATION_SCOPE_LOCAL);
162    assertEquals(userEntryB, filter.filter(userEntry));
163  }
164
165  WALEntryFilter nullFilter = new WALEntryFilter() {
166    @Override
167    public Entry filter(Entry entry) {
168      return null;
169    }
170  };
171
172  WALEntryFilter passFilter = new WALEntryFilter() {
173    @Override
174    public Entry filter(Entry entry) {
175      return entry;
176    }
177  };
178
179  public static class FilterSomeCellsWALCellFilter implements WALEntryFilter, WALCellFilter {
180    @Override
181    public Entry filter(Entry entry) {
182      return entry;
183    }
184
185    @Override
186    public Cell filterCell(Entry entry, Cell cell) {
187      if (
188        Bytes.toString(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength()).equals("a")
189      ) {
190        return null;
191      } else {
192        return cell;
193      }
194    }
195  }
196
197  public static class FilterAllCellsWALCellFilter implements WALEntryFilter, WALCellFilter {
198    @Override
199    public Entry filter(Entry entry) {
200      return entry;
201    }
202
203    @Override
204    public Cell filterCell(Entry entry, Cell cell) {
205      return null;
206    }
207  }
208
209  @Test
210  public void testChainWALEntryWithCellFilter() {
211    Entry userEntry = createEntry(null, a, b, c);
212    ChainWALEntryFilter filterSomeCells =
213      new ChainWALEntryFilter(new FilterSomeCellsWALCellFilter());
214    // since WALCellFilter filter cells with rowkey 'a'
215    assertEquals(createEntry(null, b, c), filterSomeCells.filter(userEntry));
216
217    Entry userEntry2 = createEntry(null, b, c, d);
218    // since there is no cell to get filtered, nothing should get filtered
219    assertEquals(userEntry2, filterSomeCells.filter(userEntry2));
220
221    // since we filter all the cells, we should get empty entry
222    ChainWALEntryFilter filterAllCells = new ChainWALEntryFilter(new FilterAllCellsWALCellFilter());
223    assertEquals(createEntry(null), filterAllCells.filter(userEntry));
224  }
225
226  @Test
227  public void testChainWALEmptyEntryWithCellFilter() {
228    Entry userEntry = createEntry(null, a, b, c);
229    ChainWALEmptyEntryFilter filterSomeCells =
230      new ChainWALEmptyEntryFilter(new FilterSomeCellsWALCellFilter());
231    // since WALCellFilter filter cells with rowkey 'a'
232    assertEquals(createEntry(null, b, c), filterSomeCells.filter(userEntry));
233
234    Entry userEntry2 = createEntry(null, b, c, d);
235    // since there is no cell to get filtered, nothing should get filtered
236    assertEquals(userEntry2, filterSomeCells.filter(userEntry2));
237
238    ChainWALEmptyEntryFilter filterAllCells =
239      new ChainWALEmptyEntryFilter(new FilterAllCellsWALCellFilter());
240    assertEquals(createEntry(null), filterAllCells.filter(userEntry));
241    // let's set the filter empty entry flag to true now for the above case
242    filterAllCells.setFilterEmptyEntry(true);
243    // since WALCellFilter filter all cells, whole entry should be filtered
244    assertEquals(null, filterAllCells.filter(userEntry));
245  }
246
247  @Test
248  public void testChainWALEntryFilter() {
249    Entry userEntry = createEntry(null, a, b, c);
250
251    ChainWALEntryFilter filter = new ChainWALEntryFilter(passFilter);
252    assertEquals(createEntry(null, a, b, c), filter.filter(userEntry));
253
254    filter = new ChainWALEntryFilter(passFilter, passFilter);
255    assertEquals(createEntry(null, a, b, c), filter.filter(userEntry));
256
257    filter = new ChainWALEntryFilter(passFilter, passFilter, passFilter);
258    assertEquals(createEntry(null, a, b, c), filter.filter(userEntry));
259
260    filter = new ChainWALEntryFilter(nullFilter);
261    assertEquals(null, filter.filter(userEntry));
262
263    filter = new ChainWALEntryFilter(nullFilter, passFilter);
264    assertEquals(null, filter.filter(userEntry));
265
266    filter = new ChainWALEntryFilter(passFilter, nullFilter);
267    assertEquals(null, filter.filter(userEntry));
268
269    filter = new ChainWALEntryFilter(nullFilter, passFilter, nullFilter);
270    assertEquals(null, filter.filter(userEntry));
271
272    filter = new ChainWALEntryFilter(nullFilter, nullFilter);
273    assertEquals(null, filter.filter(userEntry));
274
275    // flatten
276    filter = new ChainWALEntryFilter(
277      new ChainWALEntryFilter(passFilter, new ChainWALEntryFilter(passFilter, passFilter),
278        new ChainWALEntryFilter(passFilter), new ChainWALEntryFilter(passFilter)),
279      new ChainWALEntryFilter(passFilter));
280    assertEquals(createEntry(null, a, b, c), filter.filter(userEntry));
281
282    filter = new ChainWALEntryFilter(
283      new ChainWALEntryFilter(passFilter,
284        new ChainWALEntryFilter(passFilter, new ChainWALEntryFilter(nullFilter))),
285      new ChainWALEntryFilter(passFilter));
286    assertEquals(null, filter.filter(userEntry));
287  }
288
289  @Test
290  public void testNamespaceTableCfWALEntryFilter() {
291    ReplicationPeer peer = mock(ReplicationPeer.class);
292    ReplicationPeerConfigBuilder peerConfigBuilder = ReplicationPeerConfig.newBuilder();
293
294    // 1. replicate_all flag is false, no namespaces and table-cfs config
295    peerConfigBuilder.setReplicateAllUserTables(false).setNamespaces(null).setTableCFsMap(null);
296    when(peer.getPeerConfig()).thenReturn(peerConfigBuilder.build());
297    Entry userEntry = createEntry(null, a, b, c);
298    ChainWALEntryFilter filter = new ChainWALEntryFilter(new NamespaceTableCfWALEntryFilter(peer));
299    assertEquals(null, filter.filter(userEntry));
300
301    // 2. replicate_all flag is false, and only config table-cfs in peer
302    // empty map
303    userEntry = createEntry(null, a, b, c);
304    Map<TableName, List<String>> tableCfs = new HashMap<>();
305    peerConfigBuilder.setReplicateAllUserTables(false).setTableCFsMap(tableCfs);
306    when(peer.getPeerConfig()).thenReturn(peerConfigBuilder.build());
307    filter = new ChainWALEntryFilter(new NamespaceTableCfWALEntryFilter(peer));
308    assertEquals(null, filter.filter(userEntry));
309
310    // table bar
311    userEntry = createEntry(null, a, b, c);
312    tableCfs = new HashMap<>();
313    tableCfs.put(TableName.valueOf("bar"), null);
314    peerConfigBuilder.setReplicateAllUserTables(false).setTableCFsMap(tableCfs);
315    when(peer.getPeerConfig()).thenReturn(peerConfigBuilder.build());
316    filter = new ChainWALEntryFilter(new NamespaceTableCfWALEntryFilter(peer));
317    assertEquals(null, filter.filter(userEntry));
318
319    // table foo:a
320    userEntry = createEntry(null, a, b, c);
321    tableCfs = new HashMap<>();
322    tableCfs.put(TableName.valueOf("foo"), Lists.newArrayList("a"));
323    peerConfigBuilder.setReplicateAllUserTables(false).setTableCFsMap(tableCfs);
324    when(peer.getPeerConfig()).thenReturn(peerConfigBuilder.build());
325    filter = new ChainWALEntryFilter(new NamespaceTableCfWALEntryFilter(peer));
326    assertEquals(createEntry(null, a), filter.filter(userEntry));
327
328    // table foo:a,c
329    userEntry = createEntry(null, a, b, c, d);
330    tableCfs = new HashMap<>();
331    tableCfs.put(TableName.valueOf("foo"), Lists.newArrayList("a", "c"));
332    peerConfigBuilder.setReplicateAllUserTables(false).setTableCFsMap(tableCfs);
333    when(peer.getPeerConfig()).thenReturn(peerConfigBuilder.build());
334    filter = new ChainWALEntryFilter(new NamespaceTableCfWALEntryFilter(peer));
335    assertEquals(createEntry(null, a, c), filter.filter(userEntry));
336
337    // 3. replicate_all flag is false, and only config namespaces in peer
338    when(peer.getTableCFs()).thenReturn(null);
339    // empty set
340    Set<String> namespaces = new HashSet<>();
341    peerConfigBuilder.setReplicateAllUserTables(false).setNamespaces(namespaces)
342      .setTableCFsMap(null);
343    when(peer.getPeerConfig()).thenReturn(peerConfigBuilder.build());
344    userEntry = createEntry(null, a, b, c);
345    filter = new ChainWALEntryFilter(new NamespaceTableCfWALEntryFilter(peer));
346    assertEquals(null, filter.filter(userEntry));
347
348    // namespace default
349    namespaces.add("default");
350    peerConfigBuilder.setReplicateAllUserTables(false).setNamespaces(namespaces);
351    when(peer.getPeerConfig()).thenReturn(peerConfigBuilder.build());
352    userEntry = createEntry(null, a, b, c);
353    filter = new ChainWALEntryFilter(new NamespaceTableCfWALEntryFilter(peer));
354    assertEquals(createEntry(null, a, b, c), filter.filter(userEntry));
355
356    // namespace ns1
357    namespaces = new HashSet<>();
358    namespaces.add("ns1");
359    peerConfigBuilder.setReplicateAllUserTables(false).setNamespaces(namespaces);
360    when(peer.getPeerConfig()).thenReturn(peerConfigBuilder.build());
361    userEntry = createEntry(null, a, b, c);
362    filter = new ChainWALEntryFilter(new NamespaceTableCfWALEntryFilter(peer));
363    assertEquals(null, filter.filter(userEntry));
364
365    // 4. replicate_all flag is false, and config namespaces and table-cfs both
366    // Namespaces config should not confict with table-cfs config
367    namespaces = new HashSet<>();
368    tableCfs = new HashMap<>();
369    namespaces.add("ns1");
370    tableCfs.put(TableName.valueOf("foo"), Lists.newArrayList("a", "c"));
371    peerConfigBuilder.setReplicateAllUserTables(false).setNamespaces(namespaces)
372      .setTableCFsMap(tableCfs);
373    when(peer.getPeerConfig()).thenReturn(peerConfigBuilder.build());
374    userEntry = createEntry(null, a, b, c);
375    filter = new ChainWALEntryFilter(new NamespaceTableCfWALEntryFilter(peer));
376    assertEquals(createEntry(null, a, c), filter.filter(userEntry));
377
378    namespaces = new HashSet<>();
379    tableCfs = new HashMap<>();
380    namespaces.add("default");
381    tableCfs.put(TableName.valueOf("ns1:foo"), Lists.newArrayList("a", "c"));
382    peerConfigBuilder.setReplicateAllUserTables(false).setNamespaces(namespaces)
383      .setTableCFsMap(tableCfs);
384    when(peer.getPeerConfig()).thenReturn(peerConfigBuilder.build());
385    userEntry = createEntry(null, a, b, c);
386    filter = new ChainWALEntryFilter(new NamespaceTableCfWALEntryFilter(peer));
387    assertEquals(createEntry(null, a, b, c), filter.filter(userEntry));
388
389    namespaces = new HashSet<>();
390    tableCfs = new HashMap<>();
391    namespaces.add("ns1");
392    tableCfs.put(TableName.valueOf("bar"), null);
393    peerConfigBuilder.setReplicateAllUserTables(false).setNamespaces(namespaces)
394      .setTableCFsMap(tableCfs);
395    when(peer.getPeerConfig()).thenReturn(peerConfigBuilder.build());
396    userEntry = createEntry(null, a, b, c);
397    filter = new ChainWALEntryFilter(new NamespaceTableCfWALEntryFilter(peer));
398    assertEquals(null, filter.filter(userEntry));
399  }
400
401  @Test
402  public void testNamespaceTableCfWALEntryFilter2() {
403    ReplicationPeer peer = mock(ReplicationPeer.class);
404    ReplicationPeerConfigBuilder peerConfigBuilder = ReplicationPeerConfig.newBuilder();
405
406    // 1. replicate_all flag is true
407    // and no exclude namespaces and no exclude table-cfs config
408    peerConfigBuilder.setReplicateAllUserTables(true).setExcludeNamespaces(null)
409      .setExcludeTableCFsMap(null);
410    when(peer.getPeerConfig()).thenReturn(peerConfigBuilder.build());
411    Entry userEntry = createEntry(null, a, b, c);
412    ChainWALEntryFilter filter = new ChainWALEntryFilter(new NamespaceTableCfWALEntryFilter(peer));
413    assertEquals(createEntry(null, a, b, c), filter.filter(userEntry));
414
415    // 2. replicate_all flag is true, and only config exclude namespaces
416    // empty set
417    Set<String> namespaces = new HashSet<String>();
418    peerConfigBuilder.setExcludeNamespaces(namespaces).setExcludeTableCFsMap(null);
419    when(peer.getPeerConfig()).thenReturn(peerConfigBuilder.build());
420    userEntry = createEntry(null, a, b, c);
421    filter = new ChainWALEntryFilter(new NamespaceTableCfWALEntryFilter(peer));
422    assertEquals(createEntry(null, a, b, c), filter.filter(userEntry));
423
424    // exclude namespace default
425    namespaces.add("default");
426    peerConfigBuilder.setExcludeNamespaces(namespaces).setExcludeTableCFsMap(null);
427    when(peer.getPeerConfig()).thenReturn(peerConfigBuilder.build());
428    userEntry = createEntry(null, a, b, c);
429    filter = new ChainWALEntryFilter(new NamespaceTableCfWALEntryFilter(peer));
430    assertEquals(null, filter.filter(userEntry));
431
432    // exclude namespace ns1
433    namespaces = new HashSet<String>();
434    namespaces.add("ns1");
435    peerConfigBuilder.setExcludeNamespaces(namespaces).setExcludeTableCFsMap(null);
436    when(peer.getPeerConfig()).thenReturn(peerConfigBuilder.build());
437    userEntry = createEntry(null, a, b, c);
438    filter = new ChainWALEntryFilter(new NamespaceTableCfWALEntryFilter(peer));
439    assertEquals(createEntry(null, a, b, c), filter.filter(userEntry));
440
441    // 3. replicate_all flag is true, and only config exclude table-cfs
442    // empty table-cfs map
443    Map<TableName, List<String>> tableCfs = new HashMap<TableName, List<String>>();
444    peerConfigBuilder.setExcludeNamespaces(null).setExcludeTableCFsMap(tableCfs);
445    when(peer.getPeerConfig()).thenReturn(peerConfigBuilder.build());
446    userEntry = createEntry(null, a, b, c);
447    filter = new ChainWALEntryFilter(new NamespaceTableCfWALEntryFilter(peer));
448    assertEquals(createEntry(null, a, b, c), filter.filter(userEntry));
449
450    // exclude table bar
451    tableCfs = new HashMap<TableName, List<String>>();
452    tableCfs.put(TableName.valueOf("bar"), null);
453    peerConfigBuilder.setExcludeNamespaces(null).setExcludeTableCFsMap(tableCfs);
454    when(peer.getPeerConfig()).thenReturn(peerConfigBuilder.build());
455    userEntry = createEntry(null, a, b, c);
456    filter = new ChainWALEntryFilter(new NamespaceTableCfWALEntryFilter(peer));
457    assertEquals(createEntry(null, a, b, c), filter.filter(userEntry));
458
459    // exclude table foo:a
460    tableCfs = new HashMap<TableName, List<String>>();
461    tableCfs.put(TableName.valueOf("foo"), Lists.newArrayList("a"));
462    peerConfigBuilder.setExcludeNamespaces(null).setExcludeTableCFsMap(tableCfs);
463    when(peer.getPeerConfig()).thenReturn(peerConfigBuilder.build());
464    userEntry = createEntry(null, a, b, c);
465    filter = new ChainWALEntryFilter(new NamespaceTableCfWALEntryFilter(peer));
466    assertEquals(createEntry(null, b, c), filter.filter(userEntry));
467
468    // 4. replicate_all flag is true, and config exclude namespaces and table-cfs both
469    // exclude ns1 and table foo:a,c
470    namespaces = new HashSet<String>();
471    tableCfs = new HashMap<TableName, List<String>>();
472    namespaces.add("ns1");
473    tableCfs.put(TableName.valueOf("foo"), Lists.newArrayList("a", "c"));
474    peerConfigBuilder.setExcludeNamespaces(namespaces).setExcludeTableCFsMap(tableCfs);
475    when(peer.getPeerConfig()).thenReturn(peerConfigBuilder.build());
476    userEntry = createEntry(null, a, b, c);
477    filter = new ChainWALEntryFilter(new NamespaceTableCfWALEntryFilter(peer));
478    assertEquals(createEntry(null, b), filter.filter(userEntry));
479
480    // exclude namespace default and table ns1:bar
481    namespaces = new HashSet<String>();
482    tableCfs = new HashMap<TableName, List<String>>();
483    namespaces.add("default");
484    tableCfs.put(TableName.valueOf("ns1:bar"), new ArrayList<String>());
485    peerConfigBuilder.setExcludeNamespaces(namespaces).setExcludeTableCFsMap(tableCfs);
486    when(peer.getPeerConfig()).thenReturn(peerConfigBuilder.build());
487    userEntry = createEntry(null, a, b, c);
488    filter = new ChainWALEntryFilter(new NamespaceTableCfWALEntryFilter(peer));
489    assertEquals(null, filter.filter(userEntry));
490  }
491
492  private Entry createEntry(TreeMap<byte[], Integer> scopes, byte[]... kvs) {
493    WALKeyImpl key1 = new WALKeyImpl(new byte[0], TableName.valueOf("foo"),
494      EnvironmentEdgeManager.currentTime(), scopes);
495    WALEdit edit1 = new WALEdit();
496
497    for (byte[] kv : kvs) {
498      WALEditInternalHelper.addExtendedCell(edit1, new KeyValue(kv, kv, kv));
499    }
500    return new Entry(key1, edit1);
501  }
502
503  private void assertEquals(Entry e1, Entry e2) {
504    Assert.assertEquals(e1 == null, e2 == null);
505    if (e1 == null) {
506      return;
507    }
508
509    // do not compare WALKeys
510
511    // compare kvs
512    Assert.assertEquals(e1.getEdit() == null, e2.getEdit() == null);
513    if (e1.getEdit() == null) {
514      return;
515    }
516    List<Cell> cells1 = e1.getEdit().getCells();
517    List<Cell> cells2 = e2.getEdit().getCells();
518    Assert.assertEquals(cells1.size(), cells2.size());
519    for (int i = 0; i < cells1.size(); i++) {
520      CellComparatorImpl.COMPARATOR.compare(cells1.get(i), cells2.get(i));
521    }
522  }
523}