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.filter;
19  
20  import static org.junit.Assert.assertArrayEquals;
21  import static org.junit.Assert.assertEquals;
22  import static org.junit.Assert.assertFalse;
23  
24  import org.apache.hadoop.hbase.Cell;
25  import org.apache.hadoop.hbase.HBaseTestingUtility;
26  import org.apache.hadoop.hbase.HColumnDescriptor;
27  import org.apache.hadoop.hbase.HRegionInfo;
28  import org.apache.hadoop.hbase.HTableDescriptor;
29  import org.apache.hadoop.hbase.HTestConst;
30  import org.apache.hadoop.hbase.KeyValue;
31  import org.apache.hadoop.hbase.TableName;
32  import org.apache.hadoop.hbase.client.Put;
33  import org.apache.hadoop.hbase.client.Scan;
34  import org.apache.hadoop.hbase.regionserver.HRegion;
35  import org.apache.hadoop.hbase.regionserver.InternalScanner;
36  import org.apache.hadoop.hbase.testclassification.SmallTests;
37  import org.apache.hadoop.hbase.util.Bytes;
38  import org.junit.AfterClass;
39  import org.junit.BeforeClass;
40  import org.junit.Test;
41  import org.junit.experimental.categories.Category;
42  
43  import java.io.IOException;
44  import java.util.ArrayList;
45  import java.util.List;
46  
47  /**
48   * To test behavior of filters at server from region side.
49   */
50  @Category(SmallTests.class)
51  public class TestFilterFromRegionSide {
52  
53    private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
54    private static HRegion REGION;
55  
56    private static TableName TABLE_NAME = TableName.valueOf("TestFilterFromRegionSide");
57  
58    private static int NUM_ROWS = 5;
59    private static byte[] ROW = Bytes.toBytes("testRow");
60    private static byte[][] ROWS = HTestConst.makeNAscii(ROW, NUM_ROWS);
61  
62    // Should keep this value below 10 to keep generation of expected kv's simple. If above 10 then
63    // table/row/cf1/... will be followed by table/row/cf10/... instead of table/row/cf2/... which
64    // breaks the simple generation of expected kv's
65    private static int NUM_FAMILIES = 5;
66    private static byte[] FAMILY = Bytes.toBytes("testFamily");
67    private static byte[][] FAMILIES = HTestConst.makeNAscii(FAMILY, NUM_FAMILIES);
68  
69    private static int NUM_QUALIFIERS = 5;
70    private static byte[] QUALIFIER = Bytes.toBytes("testQualifier");
71    private static byte[][] QUALIFIERS = HTestConst.makeNAscii(QUALIFIER, NUM_QUALIFIERS);
72  
73    private static int VALUE_SIZE = 1024;
74    private static byte[] VALUE = Bytes.createMaxByteArray(VALUE_SIZE);
75  
76    private static int NUM_COLS = NUM_FAMILIES * NUM_QUALIFIERS;
77  
78    @BeforeClass
79    public static void setUpBeforeClass() throws Exception {
80      HTableDescriptor htd = new HTableDescriptor(TABLE_NAME);
81      for (byte[] family : FAMILIES) {
82        HColumnDescriptor hcd = new HColumnDescriptor(family);
83        htd.addFamily(hcd);
84      }
85      HRegionInfo info = new HRegionInfo(htd.getTableName(), null, null, false);
86      REGION = HBaseTestingUtility
87          .createRegionAndWAL(info, TEST_UTIL.getDataTestDir(), TEST_UTIL.getDataTestDir(), TEST_UTIL.getConfiguration(), htd);
88      for(Put put:createPuts(ROWS, FAMILIES, QUALIFIERS, VALUE)){
89        REGION.put(put);
90      }
91    }
92  
93    private static ArrayList<Put> createPuts(byte[][] rows, byte[][] families, byte[][] qualifiers,
94        byte[] value) throws IOException {
95      Put put;
96      ArrayList<Put> puts = new ArrayList<>();
97  
98      for (byte[] row1 : rows) {
99        put = new Put(row1);
100       for (byte[] family : families) {
101         for (int qual = 0; qual < qualifiers.length; qual++) {
102           KeyValue kv = new KeyValue(row1, family, qualifiers[qual], qual, value);
103           put.add(kv);
104         }
105       }
106       puts.add(put);
107     }
108 
109     return puts;
110   }
111 
112   @AfterClass
113   public static void tearDownAfterClass() throws Exception {
114     REGION.close();
115   }
116 
117   @Test
118   public void testFirstKeyOnlyFilterAndBatch() throws IOException {
119     Scan scan = new Scan();
120     scan.setFilter(new FirstKeyOnlyFilter());
121     scan.setBatch(1);
122     InternalScanner scanner = REGION.getScanner(scan);
123     List<Cell> results = new ArrayList<>();
124     for (int i = 0; i < NUM_ROWS; i++) {
125       results.clear();
126       scanner.next(results);
127       assertEquals(1, results.size());
128       Cell cell = results.get(0);
129       assertArrayEquals(ROWS[i],
130           Bytes.copy(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength()));
131     }
132     assertFalse(scanner.next(results));
133     scanner.close();
134   }
135 
136   public static class FirstSeveralCellsFilter extends FilterBase{
137     private int count = 0;
138 
139     public void reset() {
140       count = 0;
141     }
142 
143     @Override
144     public ReturnCode filterKeyValue(Cell v) {
145       if (count++ < NUM_COLS) {
146         return ReturnCode.INCLUDE;
147       }
148       return ReturnCode.SKIP;
149     }
150 
151     public static Filter parseFrom(final byte [] pbBytes){
152       return new FirstSeveralCellsFilter();
153     }
154   }
155 
156   @Test
157   public void testFirstSeveralCellsFilterAndBatch() throws IOException {
158     Scan scan = new Scan();
159     scan.setFilter(new FirstSeveralCellsFilter());
160     scan.setBatch(NUM_COLS);
161     InternalScanner scanner = REGION.getScanner(scan);
162     List<Cell> results = new ArrayList<>();
163     for (int i = 0; i < NUM_ROWS; i++) {
164       results.clear();
165       scanner.next(results);
166       assertEquals(NUM_COLS, results.size());
167       Cell cell = results.get(0);
168       assertArrayEquals(ROWS[i],
169           Bytes.copy(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength()));
170       assertArrayEquals(FAMILIES[0],
171           Bytes.copy(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength()));
172       assertArrayEquals(QUALIFIERS[0], Bytes.copy(cell.getQualifierArray(),
173           cell.getQualifierOffset(), cell.getQualifierLength()));
174     }
175     assertFalse(scanner.next(results));
176     scanner.close();
177   }
178 }