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