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.KeyValue;
33  import org.apache.hadoop.hbase.MediumTests;
34  import org.apache.hadoop.hbase.client.Delete;
35  import org.apache.hadoop.hbase.client.Get;
36  import org.apache.hadoop.hbase.client.HBaseAdmin;
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.regionserver.wal.WALEdit;
42  import org.apache.hadoop.hbase.util.Bytes;
43  import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
44  import org.apache.hadoop.hbase.util.EnvironmentEdgeManagerTestHelper;
45  import org.apache.hadoop.hbase.util.IncrementingEnvironmentEdge;
46  import org.junit.AfterClass;
47  import org.junit.Before;
48  import org.junit.BeforeClass;
49  import org.junit.Test;
50  import org.junit.experimental.categories.Category;
51  
52  @Category(MediumTests.class)
53  public class TestRegionObserverBypass {
54    private static HBaseTestingUtility util;
55    private static final byte[] tableName = Bytes.toBytes("test");
56    private static final byte[] dummy = Bytes.toBytes("dummy");
57    private static final byte[] row1 = Bytes.toBytes("r1");
58    private static final byte[] row2 = Bytes.toBytes("r2");
59    private static final byte[] row3 = Bytes.toBytes("r3");
60    private static final byte[] test = Bytes.toBytes("test");
61  
62    @BeforeClass
63    public static void setUpBeforeClass() throws Exception {
64      Configuration conf = HBaseConfiguration.create();
65      conf.setStrings(CoprocessorHost.USER_REGION_COPROCESSOR_CONF_KEY,
66          TestCoprocessor.class.getName());
67      util = new HBaseTestingUtility(conf);
68      util.startMiniCluster();
69    }
70  
71    @AfterClass
72    public static void tearDownAfterClass() throws Exception {
73      util.shutdownMiniCluster();
74    }
75  
76    @Before
77    public void setUp() throws Exception {
78      HBaseAdmin admin = util.getHBaseAdmin();
79      if (admin.tableExists(tableName)) {
80        if (admin.isTableEnabled(tableName)) {
81          admin.disableTable(tableName);
82        }
83        admin.deleteTable(tableName);
84      }
85      util.createTable(tableName, new byte[][] {dummy, test});
86    }
87  
88    /**
89     * do a single put that is bypassed by a RegionObserver
90     * @throws Exception
91     */
92    @Test
93    public void testSimple() throws Exception {
94      HTable t = new HTable(util.getConfiguration(), tableName);
95      Put p = new Put(row1);
96      p.add(test,dummy,dummy);
97      // before HBASE-4331, this would throw an exception
98      t.put(p);
99      checkRowAndDelete(t,row1,0);
100     t.close();
101   }
102 
103   /**
104    * Test various multiput operations.
105    * @throws Exception
106    */
107   @Test
108   public void testMulti() throws Exception {
109     //ensure that server time increments every time we do an operation, otherwise
110     //previous deletes will eclipse successive puts having the same timestamp
111     EnvironmentEdgeManagerTestHelper.injectEdge(new IncrementingEnvironmentEdge());
112 
113     HTable t = new HTable(util.getConfiguration(), tableName);
114     List<Put> puts = new ArrayList<Put>();
115     Put p = new Put(row1);
116     p.add(dummy,dummy,dummy);
117     puts.add(p);
118     p = new Put(row2);
119     p.add(test,dummy,dummy);
120     puts.add(p);
121     p = new Put(row3);
122     p.add(test,dummy,dummy);
123     puts.add(p);
124     // before HBASE-4331, this would throw an exception
125     t.put(puts);
126     checkRowAndDelete(t,row1,1);
127     checkRowAndDelete(t,row2,0);
128     checkRowAndDelete(t,row3,0);
129 
130     puts.clear();
131     p = new Put(row1);
132     p.add(test,dummy,dummy);
133     puts.add(p);
134     p = new Put(row2);
135     p.add(test,dummy,dummy);
136     puts.add(p);
137     p = new Put(row3);
138     p.add(test,dummy,dummy);
139     puts.add(p);
140     // before HBASE-4331, this would throw an exception
141     t.put(puts);
142     checkRowAndDelete(t,row1,0);
143     checkRowAndDelete(t,row2,0);
144     checkRowAndDelete(t,row3,0);
145 
146     puts.clear();
147     p = new Put(row1);
148     p.add(test,dummy,dummy);
149     puts.add(p);
150     p = new Put(row2);
151     p.add(test,dummy,dummy);
152     puts.add(p);
153     p = new Put(row3);
154     p.add(dummy,dummy,dummy);
155     puts.add(p);
156     // this worked fine even before HBASE-4331
157     t.put(puts);
158     checkRowAndDelete(t,row1,0);
159     checkRowAndDelete(t,row2,0);
160     checkRowAndDelete(t,row3,1);
161 
162     puts.clear();
163     p = new Put(row1);
164     p.add(dummy,dummy,dummy);
165     puts.add(p);
166     p = new Put(row2);
167     p.add(test,dummy,dummy);
168     puts.add(p);
169     p = new Put(row3);
170     p.add(dummy,dummy,dummy);
171     puts.add(p);
172     // this worked fine even before HBASE-4331
173     t.put(puts);
174     checkRowAndDelete(t,row1,1);
175     checkRowAndDelete(t,row2,0);
176     checkRowAndDelete(t,row3,1);
177 
178     puts.clear();
179     p = new Put(row1);
180     p.add(test,dummy,dummy);
181     puts.add(p);
182     p = new Put(row2);
183     p.add(dummy,dummy,dummy);
184     puts.add(p);
185     p = new Put(row3);
186     p.add(test,dummy,dummy);
187     puts.add(p);
188     // before HBASE-4331, this would throw an exception
189     t.put(puts);
190     checkRowAndDelete(t,row1,0);
191     checkRowAndDelete(t,row2,1);
192     checkRowAndDelete(t,row3,0);
193     t.close();
194 
195     EnvironmentEdgeManager.reset();
196   }
197 
198   private void checkRowAndDelete(HTable t, byte[] row, int count) throws IOException {
199     Get g = new Get(row);
200     Result r = t.get(g);
201     assertEquals(count, r.size());
202     Delete d = new Delete(row);
203     t.delete(d);
204   }
205 
206   public static class TestCoprocessor extends BaseRegionObserver {
207     @Override
208     public void prePut(final ObserverContext<RegionCoprocessorEnvironment> e,
209         final Put put, final WALEdit edit, final Durability durability)
210         throws IOException {
211       Map<byte[], List<Cell>> familyMap = put.getFamilyCellMap();
212       if (familyMap.containsKey(test)) {
213         e.bypass();
214       }
215     }
216   }
217 }