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.security.visibility;
19  
20  import java.io.IOException;
21  import java.util.Map;
22  import java.util.Objects;
23  
24  import org.apache.hadoop.hbase.classification.InterfaceAudience;
25  import org.apache.hadoop.hbase.Cell;
26  import org.apache.hadoop.hbase.filter.FilterBase;
27  import org.apache.hadoop.hbase.util.ByteRange;
28  import org.apache.hadoop.hbase.util.Bytes;
29  import org.apache.hadoop.hbase.util.SimpleMutableByteRange;
30  
31  /**
32   * This Filter checks the visibility expression with each KV against visibility labels associated
33   * with the scan. Based on the check the KV is included in the scan result or gets filtered out.
34   */
35  @InterfaceAudience.Private
36  class VisibilityLabelFilter extends FilterBase {
37  
38    private final VisibilityExpEvaluator expEvaluator;
39    private final Map<ByteRange, Integer> cfVsMaxVersions;
40    private final ByteRange curFamily;
41    private final ByteRange curQualifier;
42    private int curFamilyMaxVersions;
43    private int curQualMetVersions;
44  
45    public VisibilityLabelFilter(VisibilityExpEvaluator expEvaluator,
46        Map<ByteRange, Integer> cfVsMaxVersions) {
47      this.expEvaluator = expEvaluator;
48      this.cfVsMaxVersions = cfVsMaxVersions;
49      this.curFamily = new SimpleMutableByteRange();
50      this.curQualifier = new SimpleMutableByteRange();
51    }
52  
53    @Override
54    public ReturnCode filterKeyValue(Cell cell) throws IOException {
55      if (curFamily.getBytes() == null
56          || (Bytes.compareTo(curFamily.getBytes(), curFamily.getOffset(), curFamily.getLength(),
57              cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength()) != 0)) {
58        curFamily.set(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength());
59        // For this family, all the columns can have max of curFamilyMaxVersions versions. No need to
60        // consider the older versions for visibility label check.
61        // Ideally this should have been done at a lower layer by HBase (?)
62        curFamilyMaxVersions = cfVsMaxVersions.get(curFamily);
63        // Family is changed. Just unset curQualifier.
64        curQualifier.unset();
65      }
66      if (curQualifier.getBytes() == null
67          || (Bytes.compareTo(curQualifier.getBytes(), curQualifier.getOffset(),
68              curQualifier.getLength(), cell.getQualifierArray(), cell.getQualifierOffset(),
69              cell.getQualifierLength()) != 0)) {
70        curQualifier.set(cell.getQualifierArray(), cell.getQualifierOffset(),
71            cell.getQualifierLength());
72        curQualMetVersions = 0;
73      }
74      curQualMetVersions++;
75      if (curQualMetVersions > curFamilyMaxVersions) {
76        return ReturnCode.SKIP;
77      }
78  
79      return this.expEvaluator.evaluate(cell) ? ReturnCode.INCLUDE : ReturnCode.SKIP;
80    }
81  
82    // Override here explicitly as the method in super class FilterBase might do a KeyValue recreate.
83    // See HBASE-12068
84    @Override
85    public Cell transformCell(Cell v) {
86      return v;
87    }
88  
89    @Override
90    public void reset() throws IOException {
91      this.curFamily.unset();
92      this.curQualifier.unset();
93      this.curFamilyMaxVersions = 0;
94      this.curQualMetVersions = 0;
95    }
96  
97    @Override
98    public boolean equals(Object obj) {
99      if (!(obj instanceof VisibilityLabelFilter)) {
100       return false;
101     }
102     if(this == obj){
103       return true;
104     }
105     VisibilityLabelFilter f = (VisibilityLabelFilter)obj;
106     return this.expEvaluator.equals(f.expEvaluator) &&
107       this.cfVsMaxVersions.equals(f.cfVsMaxVersions);
108   }
109 
110   @Override
111   public int hashCode() {
112     return Objects.hash(this.expEvaluator, this.cfVsMaxVersions);
113   }
114 }