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  
20  package org.apache.hadoop.hbase.coprocessor;
21  
22  import static org.junit.Assert.assertArrayEquals;
23  import static org.junit.Assert.assertEquals;
24  import static org.junit.Assert.assertNotNull;
25  import static org.junit.Assert.assertTrue;
26  
27  import java.io.IOException;
28  import java.util.List;
29  import java.util.Map;
30  import java.util.NavigableSet;
31  import java.util.concurrent.atomic.AtomicBoolean;
32  import java.util.concurrent.atomic.AtomicInteger;
33  
34  import org.apache.commons.logging.Log;
35  import org.apache.commons.logging.LogFactory;
36  import org.apache.hadoop.fs.FileSystem;
37  import org.apache.hadoop.fs.Path;
38  import org.apache.hadoop.hbase.Cell;
39  import org.apache.hadoop.hbase.CellUtil;
40  import org.apache.hadoop.hbase.CoprocessorEnvironment;
41  import org.apache.hadoop.hbase.HRegionInfo;
42  import org.apache.hadoop.hbase.KeyValue;
43  import org.apache.hadoop.hbase.client.Append;
44  import org.apache.hadoop.hbase.client.Delete;
45  import org.apache.hadoop.hbase.client.Durability;
46  import org.apache.hadoop.hbase.client.Get;
47  import org.apache.hadoop.hbase.client.Increment;
48  import org.apache.hadoop.hbase.client.Mutation;
49  import org.apache.hadoop.hbase.client.Put;
50  import org.apache.hadoop.hbase.client.Result;
51  import org.apache.hadoop.hbase.client.Scan;
52  import org.apache.hadoop.hbase.filter.ByteArrayComparable;
53  import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
54  import org.apache.hadoop.hbase.io.FSDataInputStreamWrapper;
55  import org.apache.hadoop.hbase.io.Reference;
56  import org.apache.hadoop.hbase.io.hfile.CacheConfig;
57  import org.apache.hadoop.hbase.regionserver.InternalScanner;
58  import org.apache.hadoop.hbase.regionserver.KeyValueScanner;
59  import org.apache.hadoop.hbase.regionserver.Leases;
60  import org.apache.hadoop.hbase.regionserver.MiniBatchOperationInProgress;
61  import org.apache.hadoop.hbase.regionserver.Region;
62  import org.apache.hadoop.hbase.regionserver.Region.Operation;
63  import org.apache.hadoop.hbase.regionserver.RegionScanner;
64  import org.apache.hadoop.hbase.regionserver.ScanType;
65  import org.apache.hadoop.hbase.regionserver.Store;
66  import org.apache.hadoop.hbase.regionserver.StoreFile;
67  import org.apache.hadoop.hbase.regionserver.StoreFile.Reader;
68  import org.apache.hadoop.hbase.regionserver.wal.HLogKey;
69  import org.apache.hadoop.hbase.wal.WALKey;
70  import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
71  import org.apache.hadoop.hbase.util.Bytes;
72  import org.apache.hadoop.hbase.util.Pair;
73  
74  import com.google.common.collect.ImmutableList;
75  
76  /**
77   * A sample region observer that tests the RegionObserver interface.
78   * It works with TestRegionObserverInterface to provide the test case.
79   */
80  public class SimpleRegionObserver extends BaseRegionObserver {
81    static final Log LOG = LogFactory.getLog(TestRegionObserverInterface.class);
82  
83    final AtomicInteger ctBeforeDelete = new AtomicInteger(1);
84    final AtomicInteger ctPreOpen = new AtomicInteger(0);
85    final AtomicInteger ctPostOpen = new AtomicInteger(0);
86    final AtomicInteger ctPreClose = new AtomicInteger(0);
87    final AtomicInteger ctPostClose = new AtomicInteger(0);
88    final AtomicInteger ctPreFlush = new AtomicInteger(0);
89    final AtomicInteger ctPreFlushScannerOpen = new AtomicInteger(0);
90    final AtomicInteger ctPostFlush = new AtomicInteger(0);
91    final AtomicInteger ctPreSplit = new AtomicInteger(0);
92    final AtomicInteger ctPostSplit = new AtomicInteger(0);
93    final AtomicInteger ctPreCompactSelect = new AtomicInteger(0);
94    final AtomicInteger ctPostCompactSelect = new AtomicInteger(0);
95    final AtomicInteger ctPreCompactScanner = new AtomicInteger(0);
96    final AtomicInteger ctPreCompact = new AtomicInteger(0);
97    final AtomicInteger ctPostCompact = new AtomicInteger(0);
98    final AtomicInteger ctPreGet = new AtomicInteger(0);
99    final AtomicInteger ctPostGet = new AtomicInteger(0);
100   final AtomicInteger ctPrePut = new AtomicInteger(0);
101   final AtomicInteger ctPostPut = new AtomicInteger(0);
102   final AtomicInteger ctPreDeleted = new AtomicInteger(0);
103   final AtomicInteger ctPrePrepareDeleteTS = new AtomicInteger(0);
104   final AtomicInteger ctPostDeleted = new AtomicInteger(0);
105   final AtomicInteger ctPreGetClosestRowBefore = new AtomicInteger(0);
106   final AtomicInteger ctPostGetClosestRowBefore = new AtomicInteger(0);
107   final AtomicInteger ctPreIncrement = new AtomicInteger(0);
108   final AtomicInteger ctPreIncrementAfterRowLock = new AtomicInteger(0);
109   final AtomicInteger ctPreAppend = new AtomicInteger(0);
110   final AtomicInteger ctPreAppendAfterRowLock = new AtomicInteger(0);
111   final AtomicInteger ctPostIncrement = new AtomicInteger(0);
112   final AtomicInteger ctPostAppend = new AtomicInteger(0);
113   final AtomicInteger ctPreCheckAndPut = new AtomicInteger(0);
114   final AtomicInteger ctPreCheckAndPutAfterRowLock = new AtomicInteger(0);
115   final AtomicInteger ctPostCheckAndPut = new AtomicInteger(0);
116   final AtomicInteger ctPreCheckAndDelete = new AtomicInteger(0);
117   final AtomicInteger ctPreCheckAndDeleteAfterRowLock = new AtomicInteger(0);
118   final AtomicInteger ctPostCheckAndDelete = new AtomicInteger(0);
119   final AtomicInteger ctPreScannerNext = new AtomicInteger(0);
120   final AtomicInteger ctPostScannerNext = new AtomicInteger(0);
121   final AtomicInteger ctPreScannerClose = new AtomicInteger(0);
122   final AtomicInteger ctPostScannerClose = new AtomicInteger(0);
123   final AtomicInteger ctPreScannerOpen = new AtomicInteger(0);
124   final AtomicInteger ctPreStoreScannerOpen = new AtomicInteger(0);
125   final AtomicInteger ctPostScannerOpen = new AtomicInteger(0);
126   final AtomicInteger ctPreBulkLoadHFile = new AtomicInteger(0);
127   final AtomicInteger ctPostBulkLoadHFile = new AtomicInteger(0);
128   final AtomicInteger ctPreBatchMutate = new AtomicInteger(0);
129   final AtomicInteger ctPostBatchMutate = new AtomicInteger(0);
130   final AtomicInteger ctPreWALRestore = new AtomicInteger(0);
131   final AtomicInteger ctPostWALRestore = new AtomicInteger(0);
132   final AtomicInteger ctPreWALRestoreDeprecated = new AtomicInteger(0);
133   final AtomicInteger ctPostWALRestoreDeprecated = new AtomicInteger(0);
134   final AtomicInteger ctPreSplitBeforePONR = new AtomicInteger(0);
135   final AtomicInteger ctPreSplitAfterPONR = new AtomicInteger(0);
136   final AtomicInteger ctPreStoreFileReaderOpen = new AtomicInteger(0);
137   final AtomicInteger ctPostStoreFileReaderOpen = new AtomicInteger(0);
138   final AtomicInteger ctPostBatchMutateIndispensably = new AtomicInteger(0);
139   final AtomicInteger ctPostStartRegionOperation = new AtomicInteger(0);
140   final AtomicInteger ctPostCloseRegionOperation = new AtomicInteger(0);
141   final AtomicBoolean throwOnPostFlush = new AtomicBoolean(false);
142   static final String TABLE_SKIPPED = "SKIPPED_BY_PREWALRESTORE";
143 
144   public void setThrowOnPostFlush(Boolean val){
145     throwOnPostFlush.set(val);
146   }
147 
148   @Override
149   public void start(CoprocessorEnvironment e) throws IOException {
150     // this only makes sure that leases and locks are available to coprocessors
151     // from external packages
152     RegionCoprocessorEnvironment re = (RegionCoprocessorEnvironment)e;
153     Leases leases = re.getRegionServerServices().getLeases();
154     leases.createLease(re.getRegion().getRegionInfo().getRegionNameAsString(), 2000, null);
155     leases.cancelLease(re.getRegion().getRegionInfo().getRegionNameAsString());
156   }
157 
158   @Override
159   public void preOpen(ObserverContext<RegionCoprocessorEnvironment> c) {
160     ctPreOpen.incrementAndGet();
161   }
162 
163   @Override
164   public void postOpen(ObserverContext<RegionCoprocessorEnvironment> c) {
165     ctPostOpen.incrementAndGet();
166   }
167 
168   public boolean wasOpened() {
169     return ctPreOpen.get() > 0 && ctPostOpen.get() > 0;
170   }
171 
172   @Override
173   public void preClose(ObserverContext<RegionCoprocessorEnvironment> c, boolean abortRequested) {
174     ctPreClose.incrementAndGet();
175   }
176 
177   @Override
178   public void postClose(ObserverContext<RegionCoprocessorEnvironment> c, boolean abortRequested) {
179     ctPostClose.incrementAndGet();
180   }
181 
182   public boolean wasClosed() {
183     return ctPreClose.get() > 0 && ctPostClose.get() > 0;
184   }
185 
186   @Override
187   public InternalScanner preFlush(ObserverContext<RegionCoprocessorEnvironment> c,
188       Store store, InternalScanner scanner) throws IOException {
189     ctPreFlush.incrementAndGet();
190     return scanner;
191   }
192 
193   @Override
194   public InternalScanner preFlushScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c,
195       Store store, KeyValueScanner memstoreScanner, InternalScanner s) throws IOException {
196     ctPreFlushScannerOpen.incrementAndGet();
197     return null;
198   }
199 
200   @Override
201   public void postFlush(ObserverContext<RegionCoprocessorEnvironment> c,
202       Store store, StoreFile resultFile) throws IOException {
203     ctPostFlush.incrementAndGet();
204     if (throwOnPostFlush.get()){
205       throw new IOException("throwOnPostFlush is true in postFlush");
206     }
207   }
208 
209   public boolean wasFlushed() {
210     return ctPreFlush.get() > 0 && ctPostFlush.get() > 0;
211   }
212 
213   @Override
214   public void preSplit(ObserverContext<RegionCoprocessorEnvironment> c) {
215     ctPreSplit.incrementAndGet();
216   }
217 
218   @Override
219   public void preSplitBeforePONR(
220       ObserverContext<RegionCoprocessorEnvironment> ctx, byte[] splitKey,
221       List<Mutation> metaEntries) throws IOException {
222     ctPreSplitBeforePONR.incrementAndGet();
223   }
224   
225   @Override
226   public void preSplitAfterPONR(
227       ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException {
228     ctPreSplitAfterPONR.incrementAndGet();
229   }
230   
231   @Override
232   public void postSplit(ObserverContext<RegionCoprocessorEnvironment> c, Region l, Region r) {
233     ctPostSplit.incrementAndGet();
234   }
235 
236   public boolean wasSplit() {
237     return ctPreSplit.get() > 0 && ctPostSplit.get() > 0;
238   }
239 
240   @Override
241   public void preCompactSelection(ObserverContext<RegionCoprocessorEnvironment> c,
242       Store store, List<StoreFile> candidates) {
243     ctPreCompactSelect.incrementAndGet();
244   }
245 
246   @Override
247   public void postCompactSelection(ObserverContext<RegionCoprocessorEnvironment> c,
248       Store store, ImmutableList<StoreFile> selected) {
249     ctPostCompactSelect.incrementAndGet();
250   }
251 
252   @Override
253   public InternalScanner preCompact(ObserverContext<RegionCoprocessorEnvironment> e,
254       Store store, InternalScanner scanner, ScanType scanType) {
255     ctPreCompact.incrementAndGet();
256     return scanner;
257   }
258 
259   @Override
260   public InternalScanner preCompactScannerOpen(
261       final ObserverContext<RegionCoprocessorEnvironment> c,
262       Store store, List<? extends KeyValueScanner> scanners, ScanType scanType, long earliestPutTs,
263       InternalScanner s) throws IOException {
264     ctPreCompactScanner.incrementAndGet();
265     return null;
266   }
267 
268   @Override
269   public void postCompact(ObserverContext<RegionCoprocessorEnvironment> e,
270       Store store, StoreFile resultFile) {
271     ctPostCompact.incrementAndGet();
272   }
273 
274   public boolean wasCompacted() {
275     return ctPreCompact.get() > 0 && ctPostCompact.get() > 0;
276   }
277 
278   @Override
279   public RegionScanner preScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c,
280       final Scan scan,
281       final RegionScanner s) throws IOException {
282     ctPreScannerOpen.incrementAndGet();
283     return null;
284   }
285 
286   @Override
287   public KeyValueScanner preStoreScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c,
288       final Store store, final Scan scan, final NavigableSet<byte[]> targetCols,
289       final KeyValueScanner s) throws IOException {
290     ctPreStoreScannerOpen.incrementAndGet();
291     return null;
292   }
293 
294   @Override
295   public RegionScanner postScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c,
296       final Scan scan, final RegionScanner s)
297       throws IOException {
298     ctPostScannerOpen.incrementAndGet();
299     return s;
300   }
301 
302   @Override
303   public boolean preScannerNext(final ObserverContext<RegionCoprocessorEnvironment> c,
304       final InternalScanner s, final List<Result> results,
305       final int limit, final boolean hasMore) throws IOException {
306     ctPreScannerNext.incrementAndGet();
307     return hasMore;
308   }
309 
310   @Override
311   public boolean postScannerNext(final ObserverContext<RegionCoprocessorEnvironment> c,
312       final InternalScanner s, final List<Result> results, final int limit,
313       final boolean hasMore) throws IOException {
314     ctPostScannerNext.incrementAndGet();
315     return hasMore;
316   }
317 
318   @Override
319   public void preScannerClose(final ObserverContext<RegionCoprocessorEnvironment> c,
320       final InternalScanner s) throws IOException {
321     ctPreScannerClose.incrementAndGet();
322   }
323 
324   @Override
325   public void postScannerClose(final ObserverContext<RegionCoprocessorEnvironment> c,
326       final InternalScanner s) throws IOException {
327     ctPostScannerClose.incrementAndGet();
328   }
329 
330   @Override
331   public void preGetOp(final ObserverContext<RegionCoprocessorEnvironment> c, final Get get,
332       final List<Cell> results) throws IOException {
333     RegionCoprocessorEnvironment e = c.getEnvironment();
334     assertNotNull(e);
335     assertNotNull(e.getRegion());
336     assertNotNull(get);
337     assertNotNull(results);
338     ctPreGet.incrementAndGet();
339   }
340 
341   @Override
342   public void postGetOp(final ObserverContext<RegionCoprocessorEnvironment> c, final Get get,
343       final List<Cell> results) {
344     RegionCoprocessorEnvironment e = c.getEnvironment();
345     assertNotNull(e);
346     assertNotNull(e.getRegion());
347     assertNotNull(get);
348     assertNotNull(results);
349     if (e.getRegion().getTableDesc().getTableName().equals(
350         TestRegionObserverInterface.TEST_TABLE)) {
351       boolean foundA = false;
352       boolean foundB = false;
353       boolean foundC = false;
354       for (Cell kv: results) {
355         if (CellUtil.matchingFamily(kv, TestRegionObserverInterface.A)) {
356           foundA = true;
357         }
358         if (CellUtil.matchingFamily(kv, TestRegionObserverInterface.B)) {
359           foundB = true;
360         }
361         if (CellUtil.matchingFamily(kv, TestRegionObserverInterface.C)) {
362           foundC = true;
363         }
364       }
365       assertTrue(foundA);
366       assertTrue(foundB);
367       assertTrue(foundC);
368     }
369     ctPostGet.incrementAndGet();
370   }
371 
372   @Override
373   public void prePut(final ObserverContext<RegionCoprocessorEnvironment> c, 
374       final Put put, final WALEdit edit,
375       final Durability durability) throws IOException {
376     Map<byte[], List<Cell>> familyMap  = put.getFamilyCellMap();
377     RegionCoprocessorEnvironment e = c.getEnvironment();
378     assertNotNull(e);
379     assertNotNull(e.getRegion());
380     assertNotNull(familyMap);
381     if (e.getRegion().getTableDesc().getTableName().equals(
382         TestRegionObserverInterface.TEST_TABLE)) {
383       List<Cell> cells = familyMap.get(TestRegionObserverInterface.A);
384       assertNotNull(cells);
385       assertNotNull(cells.get(0));
386       KeyValue kv = (KeyValue)cells.get(0);
387       assertTrue(Bytes.equals(kv.getQualifier(),
388           TestRegionObserverInterface.A));
389       cells = familyMap.get(TestRegionObserverInterface.B);
390       assertNotNull(cells);
391       assertNotNull(cells.get(0));
392       kv = (KeyValue)cells.get(0);
393       assertTrue(Bytes.equals(kv.getQualifier(),
394           TestRegionObserverInterface.B));
395       cells = familyMap.get(TestRegionObserverInterface.C);
396       assertNotNull(cells);
397       assertNotNull(cells.get(0));
398       kv = (KeyValue)cells.get(0);
399       assertTrue(Bytes.equals(kv.getQualifier(),
400           TestRegionObserverInterface.C));
401     }
402     ctPrePut.incrementAndGet();
403   }
404 
405   @Override
406   public void postPut(final ObserverContext<RegionCoprocessorEnvironment> c,
407       final Put put, final WALEdit edit,
408       final Durability durability) throws IOException {
409     Map<byte[], List<Cell>> familyMap  = put.getFamilyCellMap();
410     RegionCoprocessorEnvironment e = c.getEnvironment();
411     assertNotNull(e);
412     assertNotNull(e.getRegion());
413     assertNotNull(familyMap);
414     List<Cell> cells = familyMap.get(TestRegionObserverInterface.A);
415     if (e.getRegion().getTableDesc().getTableName().equals(
416         TestRegionObserverInterface.TEST_TABLE)) {
417       assertNotNull(cells);
418       assertNotNull(cells.get(0));
419       // KeyValue v1 expectation.  Cast for now until we go all Cell all the time. TODO
420       KeyValue kv = (KeyValue)cells.get(0);
421       assertTrue(Bytes.equals(kv.getQualifier(), TestRegionObserverInterface.A));
422       cells = familyMap.get(TestRegionObserverInterface.B);
423       assertNotNull(cells);
424       assertNotNull(cells.get(0));
425       // KeyValue v1 expectation.  Cast for now until we go all Cell all the time. TODO
426       kv = (KeyValue)cells.get(0);
427       assertTrue(Bytes.equals(kv.getQualifier(), TestRegionObserverInterface.B));
428       cells = familyMap.get(TestRegionObserverInterface.C);
429       assertNotNull(cells);
430       assertNotNull(cells.get(0));
431       // KeyValue v1 expectation.  Cast for now until we go all Cell all the time. TODO
432       kv = (KeyValue)cells.get(0);
433       assertTrue(Bytes.equals(kv.getQualifier(), TestRegionObserverInterface.C));
434     }
435     ctPostPut.incrementAndGet();
436   }
437 
438   @Override
439   public void preDelete(final ObserverContext<RegionCoprocessorEnvironment> c, 
440       final Delete delete, final WALEdit edit,
441       final Durability durability) throws IOException {
442     Map<byte[], List<Cell>> familyMap  = delete.getFamilyCellMap();
443     RegionCoprocessorEnvironment e = c.getEnvironment();
444     assertNotNull(e);
445     assertNotNull(e.getRegion());
446     assertNotNull(familyMap);
447     if (ctBeforeDelete.get() > 0) {
448       ctPreDeleted.incrementAndGet();
449     }
450   }
451 
452   @Override
453   public void prePrepareTimeStampForDeleteVersion(ObserverContext<RegionCoprocessorEnvironment> e,
454       Mutation delete, Cell cell, byte[] byteNow, Get get) throws IOException {
455     ctPrePrepareDeleteTS.incrementAndGet();
456   }
457 
458   @Override
459   public void postDelete(final ObserverContext<RegionCoprocessorEnvironment> c, 
460       final Delete delete, final WALEdit edit,
461       final Durability durability) throws IOException {
462     Map<byte[], List<Cell>> familyMap  = delete.getFamilyCellMap();
463     RegionCoprocessorEnvironment e = c.getEnvironment();
464     assertNotNull(e);
465     assertNotNull(e.getRegion());
466     assertNotNull(familyMap);
467     ctBeforeDelete.set(0);
468     ctPostDeleted.incrementAndGet();
469   }
470   
471   @Override
472   public void preBatchMutate(ObserverContext<RegionCoprocessorEnvironment> c,
473       MiniBatchOperationInProgress<Mutation> miniBatchOp) throws IOException {
474     RegionCoprocessorEnvironment e = c.getEnvironment();
475     assertNotNull(e);
476     assertNotNull(e.getRegion());
477     assertNotNull(miniBatchOp);
478     ctPreBatchMutate.incrementAndGet();
479   }
480 
481   @Override
482   public void postBatchMutate(final ObserverContext<RegionCoprocessorEnvironment> c,
483       final MiniBatchOperationInProgress<Mutation> miniBatchOp) throws IOException {
484     RegionCoprocessorEnvironment e = c.getEnvironment();
485     assertNotNull(e);
486     assertNotNull(e.getRegion());
487     assertNotNull(miniBatchOp);
488     ctPostBatchMutate.incrementAndGet();
489   }
490 
491   @Override
492   public void postStartRegionOperation(final ObserverContext<RegionCoprocessorEnvironment> ctx,
493       Operation op) throws IOException {
494     ctPostStartRegionOperation.incrementAndGet();
495   }
496 
497   @Override
498   public void postCloseRegionOperation(final ObserverContext<RegionCoprocessorEnvironment> ctx,
499       Operation op) throws IOException {
500     if (ctPostStartRegionOperation.get() > 0) {
501       ctPostCloseRegionOperation.incrementAndGet();
502     }
503   }
504 
505   @Override
506   public void postBatchMutateIndispensably(final ObserverContext<RegionCoprocessorEnvironment> ctx,
507       MiniBatchOperationInProgress<Mutation> miniBatchOp, final boolean success) throws IOException {
508     ctPostBatchMutateIndispensably.incrementAndGet();
509   }
510 
511   @Override
512   public void preGetClosestRowBefore(final ObserverContext<RegionCoprocessorEnvironment> c,
513       final byte[] row, final byte[] family, final Result result)
514       throws IOException {
515     RegionCoprocessorEnvironment e = c.getEnvironment();
516     assertNotNull(e);
517     assertNotNull(e.getRegion());
518     assertNotNull(row);
519     assertNotNull(result);
520     if (ctBeforeDelete.get() > 0) {
521       ctPreGetClosestRowBefore.incrementAndGet();
522     }
523   }
524 
525   @Override
526   public void postGetClosestRowBefore(final ObserverContext<RegionCoprocessorEnvironment> c,
527       final byte[] row, final byte[] family, final Result result)
528       throws IOException {
529     RegionCoprocessorEnvironment e = c.getEnvironment();
530     assertNotNull(e);
531     assertNotNull(e.getRegion());
532     assertNotNull(row);
533     assertNotNull(result);
534     ctPostGetClosestRowBefore.incrementAndGet();
535   }
536 
537   @Override
538   public Result preIncrement(final ObserverContext<RegionCoprocessorEnvironment> c,
539       final Increment increment) throws IOException {
540     ctPreIncrement.incrementAndGet();
541     return null;
542   }
543 
544   @Override
545   public Result preIncrementAfterRowLock(ObserverContext<RegionCoprocessorEnvironment> e,
546       Increment increment) throws IOException {
547     ctPreIncrementAfterRowLock.incrementAndGet();
548     return null;
549   }
550 
551   @Override
552   public Result postIncrement(final ObserverContext<RegionCoprocessorEnvironment> c,
553       final Increment increment, final Result result) throws IOException {
554     ctPostIncrement.incrementAndGet();
555     return result;
556   }
557 
558   @Override
559   public boolean preCheckAndPut(ObserverContext<RegionCoprocessorEnvironment> e, byte[] row,
560       byte[] family, byte[] qualifier, CompareOp compareOp, ByteArrayComparable comparator,
561       Put put, boolean result) throws IOException {
562     ctPreCheckAndPut.incrementAndGet();
563     return true;
564   }
565 
566   @Override
567   public boolean preCheckAndPutAfterRowLock(ObserverContext<RegionCoprocessorEnvironment> e,
568       byte[] row, byte[] family, byte[] qualifier, CompareOp compareOp,
569       ByteArrayComparable comparator, Put put, boolean result) throws IOException {
570     ctPreCheckAndPutAfterRowLock.incrementAndGet();
571     return true;
572   }
573 
574   @Override
575   public boolean postCheckAndPut(ObserverContext<RegionCoprocessorEnvironment> e, byte[] row,
576       byte[] family, byte[] qualifier, CompareOp compareOp, ByteArrayComparable comparator,
577       Put put, boolean result) throws IOException {
578     ctPostCheckAndPut.incrementAndGet();
579     return true;
580   }
581 
582   @Override
583   public boolean preCheckAndDelete(ObserverContext<RegionCoprocessorEnvironment> e, byte[] row,
584       byte[] family, byte[] qualifier, CompareOp compareOp, ByteArrayComparable comparator,
585       Delete delete, boolean result) throws IOException {
586     ctPreCheckAndDelete.incrementAndGet();
587     return true;
588   }
589 
590   @Override
591   public boolean preCheckAndDeleteAfterRowLock(ObserverContext<RegionCoprocessorEnvironment> e,
592       byte[] row, byte[] family, byte[] qualifier, CompareOp compareOp,
593       ByteArrayComparable comparator, Delete delete, boolean result) throws IOException {
594     ctPreCheckAndDeleteAfterRowLock.incrementAndGet();
595     return true;
596   }
597 
598   @Override
599   public boolean postCheckAndDelete(ObserverContext<RegionCoprocessorEnvironment> e, byte[] row,
600       byte[] family, byte[] qualifier, CompareOp compareOp, ByteArrayComparable comparator,
601       Delete delete, boolean result) throws IOException {
602     ctPostCheckAndDelete.incrementAndGet();
603     return true;
604   }
605 
606   @Override
607   public Result preAppendAfterRowLock(ObserverContext<RegionCoprocessorEnvironment> e, 
608       Append append) throws IOException {
609     ctPreAppendAfterRowLock.incrementAndGet();
610     return null;
611   }
612 
613   @Override
614   public Result preAppend(ObserverContext<RegionCoprocessorEnvironment> e, Append append)
615       throws IOException {
616     ctPreAppend.incrementAndGet();
617     return null;
618   }
619 
620   @Override
621   public Result postAppend(ObserverContext<RegionCoprocessorEnvironment> e, Append append,
622       Result result) throws IOException {
623     ctPostAppend.incrementAndGet();
624     return null;
625   }
626 
627   @Override
628   public void preBulkLoadHFile(ObserverContext<RegionCoprocessorEnvironment> ctx,
629                                List<Pair<byte[], String>> familyPaths) throws IOException {
630     RegionCoprocessorEnvironment e = ctx.getEnvironment();
631     assertNotNull(e);
632     assertNotNull(e.getRegion());
633     if (e.getRegion().getTableDesc().getTableName().equals(
634         TestRegionObserverInterface.TEST_TABLE)) {
635       assertNotNull(familyPaths);
636       assertEquals(1,familyPaths.size());
637       assertArrayEquals(familyPaths.get(0).getFirst(), TestRegionObserverInterface.A);
638       String familyPath = familyPaths.get(0).getSecond();
639       String familyName = Bytes.toString(TestRegionObserverInterface.A);
640       assertEquals(familyPath.substring(familyPath.length()-familyName.length()-1),"/"+familyName);
641     }
642     ctPreBulkLoadHFile.incrementAndGet();
643   }
644 
645   @Override
646   public boolean postBulkLoadHFile(ObserverContext<RegionCoprocessorEnvironment> ctx,
647       List<Pair<byte[], String>> familyPaths, Map<byte[], List<Path>> map, boolean hasLoaded)
648           throws IOException {
649     RegionCoprocessorEnvironment e = ctx.getEnvironment();
650     assertNotNull(e);
651     assertNotNull(e.getRegion());
652     if (e.getRegion().getTableDesc().getTableName().equals(
653         TestRegionObserverInterface.TEST_TABLE)) {
654       assertNotNull(familyPaths);
655       assertEquals(1,familyPaths.size());
656       assertArrayEquals(familyPaths.get(0).getFirst(), TestRegionObserverInterface.A);
657       String familyPath = familyPaths.get(0).getSecond();
658       String familyName = Bytes.toString(TestRegionObserverInterface.A);
659       assertEquals(familyPath.substring(familyPath.length()-familyName.length()-1),"/"+familyName);
660     }
661     ctPostBulkLoadHFile.incrementAndGet();
662     return hasLoaded;
663   }
664 
665   @Override
666   public void preWALRestore(ObserverContext<? extends RegionCoprocessorEnvironment> env,
667       HRegionInfo info, WALKey logKey, WALEdit logEdit) throws IOException {
668     String tableName = logKey.getTablename().getNameAsString();
669     if (tableName.equals(TABLE_SKIPPED)) {
670       // skip recovery of TABLE_SKIPPED for testing purpose
671       env.bypass();
672       return;
673     }
674     ctPreWALRestore.incrementAndGet();
675   }
676 
677   @Override
678   public void preWALRestore(ObserverContext<RegionCoprocessorEnvironment> env, HRegionInfo info,
679                             HLogKey logKey, WALEdit logEdit) throws IOException {
680     preWALRestore(env, info, (WALKey)logKey, logEdit);
681     ctPreWALRestoreDeprecated.incrementAndGet();
682   }
683 
684   @Override
685   public void postWALRestore(ObserverContext<? extends RegionCoprocessorEnvironment> env,
686                              HRegionInfo info, WALKey logKey, WALEdit logEdit) throws IOException {
687     ctPostWALRestore.incrementAndGet();
688   }
689 
690   @Override
691   public void postWALRestore(ObserverContext<RegionCoprocessorEnvironment> env,
692                              HRegionInfo info, HLogKey logKey, WALEdit logEdit) throws IOException {
693     postWALRestore(env, info, (WALKey)logKey, logEdit);
694     ctPostWALRestoreDeprecated.incrementAndGet();
695   }
696 
697   @Override
698   public Reader preStoreFileReaderOpen(ObserverContext<RegionCoprocessorEnvironment> ctx,
699       FileSystem fs, Path p, FSDataInputStreamWrapper in, long size, CacheConfig cacheConf,
700       Reference r, Reader reader) throws IOException {
701     ctPreStoreFileReaderOpen.incrementAndGet();
702     return null;
703   }
704 
705   @Override
706   public Reader postStoreFileReaderOpen(ObserverContext<RegionCoprocessorEnvironment> ctx,
707       FileSystem fs, Path p, FSDataInputStreamWrapper in, long size, CacheConfig cacheConf,
708       Reference r, Reader reader) throws IOException {
709     ctPostStoreFileReaderOpen.incrementAndGet();
710     return reader;
711   }
712 
713   public boolean hadPreGet() {
714     return ctPreGet.get() > 0;
715   }
716 
717   public boolean hadPostGet() {
718     return ctPostGet.get() > 0;
719   }
720 
721   public boolean hadPrePut() {
722     return ctPrePut.get() > 0;
723   }
724 
725   public boolean hadPostPut() {
726     return ctPostPut.get() > 0;
727   }
728   
729   public boolean hadPreBatchMutate() {
730     return ctPreBatchMutate.get() > 0;
731   }
732 
733   public boolean hadPostBatchMutate() {
734     return ctPostBatchMutate.get() > 0;
735   }
736 
737   public boolean hadPostBatchMutateIndispensably() {
738     return ctPostBatchMutateIndispensably.get() > 0;
739   }
740 
741   public boolean hadPostStartRegionOperation() {
742     return ctPostStartRegionOperation.get() > 0;
743   }
744 
745   public boolean hadPostCloseRegionOperation() {
746     return ctPostCloseRegionOperation.get() > 0;
747   }
748 
749   public boolean hadDelete() {
750     return !(ctBeforeDelete.get() > 0);
751   }
752 
753   public int getCtPostStartRegionOperation() {
754     return ctPostStartRegionOperation.get();
755   }
756 
757   public int getCtPostCloseRegionOperation() {
758     return ctPostCloseRegionOperation.get();
759   }
760 
761   public boolean hadPreCheckAndPut() {
762     return ctPreCheckAndPut.get() > 0;
763   }
764 
765   public boolean hadPreCheckAndPutAfterRowLock() {
766     return ctPreCheckAndPutAfterRowLock.get() > 0;
767   }
768 
769   public boolean hadPostCheckAndPut() {
770     return ctPostCheckAndPut.get() > 0;
771   }
772 
773   public boolean hadPreCheckAndDelete() {
774     return ctPreCheckAndDelete.get() > 0;
775   }
776 
777   public boolean hadPreCheckAndDeleteAfterRowLock() {
778     return ctPreCheckAndDeleteAfterRowLock.get() > 0;
779   }
780 
781   public boolean hadPostCheckAndDelete() {
782     return ctPostCheckAndDelete.get() > 0;
783   }
784 
785   public boolean hadPreIncrement() {
786     return ctPreIncrement.get() > 0;
787   }
788   
789   public boolean hadPreIncrementAfterRowLock() {
790     return ctPreIncrementAfterRowLock.get() > 0;
791   }
792 
793   public boolean hadPostIncrement() {
794     return ctPostIncrement.get() > 0;
795   }
796 
797   public boolean hadPreAppend() {
798     return ctPreAppend.get() > 0;
799   }
800 
801   public boolean hadPreAppendAfterRowLock() {
802     return ctPreAppendAfterRowLock.get() > 0;
803   }
804 
805   public boolean hadPostAppend() {
806     return ctPostAppend.get() > 0;
807   }
808 
809   public boolean hadPrePreparedDeleteTS() {
810     return ctPrePrepareDeleteTS.get() > 0;
811   }
812   
813   public boolean hadPreWALRestore() {
814     return ctPreWALRestore.get() > 0;
815   }
816 
817   public boolean hadPostWALRestore() {
818     return ctPostWALRestore.get() > 0;
819   }
820 
821   public boolean wasScannerNextCalled() {
822     return ctPreScannerNext.get() > 0 && ctPostScannerNext.get() > 0;
823   }
824   public boolean wasScannerCloseCalled() {
825     return ctPreScannerClose.get() > 0 && ctPostScannerClose.get() > 0;
826   }
827   public boolean wasScannerOpenCalled() {
828     return ctPreScannerOpen.get() > 0 && ctPostScannerOpen.get() > 0;
829   }
830   public boolean hadDeleted() {
831     return ctPreDeleted.get() > 0 && ctPostDeleted.get() > 0;
832   }
833 
834   public boolean hadPostBulkLoadHFile() {
835     return ctPostBulkLoadHFile.get() > 0;
836   }
837 
838   public boolean hadPreBulkLoadHFile() {
839     return ctPreBulkLoadHFile.get() > 0;
840   }
841 
842 
843   public int getCtBeforeDelete() {
844     return ctBeforeDelete.get();
845   }
846 
847   public int getCtPreOpen() {
848     return ctPreOpen.get();
849   }
850 
851   public int getCtPostOpen() {
852     return ctPostOpen.get();
853   }
854 
855   public int getCtPreClose() {
856     return ctPreClose.get();
857   }
858 
859   public int getCtPostClose() {
860     return ctPostClose.get();
861   }
862 
863   public int getCtPreFlush() {
864     return ctPreFlush.get();
865   }
866 
867   public int getCtPreFlushScannerOpen() {
868     return ctPreFlushScannerOpen.get();
869   }
870 
871   public int getCtPostFlush() {
872     return ctPostFlush.get();
873   }
874 
875   public int getCtPreSplit() {
876     return ctPreSplit.get();
877   }
878   
879   public int getCtPreSplitBeforePONR() {
880     return ctPreSplitBeforePONR.get();
881   }
882 
883   public int getCtPreSplitAfterPONR() {
884     return ctPreSplitAfterPONR.get();
885   }
886 
887   public int getCtPostSplit() {
888     return ctPostSplit.get();
889   }
890 
891   public int getCtPreCompactSelect() {
892     return ctPreCompactSelect.get();
893   }
894 
895   public int getCtPostCompactSelect() {
896     return ctPostCompactSelect.get();
897   }
898 
899   public int getCtPreCompactScanner() {
900     return ctPreCompactScanner.get();
901   }
902 
903   public int getCtPreCompact() {
904     return ctPreCompact.get();
905   }
906 
907   public int getCtPostCompact() {
908     return ctPostCompact.get();
909   }
910 
911   public int getCtPreGet() {
912     return ctPreGet.get();
913   }
914 
915   public int getCtPostGet() {
916     return ctPostGet.get();
917   }
918 
919   public int getCtPrePut() {
920     return ctPrePut.get();
921   }
922 
923   public int getCtPostPut() {
924     return ctPostPut.get();
925   }
926 
927   public int getCtPreDeleted() {
928     return ctPreDeleted.get();
929   }
930 
931   public int getCtPostDeleted() {
932     return ctPostDeleted.get();
933   }
934 
935   public int getCtPreGetClosestRowBefore() {
936     return ctPreGetClosestRowBefore.get();
937   }
938 
939   public int getCtPostGetClosestRowBefore() {
940     return ctPostGetClosestRowBefore.get();
941   }
942 
943   public int getCtPreIncrement() {
944     return ctPreIncrement.get();
945   }
946 
947   public int getCtPostIncrement() {
948     return ctPostIncrement.get();
949   }
950 
951   public int getCtPreWALRestore() {
952     return ctPreWALRestore.get();
953   }
954 
955   public int getCtPostWALRestore() {
956     return ctPostWALRestore.get();
957   }
958 
959   public int getCtPreWALRestoreDeprecated() {
960     return ctPreWALRestoreDeprecated.get();
961   }
962 
963   public int getCtPostWALRestoreDeprecated() {
964     return ctPostWALRestoreDeprecated.get();
965   }
966 
967   public boolean wasStoreFileReaderOpenCalled() {
968     return ctPreStoreFileReaderOpen.get() > 0 && ctPostStoreFileReaderOpen.get() > 0;
969   }
970 
971   /**
972    * This implementation should trigger our legacy support because it does not directly
973    * implement the newer API calls.
974    */
975   public static class Legacy extends SimpleRegionObserver {
976   }
977 }