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  
19  package org.apache.hadoop.hbase.replication;
20  
21  import java.util.List;
22  import java.util.Map;
23  
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  import org.apache.hadoop.hbase.Cell;
27  import org.apache.hadoop.hbase.CellUtil;
28  import org.apache.hadoop.hbase.TableName;
29  import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
30  import org.apache.hadoop.hbase.wal.WAL.Entry;
31  import org.apache.hadoop.hbase.util.Bytes;
32  
33  import com.google.common.base.Predicate;
34  
35  public class TableCfWALEntryFilter implements WALEntryFilter, WALCellFilter {
36  
37    private static final Log LOG = LogFactory.getLog(TableCfWALEntryFilter.class);
38    private ReplicationPeer peer;
39    private BulkLoadCellFilter bulkLoadFilter = new BulkLoadCellFilter();
40  
41    public TableCfWALEntryFilter(ReplicationPeer peer) {
42      this.peer = peer;
43    }
44  
45    @Override
46    public Entry filter(Entry entry) {
47      TableName tabName = entry.getKey().getTablename();
48      Map<TableName, List<String>> tableCFs = getTableCfs();
49      // If null means user has explicitly not configured any table CFs so all the tables data are
50      // applicable for replication
51      if (tableCFs == null) return entry;
52  
53      if (!tableCFs.containsKey(tabName)) {
54        return null;
55      }
56  
57      return entry;
58    }
59  
60    @Override
61    public Cell filterCell(final Entry entry, Cell cell) {
62      final Map<TableName, List<String>> tableCfs = getTableCfs();
63      if (tableCfs == null) return cell;
64      TableName tabName = entry.getKey().getTablename();
65      List<String> cfs = tableCfs.get(tabName);
66      // ignore(remove) kv if its cf isn't in the replicable cf list
67      // (empty cfs means all cfs of this table are replicable)
68      if (CellUtil.matchingColumn(cell, WALEdit.METAFAMILY, WALEdit.BULK_LOAD)) {
69        cell = bulkLoadFilter.filterCell(cell, new Predicate<byte[]>() {
70          @Override
71          public boolean apply(byte[] fam) {
72            if (tableCfs != null) {
73              List<String> cfs = tableCfs.get(entry.getKey().getTablename());
74              if (cfs != null && !cfs.contains(Bytes.toString(fam))) {
75                return true;
76              }
77            }
78            return false;
79          }
80        });
81      } else {
82        if ((cfs != null) && !cfs.contains(
83          Bytes.toString(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength()))) {
84          return null;
85        }
86      }
87      return cell;
88    }
89  
90    Map<TableName, List<String>> getTableCfs() {
91      Map<TableName, List<String>> tableCFs = null;
92      try {
93        tableCFs = this.peer.getTableCFs();
94      } catch (IllegalArgumentException e) {
95        LOG.error("should not happen: can't get tableCFs for peer " + peer.getId() +
96            ", degenerate as if it's not configured by keeping tableCFs==null");
97      }
98      return tableCFs;
99    }
100 }