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.security.visibility; 019 020import java.io.IOException; 021import java.util.Map; 022import java.util.Objects; 023 024import org.apache.yetus.audience.InterfaceAudience; 025import org.apache.hadoop.hbase.Cell; 026import org.apache.hadoop.hbase.PrivateCellUtil; 027import org.apache.hadoop.hbase.filter.FilterBase; 028import org.apache.hadoop.hbase.util.ByteRange; 029import org.apache.hadoop.hbase.util.SimpleMutableByteRange; 030 031/** 032 * This Filter checks the visibility expression with each KV against visibility labels associated 033 * with the scan. Based on the check the KV is included in the scan result or gets filtered out. 034 */ 035@InterfaceAudience.Private 036class VisibilityLabelFilter extends FilterBase { 037 038 private final VisibilityExpEvaluator expEvaluator; 039 private final Map<ByteRange, Integer> cfVsMaxVersions; 040 private final ByteRange curFamily; 041 private final ByteRange curQualifier; 042 private int curFamilyMaxVersions; 043 private int curQualMetVersions; 044 045 public VisibilityLabelFilter(VisibilityExpEvaluator expEvaluator, 046 Map<ByteRange, Integer> cfVsMaxVersions) { 047 this.expEvaluator = expEvaluator; 048 this.cfVsMaxVersions = cfVsMaxVersions; 049 this.curFamily = new SimpleMutableByteRange(); 050 this.curQualifier = new SimpleMutableByteRange(); 051 } 052 053 @Override 054 public boolean filterRowKey(Cell cell) throws IOException { 055 // Impl in FilterBase might do unnecessary copy for Off heap backed Cells. 056 return false; 057 } 058 059 @Override 060 public ReturnCode filterCell(final Cell cell) throws IOException { 061 if (curFamily.getBytes() == null 062 || !(PrivateCellUtil.matchingFamily(cell, curFamily.getBytes(), curFamily.getOffset(), 063 curFamily.getLength()))) { 064 curFamily.set(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength()); 065 // For this family, all the columns can have max of curFamilyMaxVersions versions. No need to 066 // consider the older versions for visibility label check. 067 // Ideally this should have been done at a lower layer by HBase (?) 068 curFamilyMaxVersions = cfVsMaxVersions.get(curFamily); 069 // Family is changed. Just unset curQualifier. 070 curQualifier.unset(); 071 } 072 if (curQualifier.getBytes() == null || !(PrivateCellUtil.matchingQualifier(cell, 073 curQualifier.getBytes(), curQualifier.getOffset(), curQualifier.getLength()))) { 074 curQualifier.set(cell.getQualifierArray(), cell.getQualifierOffset(), 075 cell.getQualifierLength()); 076 curQualMetVersions = 0; 077 } 078 curQualMetVersions++; 079 if (curQualMetVersions > curFamilyMaxVersions) { 080 return ReturnCode.SKIP; 081 } 082 083 return this.expEvaluator.evaluate(cell) ? ReturnCode.INCLUDE : ReturnCode.SKIP; 084 } 085 086 @Override 087 public void reset() throws IOException { 088 this.curFamily.unset(); 089 this.curQualifier.unset(); 090 this.curFamilyMaxVersions = 0; 091 this.curQualMetVersions = 0; 092 } 093 094 @Override 095 public boolean equals(Object obj) { 096 if (!(obj instanceof VisibilityLabelFilter)) { 097 return false; 098 } 099 if(this == obj){ 100 return true; 101 } 102 VisibilityLabelFilter f = (VisibilityLabelFilter)obj; 103 return this.expEvaluator.equals(f.expEvaluator) && 104 this.cfVsMaxVersions.equals(f.cfVsMaxVersions); 105 } 106 107 @Override 108 public int hashCode() { 109 return Objects.hash(this.expEvaluator, this.cfVsMaxVersions); 110 } 111}