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