View Javadoc

1   /*
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  package org.apache.hadoop.hbase.coprocessor;
20  
21  import static junit.framework.Assert.assertEquals;
22  
23  import java.io.IOException;
24  import java.util.ArrayList;
25  import java.util.List;
26  import java.util.Map;
27  
28  import org.apache.hadoop.conf.Configuration;
29  import org.apache.hadoop.hbase.Cell;
30  import org.apache.hadoop.hbase.HBaseConfiguration;
31  import org.apache.hadoop.hbase.HBaseTestingUtility;
32  import org.apache.hadoop.hbase.testclassification.MediumTests;
33  import org.apache.hadoop.hbase.TableName;
34  import org.apache.hadoop.hbase.client.Admin;
35  import org.apache.hadoop.hbase.client.Delete;
36  import org.apache.hadoop.hbase.client.Get;
37  import org.apache.hadoop.hbase.client.HTable;
38  import org.apache.hadoop.hbase.client.Put;
39  import org.apache.hadoop.hbase.client.Result;
40  import org.apache.hadoop.hbase.client.Durability;
41  import org.apache.hadoop.hbase.client.Table;
42  import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
43  import org.apache.hadoop.hbase.util.Bytes;
44  import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
45  import org.apache.hadoop.hbase.util.EnvironmentEdgeManagerTestHelper;
46  import org.apache.hadoop.hbase.util.IncrementingEnvironmentEdge;
47  import org.junit.AfterClass;
48  import org.junit.Before;
49  import org.junit.BeforeClass;
50  import org.junit.Test;
51  import org.junit.experimental.categories.Category;
52  
53  @Category(MediumTests.class)
54  public class TestRegionObserverBypass {
55    private static HBaseTestingUtility util;
56    private static final TableName tableName = TableName.valueOf("test");
57    private static final byte[] dummy = Bytes.toBytes("dummy");
58    private static final byte[] row1 = Bytes.toBytes("r1");
59    private static final byte[] row2 = Bytes.toBytes("r2");
60    private static final byte[] row3 = Bytes.toBytes("r3");
61    private static final byte[] test = Bytes.toBytes("test");
62  
63    @BeforeClass
64    public static void setUpBeforeClass() throws Exception {
65      Configuration conf = HBaseConfiguration.create();
66      conf.setStrings(CoprocessorHost.USER_REGION_COPROCESSOR_CONF_KEY,
67          TestCoprocessor.class.getName());
68      util = new HBaseTestingUtility(conf);
69      util.startMiniCluster();
70    }
71  
72    @AfterClass
73    public static void tearDownAfterClass() throws Exception {
74      util.shutdownMiniCluster();
75    }
76  
77    @Before
78    public void setUp() throws Exception {
79      Admin admin = util.getHBaseAdmin();
80      if (admin.tableExists(tableName)) {
81        if (admin.isTableEnabled(tableName)) {
82          admin.disableTable(tableName);
83        }
84        admin.deleteTable(tableName);
85      }
86      util.createTable(tableName, new byte[][] {dummy, test});
87    }
88  
89    /**
90     * do a single put that is bypassed by a RegionObserver
91     * @throws Exception
92     */
93    @Test
94    public void testSimple() throws Exception {
95      Table t = new HTable(util.getConfiguration(), tableName);
96      Put p = new Put(row1);
97      p.add(test,dummy,dummy);
98      // before HBASE-4331, this would throw an exception
99      t.put(p);
100     checkRowAndDelete(t,row1,0);
101     t.close();
102   }
103 
104   /**
105    * Test various multiput operations.
106    * @throws Exception
107    */
108   @Test
109   public void testMulti() throws Exception {
110     //ensure that server time increments every time we do an operation, otherwise
111     //previous deletes will eclipse successive puts having the same timestamp
112     EnvironmentEdgeManagerTestHelper.injectEdge(new IncrementingEnvironmentEdge());
113 
114     Table t = new HTable(util.getConfiguration(), tableName);
115     List<Put> puts = new ArrayList<Put>();
116     Put p = new Put(row1);
117     p.add(dummy,dummy,dummy);
118     puts.add(p);
119     p = new Put(row2);
120     p.add(test,dummy,dummy);
121     puts.add(p);
122     p = new Put(row3);
123     p.add(test,dummy,dummy);
124     puts.add(p);
125     // before HBASE-4331, this would throw an exception
126     t.put(puts);
127     checkRowAndDelete(t,row1,1);
128     checkRowAndDelete(t,row2,0);
129     checkRowAndDelete(t,row3,0);
130 
131     puts.clear();
132     p = new Put(row1);
133     p.add(test,dummy,dummy);
134     puts.add(p);
135     p = new Put(row2);
136     p.add(test,dummy,dummy);
137     puts.add(p);
138     p = new Put(row3);
139     p.add(test,dummy,dummy);
140     puts.add(p);
141     // before HBASE-4331, this would throw an exception
142     t.put(puts);
143     checkRowAndDelete(t,row1,0);
144     checkRowAndDelete(t,row2,0);
145     checkRowAndDelete(t,row3,0);
146 
147     puts.clear();
148     p = new Put(row1);
149     p.add(test,dummy,dummy);
150     puts.add(p);
151     p = new Put(row2);
152     p.add(test,dummy,dummy);
153     puts.add(p);
154     p = new Put(row3);
155     p.add(dummy,dummy,dummy);
156     puts.add(p);
157     // this worked fine even before HBASE-4331
158     t.put(puts);
159     checkRowAndDelete(t,row1,0);
160     checkRowAndDelete(t,row2,0);
161     checkRowAndDelete(t,row3,1);
162 
163     puts.clear();
164     p = new Put(row1);
165     p.add(dummy,dummy,dummy);
166     puts.add(p);
167     p = new Put(row2);
168     p.add(test,dummy,dummy);
169     puts.add(p);
170     p = new Put(row3);
171     p.add(dummy,dummy,dummy);
172     puts.add(p);
173     // this worked fine even before HBASE-4331
174     t.put(puts);
175     checkRowAndDelete(t,row1,1);
176     checkRowAndDelete(t,row2,0);
177     checkRowAndDelete(t,row3,1);
178 
179     puts.clear();
180     p = new Put(row1);
181     p.add(test,dummy,dummy);
182     puts.add(p);
183     p = new Put(row2);
184     p.add(dummy,dummy,dummy);
185     puts.add(p);
186     p = new Put(row3);
187     p.add(test,dummy,dummy);
188     puts.add(p);
189     // before HBASE-4331, this would throw an exception
190     t.put(puts);
191     checkRowAndDelete(t,row1,0);
192     checkRowAndDelete(t,row2,1);
193     checkRowAndDelete(t,row3,0);
194     t.close();
195 
196     EnvironmentEdgeManager.reset();
197   }
198 
199   private void checkRowAndDelete(Table t, byte[] row, int count) throws IOException {
200     Get g = new Get(row);
201     Result r = t.get(g);
202     assertEquals(count, r.size());
203     Delete d = new Delete(row);
204     t.delete(d);
205   }
206 
207   public static class TestCoprocessor extends BaseRegionObserver {
208     @Override
209     public void prePut(final ObserverContext<RegionCoprocessorEnvironment> e,
210         final Put put, final WALEdit edit, final Durability durability)
211         throws IOException {
212       Map<byte[], List<Cell>> familyMap = put.getFamilyCellMap();
213       if (familyMap.containsKey(test)) {
214         e.bypass();
215       }
216     }
217   }
218 }