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