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 ctPostScannerFilterRow = new AtomicInteger(0);
123   final AtomicInteger ctPreScannerClose = new AtomicInteger(0);
124   final AtomicInteger ctPostScannerClose = new AtomicInteger(0);
125   final AtomicInteger ctPreScannerOpen = new AtomicInteger(0);
126   final AtomicInteger ctPreStoreScannerOpen = new AtomicInteger(0);
127   final AtomicInteger ctPostScannerOpen = new AtomicInteger(0);
128   final AtomicInteger ctPreBulkLoadHFile = new AtomicInteger(0);
129   final AtomicInteger ctPostBulkLoadHFile = new AtomicInteger(0);
130   final AtomicInteger ctPreBatchMutate = new AtomicInteger(0);
131   final AtomicInteger ctPostBatchMutate = new AtomicInteger(0);
132   final AtomicInteger ctPreWALRestore = new AtomicInteger(0);
133   final AtomicInteger ctPostWALRestore = 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().getRegionNameAsString(), 2000, null);
155     leases.cancelLease(re.getRegion().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, HRegion l, HRegion 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 boolean postScannerFilterRow(final ObserverContext<RegionCoprocessorEnvironment> e,
320       final InternalScanner s, final byte[] currentRow, final int offset, final short length,
321       final boolean hasMore) throws IOException {
322     ctPostScannerFilterRow.incrementAndGet();
323     return hasMore;
324   }
325 
326   @Override
327   public void preScannerClose(final ObserverContext<RegionCoprocessorEnvironment> c,
328       final InternalScanner s) throws IOException {
329     ctPreScannerClose.incrementAndGet();
330   }
331 
332   @Override
333   public void postScannerClose(final ObserverContext<RegionCoprocessorEnvironment> c,
334       final InternalScanner s) throws IOException {
335     ctPostScannerClose.incrementAndGet();
336   }
337 
338   @Override
339   public void preGetOp(final ObserverContext<RegionCoprocessorEnvironment> c, final Get get,
340       final List<Cell> results) throws IOException {
341     RegionCoprocessorEnvironment e = c.getEnvironment();
342     assertNotNull(e);
343     assertNotNull(e.getRegion());
344     assertNotNull(get);
345     assertNotNull(results);
346     ctPreGet.incrementAndGet();
347   }
348 
349   @Override
350   public void postGetOp(final ObserverContext<RegionCoprocessorEnvironment> c, final Get get,
351       final List<Cell> results) {
352     RegionCoprocessorEnvironment e = c.getEnvironment();
353     assertNotNull(e);
354     assertNotNull(e.getRegion());
355     assertNotNull(get);
356     assertNotNull(results);
357     if (e.getRegion().getTableDesc().getTableName().equals(
358         TestRegionObserverInterface.TEST_TABLE)) {
359       boolean foundA = false;
360       boolean foundB = false;
361       boolean foundC = false;
362       for (Cell kv: results) {
363         if (CellUtil.matchingFamily(kv, TestRegionObserverInterface.A)) {
364           foundA = true;
365         }
366         if (CellUtil.matchingFamily(kv, TestRegionObserverInterface.B)) {
367           foundB = true;
368         }
369         if (CellUtil.matchingFamily(kv, TestRegionObserverInterface.C)) {
370           foundC = true;
371         }
372       }
373       assertTrue(foundA);
374       assertTrue(foundB);
375       assertTrue(foundC);
376     }
377     ctPostGet.incrementAndGet();
378   }
379 
380   @Override
381   public void prePut(final ObserverContext<RegionCoprocessorEnvironment> c, 
382       final Put put, final WALEdit edit,
383       final Durability durability) throws IOException {
384     Map<byte[], List<Cell>> familyMap  = put.getFamilyCellMap();
385     RegionCoprocessorEnvironment e = c.getEnvironment();
386     assertNotNull(e);
387     assertNotNull(e.getRegion());
388     assertNotNull(familyMap);
389     if (e.getRegion().getTableDesc().getTableName().equals(
390         TestRegionObserverInterface.TEST_TABLE)) {
391       List<Cell> cells = familyMap.get(TestRegionObserverInterface.A);
392       assertNotNull(cells);
393       assertNotNull(cells.get(0));
394       KeyValue kv = (KeyValue)cells.get(0);
395       assertTrue(Bytes.equals(kv.getQualifier(),
396           TestRegionObserverInterface.A));
397       cells = familyMap.get(TestRegionObserverInterface.B);
398       assertNotNull(cells);
399       assertNotNull(cells.get(0));
400       kv = (KeyValue)cells.get(0);
401       assertTrue(Bytes.equals(kv.getQualifier(),
402           TestRegionObserverInterface.B));
403       cells = familyMap.get(TestRegionObserverInterface.C);
404       assertNotNull(cells);
405       assertNotNull(cells.get(0));
406       kv = (KeyValue)cells.get(0);
407       assertTrue(Bytes.equals(kv.getQualifier(),
408           TestRegionObserverInterface.C));
409     }
410     ctPrePut.incrementAndGet();
411   }
412 
413   @Override
414   public void postPut(final ObserverContext<RegionCoprocessorEnvironment> c,
415       final Put put, final WALEdit edit,
416       final Durability durability) throws IOException {
417     Map<byte[], List<Cell>> familyMap  = put.getFamilyCellMap();
418     RegionCoprocessorEnvironment e = c.getEnvironment();
419     assertNotNull(e);
420     assertNotNull(e.getRegion());
421     assertNotNull(familyMap);
422     List<Cell> cells = familyMap.get(TestRegionObserverInterface.A);
423     if (e.getRegion().getTableDesc().getTableName().equals(
424         TestRegionObserverInterface.TEST_TABLE)) {
425       assertNotNull(cells);
426       assertNotNull(cells.get(0));
427       // KeyValue v1 expectation.  Cast for now until we go all Cell all the time. TODO
428       KeyValue kv = (KeyValue)cells.get(0);
429       assertTrue(Bytes.equals(kv.getQualifier(), TestRegionObserverInterface.A));
430       cells = familyMap.get(TestRegionObserverInterface.B);
431       assertNotNull(cells);
432       assertNotNull(cells.get(0));
433       // KeyValue v1 expectation.  Cast for now until we go all Cell all the time. TODO
434       kv = (KeyValue)cells.get(0);
435       assertTrue(Bytes.equals(kv.getQualifier(), TestRegionObserverInterface.B));
436       cells = familyMap.get(TestRegionObserverInterface.C);
437       assertNotNull(cells);
438       assertNotNull(cells.get(0));
439       // KeyValue v1 expectation.  Cast for now until we go all Cell all the time. TODO
440       kv = (KeyValue)cells.get(0);
441       assertTrue(Bytes.equals(kv.getQualifier(), TestRegionObserverInterface.C));
442     }
443     ctPostPut.incrementAndGet();
444   }
445 
446   @Override
447   public void preDelete(final ObserverContext<RegionCoprocessorEnvironment> c, 
448       final Delete delete, final WALEdit edit,
449       final Durability durability) throws IOException {
450     Map<byte[], List<Cell>> familyMap  = delete.getFamilyCellMap();
451     RegionCoprocessorEnvironment e = c.getEnvironment();
452     assertNotNull(e);
453     assertNotNull(e.getRegion());
454     assertNotNull(familyMap);
455     if (ctBeforeDelete.get() > 0) {
456       ctPreDeleted.incrementAndGet();
457     }
458   }
459 
460   @Override
461   public void prePrepareTimeStampForDeleteVersion(ObserverContext<RegionCoprocessorEnvironment> e,
462       Mutation delete, Cell cell, byte[] byteNow, Get get) throws IOException {
463     ctPrePrepareDeleteTS.incrementAndGet();
464   }
465 
466   @Override
467   public void postDelete(final ObserverContext<RegionCoprocessorEnvironment> c, 
468       final Delete delete, final WALEdit edit,
469       final Durability durability) throws IOException {
470     Map<byte[], List<Cell>> familyMap  = delete.getFamilyCellMap();
471     RegionCoprocessorEnvironment e = c.getEnvironment();
472     assertNotNull(e);
473     assertNotNull(e.getRegion());
474     assertNotNull(familyMap);
475     ctBeforeDelete.set(0);
476     ctPostDeleted.incrementAndGet();
477   }
478   
479   @Override
480   public void preBatchMutate(ObserverContext<RegionCoprocessorEnvironment> c,
481       MiniBatchOperationInProgress<Mutation> miniBatchOp) throws IOException {
482     RegionCoprocessorEnvironment e = c.getEnvironment();
483     assertNotNull(e);
484     assertNotNull(e.getRegion());
485     assertNotNull(miniBatchOp);
486     ctPreBatchMutate.incrementAndGet();
487   }
488 
489   @Override
490   public void postBatchMutate(final ObserverContext<RegionCoprocessorEnvironment> c,
491       final MiniBatchOperationInProgress<Mutation> miniBatchOp) throws IOException {
492     RegionCoprocessorEnvironment e = c.getEnvironment();
493     assertNotNull(e);
494     assertNotNull(e.getRegion());
495     assertNotNull(miniBatchOp);
496     ctPostBatchMutate.incrementAndGet();
497   }
498 
499   @Override
500   public void postStartRegionOperation(final ObserverContext<RegionCoprocessorEnvironment> ctx,
501       Operation op) throws IOException {
502     ctPostStartRegionOperation.incrementAndGet();
503   }
504 
505   @Override
506   public void postCloseRegionOperation(final ObserverContext<RegionCoprocessorEnvironment> ctx,
507       Operation op) throws IOException {
508     if (ctPostStartRegionOperation.get() > 0) {
509       ctPostCloseRegionOperation.incrementAndGet();
510     }
511   }
512 
513   @Override
514   public void postBatchMutateIndispensably(final ObserverContext<RegionCoprocessorEnvironment> ctx,
515       MiniBatchOperationInProgress<Mutation> miniBatchOp, final boolean success) throws IOException {
516     ctPostBatchMutateIndispensably.incrementAndGet();
517   }
518 
519   @Override
520   public void preGetClosestRowBefore(final ObserverContext<RegionCoprocessorEnvironment> c,
521       final byte[] row, final byte[] family, final Result result)
522       throws IOException {
523     RegionCoprocessorEnvironment e = c.getEnvironment();
524     assertNotNull(e);
525     assertNotNull(e.getRegion());
526     assertNotNull(row);
527     assertNotNull(result);
528     if (ctBeforeDelete.get() > 0) {
529       ctPreGetClosestRowBefore.incrementAndGet();
530     }
531   }
532 
533   @Override
534   public void postGetClosestRowBefore(final ObserverContext<RegionCoprocessorEnvironment> c,
535       final byte[] row, final byte[] family, final Result result)
536       throws IOException {
537     RegionCoprocessorEnvironment e = c.getEnvironment();
538     assertNotNull(e);
539     assertNotNull(e.getRegion());
540     assertNotNull(row);
541     assertNotNull(result);
542     ctPostGetClosestRowBefore.incrementAndGet();
543   }
544 
545   @Override
546   public Result preIncrement(final ObserverContext<RegionCoprocessorEnvironment> c,
547       final Increment increment) throws IOException {
548     ctPreIncrement.incrementAndGet();
549     return null;
550   }
551 
552   @Override
553   public Result preIncrementAfterRowLock(ObserverContext<RegionCoprocessorEnvironment> e,
554       Increment increment) throws IOException {
555     ctPreIncrementAfterRowLock.incrementAndGet();
556     return null;
557   }
558 
559   @Override
560   public Result postIncrement(final ObserverContext<RegionCoprocessorEnvironment> c,
561       final Increment increment, final Result result) throws IOException {
562     ctPostIncrement.incrementAndGet();
563     return result;
564   }
565 
566   @Override
567   public boolean preCheckAndPut(ObserverContext<RegionCoprocessorEnvironment> e, byte[] row,
568       byte[] family, byte[] qualifier, CompareOp compareOp, ByteArrayComparable comparator,
569       Put put, boolean result) throws IOException {
570     ctPreCheckAndPut.incrementAndGet();
571     return true;
572   }
573 
574   @Override
575   public boolean preCheckAndPutAfterRowLock(ObserverContext<RegionCoprocessorEnvironment> e,
576       byte[] row, byte[] family, byte[] qualifier, CompareOp compareOp,
577       ByteArrayComparable comparator, Put put, boolean result) throws IOException {
578     ctPreCheckAndPutAfterRowLock.incrementAndGet();
579     return true;
580   }
581 
582   @Override
583   public boolean postCheckAndPut(ObserverContext<RegionCoprocessorEnvironment> e, byte[] row,
584       byte[] family, byte[] qualifier, CompareOp compareOp, ByteArrayComparable comparator,
585       Put put, boolean result) throws IOException {
586     ctPostCheckAndPut.incrementAndGet();
587     return true;
588   }
589 
590   @Override
591   public boolean preCheckAndDelete(ObserverContext<RegionCoprocessorEnvironment> e, byte[] row,
592       byte[] family, byte[] qualifier, CompareOp compareOp, ByteArrayComparable comparator,
593       Delete delete, boolean result) throws IOException {
594     ctPreCheckAndDelete.incrementAndGet();
595     return true;
596   }
597 
598   @Override
599   public boolean preCheckAndDeleteAfterRowLock(ObserverContext<RegionCoprocessorEnvironment> e,
600       byte[] row, byte[] family, byte[] qualifier, CompareOp compareOp,
601       ByteArrayComparable comparator, Delete delete, boolean result) throws IOException {
602     ctPreCheckAndDeleteAfterRowLock.incrementAndGet();
603     return true;
604   }
605 
606   @Override
607   public boolean postCheckAndDelete(ObserverContext<RegionCoprocessorEnvironment> e, byte[] row,
608       byte[] family, byte[] qualifier, CompareOp compareOp, ByteArrayComparable comparator,
609       Delete delete, boolean result) throws IOException {
610     ctPostCheckAndDelete.incrementAndGet();
611     return true;
612   }
613 
614   @Override
615   public Result preAppendAfterRowLock(ObserverContext<RegionCoprocessorEnvironment> e, 
616       Append append) throws IOException {
617     ctPreAppendAfterRowLock.incrementAndGet();
618     return null;
619   }
620 
621   @Override
622   public Result preAppend(ObserverContext<RegionCoprocessorEnvironment> e, Append append)
623       throws IOException {
624     ctPreAppend.incrementAndGet();
625     return null;
626   }
627 
628   @Override
629   public Result postAppend(ObserverContext<RegionCoprocessorEnvironment> e, Append append,
630       Result result) throws IOException {
631     ctPostAppend.incrementAndGet();
632     return null;
633   }
634 
635   @Override
636   public void preBulkLoadHFile(ObserverContext<RegionCoprocessorEnvironment> ctx,
637                                List<Pair<byte[], String>> familyPaths) throws IOException {
638     RegionCoprocessorEnvironment e = ctx.getEnvironment();
639     assertNotNull(e);
640     assertNotNull(e.getRegion());
641     if (e.getRegion().getTableDesc().getTableName().equals(
642         TestRegionObserverInterface.TEST_TABLE)) {
643       assertNotNull(familyPaths);
644       assertEquals(1,familyPaths.size());
645       assertArrayEquals(familyPaths.get(0).getFirst(), TestRegionObserverInterface.A);
646       String familyPath = familyPaths.get(0).getSecond();
647       String familyName = Bytes.toString(TestRegionObserverInterface.A);
648       assertEquals(familyPath.substring(familyPath.length()-familyName.length()-1),"/"+familyName);
649     }
650     ctPreBulkLoadHFile.incrementAndGet();
651   }
652 
653   @Override
654   public boolean postBulkLoadHFile(ObserverContext<RegionCoprocessorEnvironment> ctx,
655       List<Pair<byte[], String>> familyPaths, boolean hasLoaded) throws IOException {
656     RegionCoprocessorEnvironment e = ctx.getEnvironment();
657     assertNotNull(e);
658     assertNotNull(e.getRegion());
659     if (e.getRegion().getTableDesc().getTableName().equals(
660         TestRegionObserverInterface.TEST_TABLE)) {
661       assertNotNull(familyPaths);
662       assertEquals(1,familyPaths.size());
663       assertArrayEquals(familyPaths.get(0).getFirst(), TestRegionObserverInterface.A);
664       String familyPath = familyPaths.get(0).getSecond();
665       String familyName = Bytes.toString(TestRegionObserverInterface.A);
666       assertEquals(familyPath.substring(familyPath.length()-familyName.length()-1),"/"+familyName);
667     }
668     ctPostBulkLoadHFile.incrementAndGet();
669     return hasLoaded;
670   }
671 
672   @Override
673   public void preWALRestore(ObserverContext<RegionCoprocessorEnvironment> env, HRegionInfo info,
674                             HLogKey logKey, WALEdit logEdit) throws IOException {
675     String tableName = logKey.getTablename().getNameAsString();
676     if (tableName.equals(TABLE_SKIPPED)) {
677       // skip recovery of TABLE_SKIPPED for testing purpose
678       env.bypass();
679       return;
680     }
681     ctPreWALRestore.incrementAndGet();
682   }
683 
684   @Override
685   public void postWALRestore(ObserverContext<RegionCoprocessorEnvironment> env,
686                              HRegionInfo info, HLogKey logKey, WALEdit logEdit) throws IOException {
687     ctPostWALRestore.incrementAndGet();
688   }
689 
690   @Override
691   public Reader preStoreFileReaderOpen(ObserverContext<RegionCoprocessorEnvironment> ctx,
692       FileSystem fs, Path p, FSDataInputStreamWrapper in, long size, CacheConfig cacheConf,
693       Reference r, Reader reader) throws IOException {
694     ctPreStoreFileReaderOpen.incrementAndGet();
695     return null;
696   }
697 
698   @Override
699   public Reader postStoreFileReaderOpen(ObserverContext<RegionCoprocessorEnvironment> ctx,
700       FileSystem fs, Path p, FSDataInputStreamWrapper in, long size, CacheConfig cacheConf,
701       Reference r, Reader reader) throws IOException {
702     ctPostStoreFileReaderOpen.incrementAndGet();
703     return reader;
704   }
705 
706   public boolean hadPreGet() {
707     return ctPreGet.get() > 0;
708   }
709 
710   public boolean hadPostGet() {
711     return ctPostGet.get() > 0;
712   }
713 
714   public boolean hadPrePut() {
715     return ctPrePut.get() > 0;
716   }
717 
718   public boolean hadPostPut() {
719     return ctPostPut.get() > 0;
720   }
721   
722   public boolean hadPreBatchMutate() {
723     return ctPreBatchMutate.get() > 0;
724   }
725 
726   public boolean hadPostBatchMutate() {
727     return ctPostBatchMutate.get() > 0;
728   }
729 
730   public boolean hadPostBatchMutateIndispensably() {
731     return ctPostBatchMutateIndispensably.get() > 0;
732   }
733 
734   public boolean hadPostStartRegionOperation() {
735     return ctPostStartRegionOperation.get() > 0;
736   }
737 
738   public boolean hadPostCloseRegionOperation() {
739     return ctPostCloseRegionOperation.get() > 0;
740   }
741 
742   public boolean hadDelete() {
743     return !(ctBeforeDelete.get() > 0);
744   }
745 
746   public int getCtPostStartRegionOperation() {
747     return ctPostStartRegionOperation.get();
748   }
749 
750   public int getCtPostCloseRegionOperation() {
751     return ctPostCloseRegionOperation.get();
752   }
753 
754   public boolean hadPreCheckAndPut() {
755     return ctPreCheckAndPut.get() > 0;
756   }
757 
758   public boolean hadPreCheckAndPutAfterRowLock() {
759     return ctPreCheckAndPutAfterRowLock.get() > 0;
760   }
761 
762   public boolean hadPostCheckAndPut() {
763     return ctPostCheckAndPut.get() > 0;
764   }
765 
766   public boolean hadPreCheckAndDelete() {
767     return ctPreCheckAndDelete.get() > 0;
768   }
769 
770   public boolean hadPreCheckAndDeleteAfterRowLock() {
771     return ctPreCheckAndDeleteAfterRowLock.get() > 0;
772   }
773 
774   public boolean hadPostCheckAndDelete() {
775     return ctPostCheckAndDelete.get() > 0;
776   }
777 
778   public boolean hadPreIncrement() {
779     return ctPreIncrement.get() > 0;
780   }
781   
782   public boolean hadPreIncrementAfterRowLock() {
783     return ctPreIncrementAfterRowLock.get() > 0;
784   }
785 
786   public boolean hadPostIncrement() {
787     return ctPostIncrement.get() > 0;
788   }
789 
790   public boolean hadPreAppend() {
791     return ctPreAppend.get() > 0;
792   }
793 
794   public boolean hadPreAppendAfterRowLock() {
795     return ctPreAppendAfterRowLock.get() > 0;
796   }
797 
798   public boolean hadPostAppend() {
799     return ctPostAppend.get() > 0;
800   }
801 
802   public boolean hadPrePreparedDeleteTS() {
803     return ctPrePrepareDeleteTS.get() > 0;
804   }
805   
806   public boolean hadPreWALRestored() {
807     return ctPreWALRestored.get() > 0;
808   }
809 
810   public boolean hadPostWALRestored() {
811     return ctPostWALRestored.get() > 0;
812   }
813   public boolean wasScannerNextCalled() {
814     return ctPreScannerNext.get() > 0 && ctPostScannerNext.get() > 0;
815   }
816   public boolean wasScannerFilterRowCalled() {
817     return ctPostScannerFilterRow.get() > 0;
818   }
819   public boolean wasScannerCloseCalled() {
820     return ctPreScannerClose.get() > 0 && ctPostScannerClose.get() > 0;
821   }
822   public boolean wasScannerOpenCalled() {
823     return ctPreScannerOpen.get() > 0 && ctPostScannerOpen.get() > 0;
824   }
825   public boolean hadDeleted() {
826     return ctPreDeleted.get() > 0 && ctPostDeleted.get() > 0;
827   }
828 
829   public boolean hadPostBulkLoadHFile() {
830     return ctPostBulkLoadHFile.get() > 0;
831   }
832 
833   public boolean hadPreBulkLoadHFile() {
834     return ctPreBulkLoadHFile.get() > 0;
835   }
836 
837 
838   public int getCtBeforeDelete() {
839     return ctBeforeDelete.get();
840   }
841 
842   public int getCtPreOpen() {
843     return ctPreOpen.get();
844   }
845 
846   public int getCtPostOpen() {
847     return ctPostOpen.get();
848   }
849 
850   public int getCtPreClose() {
851     return ctPreClose.get();
852   }
853 
854   public int getCtPostClose() {
855     return ctPostClose.get();
856   }
857 
858   public int getCtPreFlush() {
859     return ctPreFlush.get();
860   }
861 
862   public int getCtPreFlushScannerOpen() {
863     return ctPreFlushScannerOpen.get();
864   }
865 
866   public int getCtPostFlush() {
867     return ctPostFlush.get();
868   }
869 
870   public int getCtPreSplit() {
871     return ctPreSplit.get();
872   }
873   
874   public int getCtPreSplitBeforePONR() {
875     return ctPreSplitBeforePONR.get();
876   }
877 
878   public int getCtPreSplitAfterPONR() {
879     return ctPreSplitAfterPONR.get();
880   }
881 
882   public int getCtPostSplit() {
883     return ctPostSplit.get();
884   }
885 
886   public int getCtPreCompactSelect() {
887     return ctPreCompactSelect.get();
888   }
889 
890   public int getCtPostCompactSelect() {
891     return ctPostCompactSelect.get();
892   }
893 
894   public int getCtPreCompactScanner() {
895     return ctPreCompactScanner.get();
896   }
897 
898   public int getCtPreCompact() {
899     return ctPreCompact.get();
900   }
901 
902   public int getCtPostCompact() {
903     return ctPostCompact.get();
904   }
905 
906   public int getCtPreGet() {
907     return ctPreGet.get();
908   }
909 
910   public int getCtPostGet() {
911     return ctPostGet.get();
912   }
913 
914   public int getCtPrePut() {
915     return ctPrePut.get();
916   }
917 
918   public int getCtPostPut() {
919     return ctPostPut.get();
920   }
921 
922   public int getCtPreDeleted() {
923     return ctPreDeleted.get();
924   }
925 
926   public int getCtPostDeleted() {
927     return ctPostDeleted.get();
928   }
929 
930   public int getCtPreGetClosestRowBefore() {
931     return ctPreGetClosestRowBefore.get();
932   }
933 
934   public int getCtPostGetClosestRowBefore() {
935     return ctPostGetClosestRowBefore.get();
936   }
937 
938   public int getCtPreIncrement() {
939     return ctPreIncrement.get();
940   }
941 
942   public int getCtPostIncrement() {
943     return ctPostIncrement.get();
944   }
945 
946   public int getCtPreWALRestore() {
947     return ctPreWALRestore.get();
948   }
949 
950   public int getCtPostWALRestore() {
951     return ctPostWALRestore.get();
952   }
953 
954   public boolean wasStoreFileReaderOpenCalled() {
955     return ctPreStoreFileReaderOpen.get() > 0 && ctPostStoreFileReaderOpen.get() > 0;
956   }
957 }