001/**
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 *     http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 */
019
020package org.apache.hadoop.hbase.coprocessor;
021
022import static org.junit.Assert.assertArrayEquals;
023import static org.junit.Assert.assertEquals;
024import static org.junit.Assert.assertNotNull;
025import static org.junit.Assert.assertTrue;
026
027import java.io.IOException;
028import java.util.List;
029import java.util.Map;
030import java.util.Optional;
031import java.util.concurrent.atomic.AtomicBoolean;
032import java.util.concurrent.atomic.AtomicInteger;
033
034import org.apache.hadoop.fs.FileSystem;
035import org.apache.hadoop.fs.Path;
036import org.apache.hadoop.hbase.Cell;
037import org.apache.hadoop.hbase.CellUtil;
038import org.apache.hadoop.hbase.CompareOperator;
039import org.apache.hadoop.hbase.CoprocessorEnvironment;
040import org.apache.hadoop.hbase.client.Append;
041import org.apache.hadoop.hbase.client.Delete;
042import org.apache.hadoop.hbase.client.Durability;
043import org.apache.hadoop.hbase.client.Get;
044import org.apache.hadoop.hbase.client.Increment;
045import org.apache.hadoop.hbase.client.Mutation;
046import org.apache.hadoop.hbase.client.Put;
047import org.apache.hadoop.hbase.client.RegionInfo;
048import org.apache.hadoop.hbase.client.Result;
049import org.apache.hadoop.hbase.client.Scan;
050import org.apache.hadoop.hbase.filter.ByteArrayComparable;
051import org.apache.hadoop.hbase.io.FSDataInputStreamWrapper;
052import org.apache.hadoop.hbase.io.Reference;
053import org.apache.hadoop.hbase.io.hfile.CacheConfig;
054import org.apache.hadoop.hbase.regionserver.FlushLifeCycleTracker;
055import org.apache.hadoop.hbase.regionserver.InternalScanner;
056import org.apache.hadoop.hbase.regionserver.MiniBatchOperationInProgress;
057import org.apache.hadoop.hbase.regionserver.Region.Operation;
058import org.apache.hadoop.hbase.regionserver.RegionScanner;
059import org.apache.hadoop.hbase.regionserver.ScanType;
060import org.apache.hadoop.hbase.regionserver.Store;
061import org.apache.hadoop.hbase.regionserver.StoreFile;
062import org.apache.hadoop.hbase.regionserver.StoreFileReader;
063import org.apache.hadoop.hbase.regionserver.compactions.CompactionLifeCycleTracker;
064import org.apache.hadoop.hbase.regionserver.compactions.CompactionRequest;
065import org.apache.hadoop.hbase.util.Bytes;
066import org.apache.hadoop.hbase.util.Pair;
067import org.apache.hadoop.hbase.wal.WALEdit;
068import org.apache.hadoop.hbase.wal.WALKey;
069
070/**
071 * A sample region observer that tests the RegionObserver interface.
072 * It works with TestRegionObserverInterface to provide the test case.
073 */
074public class SimpleRegionObserver implements RegionCoprocessor, RegionObserver {
075
076  final AtomicInteger ctBeforeDelete = new AtomicInteger(1);
077  final AtomicInteger ctPreOpen = new AtomicInteger(0);
078  final AtomicInteger ctPostOpen = new AtomicInteger(0);
079  final AtomicInteger ctPreClose = new AtomicInteger(0);
080  final AtomicInteger ctPostClose = new AtomicInteger(0);
081  final AtomicInteger ctPreFlush = new AtomicInteger(0);
082  final AtomicInteger ctPostFlush = new AtomicInteger(0);
083  final AtomicInteger ctPreCompactSelect = new AtomicInteger(0);
084  final AtomicInteger ctPostCompactSelect = new AtomicInteger(0);
085  final AtomicInteger ctPreCompact = new AtomicInteger(0);
086  final AtomicInteger ctPostCompact = new AtomicInteger(0);
087  final AtomicInteger ctPreGet = new AtomicInteger(0);
088  final AtomicInteger ctPostGet = new AtomicInteger(0);
089  final AtomicInteger ctPrePut = new AtomicInteger(0);
090  final AtomicInteger ctPostPut = new AtomicInteger(0);
091  final AtomicInteger ctPreDeleted = new AtomicInteger(0);
092  final AtomicInteger ctPrePrepareDeleteTS = new AtomicInteger(0);
093  final AtomicInteger ctPostDeleted = new AtomicInteger(0);
094  final AtomicInteger ctPreIncrement = new AtomicInteger(0);
095  final AtomicInteger ctPreIncrementAfterRowLock = new AtomicInteger(0);
096  final AtomicInteger ctPreAppend = new AtomicInteger(0);
097  final AtomicInteger ctPreAppendAfterRowLock = new AtomicInteger(0);
098  final AtomicInteger ctPostIncrement = new AtomicInteger(0);
099  final AtomicInteger ctPostAppend = new AtomicInteger(0);
100  final AtomicInteger ctPreCheckAndPut = new AtomicInteger(0);
101  final AtomicInteger ctPreCheckAndPutAfterRowLock = new AtomicInteger(0);
102  final AtomicInteger ctPostCheckAndPut = new AtomicInteger(0);
103  final AtomicInteger ctPreCheckAndDelete = new AtomicInteger(0);
104  final AtomicInteger ctPreCheckAndDeleteAfterRowLock = new AtomicInteger(0);
105  final AtomicInteger ctPostCheckAndDelete = new AtomicInteger(0);
106  final AtomicInteger ctPreScannerNext = new AtomicInteger(0);
107  final AtomicInteger ctPostScannerNext = new AtomicInteger(0);
108  final AtomicInteger ctPostScannerFilterRow = new AtomicInteger(0);
109  final AtomicInteger ctPreScannerClose = new AtomicInteger(0);
110  final AtomicInteger ctPostScannerClose = new AtomicInteger(0);
111  final AtomicInteger ctPreScannerOpen = 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 ctPreReplayWALs = new AtomicInteger(0);
118  final AtomicInteger ctPostReplayWALs = new AtomicInteger(0);
119  final AtomicInteger ctPreWALRestore = new AtomicInteger(0);
120  final AtomicInteger ctPostWALRestore = 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 Optional<RegionObserver> getRegionObserver() {
135    return Optional.of(this);
136  }
137
138  @Override
139  public void start(CoprocessorEnvironment e) throws IOException {
140  }
141
142  @Override
143  public void preOpen(ObserverContext<RegionCoprocessorEnvironment> c) {
144    ctPreOpen.incrementAndGet();
145  }
146
147  @Override
148  public void postOpen(ObserverContext<RegionCoprocessorEnvironment> c) {
149    ctPostOpen.incrementAndGet();
150  }
151
152  public boolean wasOpened() {
153    return ctPreOpen.get() > 0 && ctPostOpen.get() > 0;
154  }
155
156  @Override
157  public void preClose(ObserverContext<RegionCoprocessorEnvironment> c, boolean abortRequested) {
158    ctPreClose.incrementAndGet();
159  }
160
161  @Override
162  public void postClose(ObserverContext<RegionCoprocessorEnvironment> c, boolean abortRequested) {
163    ctPostClose.incrementAndGet();
164  }
165
166  public boolean wasClosed() {
167    return ctPreClose.get() > 0 && ctPostClose.get() > 0;
168  }
169
170  @Override
171  public InternalScanner preFlush(ObserverContext<RegionCoprocessorEnvironment> c,
172      Store store, InternalScanner scanner, FlushLifeCycleTracker tracker) throws IOException {
173    ctPreFlush.incrementAndGet();
174    return scanner;
175  }
176
177  @Override
178  public void postFlush(ObserverContext<RegionCoprocessorEnvironment> c,
179      Store store, StoreFile resultFile, FlushLifeCycleTracker tracker) throws IOException {
180    ctPostFlush.incrementAndGet();
181    if (throwOnPostFlush.get()){
182      throw new IOException("throwOnPostFlush is true in postFlush");
183    }
184  }
185
186  public boolean wasFlushed() {
187    return ctPreFlush.get() > 0 && ctPostFlush.get() > 0;
188  }
189
190  @Override
191  public void preCompactSelection(ObserverContext<RegionCoprocessorEnvironment> c, Store store,
192      List<? extends StoreFile> candidates, CompactionLifeCycleTracker tracker) throws IOException {
193    ctPreCompactSelect.incrementAndGet();
194  }
195
196  @Override
197  public void postCompactSelection(ObserverContext<RegionCoprocessorEnvironment> c, Store store,
198      List<? extends StoreFile> selected, CompactionLifeCycleTracker tracker,
199      CompactionRequest request) {
200    ctPostCompactSelect.incrementAndGet();
201  }
202
203  @Override
204  public InternalScanner preCompact(ObserverContext<RegionCoprocessorEnvironment> c, Store store,
205      InternalScanner scanner, ScanType scanType, CompactionLifeCycleTracker tracker,
206      CompactionRequest request) throws IOException {
207    ctPreCompact.incrementAndGet();
208    return scanner;
209  }
210
211  @Override
212  public void postCompact(ObserverContext<RegionCoprocessorEnvironment> c, Store store,
213      StoreFile resultFile, CompactionLifeCycleTracker tracker,
214      CompactionRequest request) throws IOException {
215    ctPostCompact.incrementAndGet();
216  }
217
218  public boolean wasCompacted() {
219    return ctPreCompact.get() > 0 && ctPostCompact.get() > 0;
220  }
221
222  @Override
223  public void preScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c, final Scan scan)
224      throws IOException {
225    ctPreScannerOpen.incrementAndGet();
226  }
227
228  @Override
229  public RegionScanner postScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c,
230      final Scan scan, final RegionScanner s)
231      throws IOException {
232    ctPostScannerOpen.incrementAndGet();
233    return s;
234  }
235
236  @Override
237  public boolean preScannerNext(final ObserverContext<RegionCoprocessorEnvironment> c,
238      final InternalScanner s, final List<Result> results,
239      final int limit, final boolean hasMore) throws IOException {
240    ctPreScannerNext.incrementAndGet();
241    return hasMore;
242  }
243
244  @Override
245  public boolean postScannerNext(final ObserverContext<RegionCoprocessorEnvironment> c,
246      final InternalScanner s, final List<Result> results, final int limit,
247      final boolean hasMore) throws IOException {
248    ctPostScannerNext.incrementAndGet();
249    return hasMore;
250  }
251
252  @Override
253  public boolean postScannerFilterRow(final ObserverContext<RegionCoprocessorEnvironment> e,
254      final InternalScanner s, final Cell currentRow, final boolean hasMore) throws IOException {
255    ctPostScannerFilterRow.incrementAndGet();
256    return hasMore;
257  }
258
259  @Override
260  public void preScannerClose(final ObserverContext<RegionCoprocessorEnvironment> c,
261      final InternalScanner s) throws IOException {
262    ctPreScannerClose.incrementAndGet();
263  }
264
265  @Override
266  public void postScannerClose(final ObserverContext<RegionCoprocessorEnvironment> c,
267      final InternalScanner s) throws IOException {
268    ctPostScannerClose.incrementAndGet();
269  }
270
271  @Override
272  public void preGetOp(final ObserverContext<RegionCoprocessorEnvironment> c, final Get get,
273      final List<Cell> results) throws IOException {
274    RegionCoprocessorEnvironment e = c.getEnvironment();
275    assertNotNull(e);
276    assertNotNull(e.getRegion());
277    assertNotNull(get);
278    assertNotNull(results);
279    ctPreGet.incrementAndGet();
280  }
281
282  @Override
283  public void postGetOp(final ObserverContext<RegionCoprocessorEnvironment> c, final Get get,
284      final List<Cell> results) {
285    RegionCoprocessorEnvironment e = c.getEnvironment();
286    assertNotNull(e);
287    assertNotNull(e.getRegion());
288    assertNotNull(get);
289    assertNotNull(results);
290    if (e.getRegion().getTableDescriptor().getTableName().equals(
291        TestRegionObserverInterface.TEST_TABLE)) {
292      boolean foundA = false;
293      boolean foundB = false;
294      boolean foundC = false;
295      for (Cell kv: results) {
296        if (CellUtil.matchingFamily(kv, TestRegionObserverInterface.A)) {
297          foundA = true;
298        }
299        if (CellUtil.matchingFamily(kv, TestRegionObserverInterface.B)) {
300          foundB = true;
301        }
302        if (CellUtil.matchingFamily(kv, TestRegionObserverInterface.C)) {
303          foundC = true;
304        }
305      }
306      assertTrue(foundA);
307      assertTrue(foundB);
308      assertTrue(foundC);
309    }
310    ctPostGet.incrementAndGet();
311  }
312
313  @Override
314  public void prePut(final ObserverContext<RegionCoprocessorEnvironment> c,
315      final Put put, final WALEdit edit,
316      final Durability durability) throws IOException {
317    Map<byte[], List<Cell>> familyMap  = put.getFamilyCellMap();
318    RegionCoprocessorEnvironment e = c.getEnvironment();
319    assertNotNull(e);
320    assertNotNull(e.getRegion());
321    assertNotNull(familyMap);
322    if (e.getRegion().getTableDescriptor().getTableName().equals(
323        TestRegionObserverInterface.TEST_TABLE)) {
324      List<Cell> cells = familyMap.get(TestRegionObserverInterface.A);
325      assertNotNull(cells);
326      assertNotNull(cells.get(0));
327      Cell cell = cells.get(0);
328      assertTrue(Bytes.equals(cell.getQualifierArray(), cell.getQualifierOffset(),
329        cell.getQualifierLength(), TestRegionObserverInterface.A, 0,
330        TestRegionObserverInterface.A.length));
331      cells = familyMap.get(TestRegionObserverInterface.B);
332      assertNotNull(cells);
333      assertNotNull(cells.get(0));
334      cell = cells.get(0);
335      assertTrue(Bytes.equals(cell.getQualifierArray(), cell.getQualifierOffset(),
336        cell.getQualifierLength(), TestRegionObserverInterface.B, 0,
337        TestRegionObserverInterface.B.length));
338      cells = familyMap.get(TestRegionObserverInterface.C);
339      assertNotNull(cells);
340      assertNotNull(cells.get(0));
341      cell = cells.get(0);
342      assertTrue(Bytes.equals(cell.getQualifierArray(), cell.getQualifierOffset(),
343        cell.getQualifierLength(), TestRegionObserverInterface.C, 0,
344        TestRegionObserverInterface.C.length));
345    }
346    ctPrePut.incrementAndGet();
347  }
348
349  @Override
350  public void postPut(final ObserverContext<RegionCoprocessorEnvironment> c,
351      final Put put, final WALEdit edit,
352      final Durability durability) throws IOException {
353    Map<byte[], List<Cell>> familyMap  = put.getFamilyCellMap();
354    RegionCoprocessorEnvironment e = c.getEnvironment();
355    assertNotNull(e);
356    assertNotNull(e.getRegion());
357    assertNotNull(familyMap);
358    List<Cell> cells = familyMap.get(TestRegionObserverInterface.A);
359    if (e.getRegion().getTableDescriptor().getTableName().equals(
360        TestRegionObserverInterface.TEST_TABLE)) {
361      assertNotNull(cells);
362      assertNotNull(cells.get(0));
363      // KeyValue v1 expectation.  Cast for now until we go all Cell all the time. TODO
364      Cell cell = cells.get(0);
365      assertTrue(Bytes.equals(cell.getQualifierArray(), cell.getQualifierOffset(),
366        cell.getQualifierLength(), TestRegionObserverInterface.A, 0,
367        TestRegionObserverInterface.A.length));
368      cells = familyMap.get(TestRegionObserverInterface.B);
369      assertNotNull(cells);
370      assertNotNull(cells.get(0));
371      // KeyValue v1 expectation.  Cast for now until we go all Cell all the time. TODO
372      cell = cells.get(0);
373      assertTrue(Bytes.equals(cell.getQualifierArray(), cell.getQualifierOffset(),
374        cell.getQualifierLength(), TestRegionObserverInterface.B, 0,
375        TestRegionObserverInterface.B.length));
376      cells = familyMap.get(TestRegionObserverInterface.C);
377      assertNotNull(cells);
378      assertNotNull(cells.get(0));
379      // KeyValue v1 expectation.  Cast for now until we go all Cell all the time. TODO
380      cell = cells.get(0);
381      assertTrue(Bytes.equals(cell.getQualifierArray(), cell.getQualifierOffset(),
382        cell.getQualifierLength(), TestRegionObserverInterface.C, 0,
383        TestRegionObserverInterface.C.length));
384    }
385    ctPostPut.incrementAndGet();
386  }
387
388  @Override
389  public void preDelete(final ObserverContext<RegionCoprocessorEnvironment> c,
390      final Delete delete, final WALEdit edit,
391      final Durability durability) throws IOException {
392    Map<byte[], List<Cell>> familyMap  = delete.getFamilyCellMap();
393    RegionCoprocessorEnvironment e = c.getEnvironment();
394    assertNotNull(e);
395    assertNotNull(e.getRegion());
396    assertNotNull(familyMap);
397    if (ctBeforeDelete.get() > 0) {
398      ctPreDeleted.incrementAndGet();
399    }
400  }
401
402  @Override
403  public void prePrepareTimeStampForDeleteVersion(ObserverContext<RegionCoprocessorEnvironment> e,
404      Mutation delete, Cell cell, byte[] byteNow, Get get) throws IOException {
405    ctPrePrepareDeleteTS.incrementAndGet();
406  }
407
408  @Override
409  public void postDelete(final ObserverContext<RegionCoprocessorEnvironment> c,
410      final Delete delete, final WALEdit edit,
411      final Durability durability) throws IOException {
412    Map<byte[], List<Cell>> familyMap  = delete.getFamilyCellMap();
413    RegionCoprocessorEnvironment e = c.getEnvironment();
414    assertNotNull(e);
415    assertNotNull(e.getRegion());
416    assertNotNull(familyMap);
417    ctBeforeDelete.set(0);
418    ctPostDeleted.incrementAndGet();
419  }
420
421  @Override
422  public void preBatchMutate(ObserverContext<RegionCoprocessorEnvironment> c,
423      MiniBatchOperationInProgress<Mutation> miniBatchOp) throws IOException {
424    RegionCoprocessorEnvironment e = c.getEnvironment();
425    assertNotNull(e);
426    assertNotNull(e.getRegion());
427    assertNotNull(miniBatchOp);
428    ctPreBatchMutate.incrementAndGet();
429  }
430
431  @Override
432  public void postBatchMutate(final ObserverContext<RegionCoprocessorEnvironment> c,
433      final MiniBatchOperationInProgress<Mutation> miniBatchOp) throws IOException {
434    RegionCoprocessorEnvironment e = c.getEnvironment();
435    assertNotNull(e);
436    assertNotNull(e.getRegion());
437    assertNotNull(miniBatchOp);
438    ctPostBatchMutate.incrementAndGet();
439  }
440
441  @Override
442  public void postStartRegionOperation(final ObserverContext<RegionCoprocessorEnvironment> ctx,
443      Operation op) throws IOException {
444    ctPostStartRegionOperation.incrementAndGet();
445  }
446
447  @Override
448  public void postCloseRegionOperation(final ObserverContext<RegionCoprocessorEnvironment> ctx,
449      Operation op) throws IOException {
450    if (ctPostStartRegionOperation.get() > 0) {
451      ctPostCloseRegionOperation.incrementAndGet();
452    }
453  }
454
455  @Override
456  public void postBatchMutateIndispensably(final ObserverContext<RegionCoprocessorEnvironment> ctx,
457      MiniBatchOperationInProgress<Mutation> miniBatchOp, final boolean success) throws IOException {
458    ctPostBatchMutateIndispensably.incrementAndGet();
459  }
460
461  @Override
462  public Result preIncrement(final ObserverContext<RegionCoprocessorEnvironment> c,
463      final Increment increment) throws IOException {
464    ctPreIncrement.incrementAndGet();
465    return null;
466  }
467
468  @Override
469  public Result preIncrementAfterRowLock(ObserverContext<RegionCoprocessorEnvironment> e,
470      Increment increment) throws IOException {
471    ctPreIncrementAfterRowLock.incrementAndGet();
472    return null;
473  }
474
475  @Override
476  public Result postIncrement(final ObserverContext<RegionCoprocessorEnvironment> c,
477      final Increment increment, final Result result) throws IOException {
478    ctPostIncrement.incrementAndGet();
479    return result;
480  }
481
482  @Override
483  public boolean preCheckAndPut(ObserverContext<RegionCoprocessorEnvironment> e, byte[] row,
484                                byte[] family, byte[] qualifier, CompareOperator compareOp, ByteArrayComparable comparator,
485                                Put put, boolean result) throws IOException {
486    ctPreCheckAndPut.incrementAndGet();
487    return true;
488  }
489
490  @Override
491  public boolean preCheckAndPutAfterRowLock(ObserverContext<RegionCoprocessorEnvironment> e,
492      byte[] row, byte[] family, byte[] qualifier, CompareOperator compareOp,
493      ByteArrayComparable comparator, Put put, boolean result) throws IOException {
494    ctPreCheckAndPutAfterRowLock.incrementAndGet();
495    return true;
496  }
497
498  @Override
499  public boolean postCheckAndPut(ObserverContext<RegionCoprocessorEnvironment> e, byte[] row,
500                                 byte[] family, byte[] qualifier, CompareOperator compareOp, ByteArrayComparable comparator,
501                                 Put put, boolean result) throws IOException {
502    ctPostCheckAndPut.incrementAndGet();
503    return true;
504  }
505
506  @Override
507  public boolean preCheckAndDelete(ObserverContext<RegionCoprocessorEnvironment> e, byte[] row,
508                                   byte[] family, byte[] qualifier, CompareOperator compareOp, ByteArrayComparable comparator,
509                                   Delete delete, boolean result) throws IOException {
510    ctPreCheckAndDelete.incrementAndGet();
511    return true;
512  }
513
514  @Override
515  public boolean preCheckAndDeleteAfterRowLock(ObserverContext<RegionCoprocessorEnvironment> e,
516      byte[] row, byte[] family, byte[] qualifier, CompareOperator compareOp,
517      ByteArrayComparable comparator, Delete delete, boolean result) throws IOException {
518    ctPreCheckAndDeleteAfterRowLock.incrementAndGet();
519    return true;
520  }
521
522  @Override
523  public boolean postCheckAndDelete(ObserverContext<RegionCoprocessorEnvironment> e, byte[] row,
524                                    byte[] family, byte[] qualifier, CompareOperator compareOp, ByteArrayComparable comparator,
525                                    Delete delete, boolean result) throws IOException {
526    ctPostCheckAndDelete.incrementAndGet();
527    return true;
528  }
529
530  @Override
531  public Result preAppendAfterRowLock(ObserverContext<RegionCoprocessorEnvironment> e,
532      Append append) throws IOException {
533    ctPreAppendAfterRowLock.incrementAndGet();
534    return null;
535  }
536
537  @Override
538  public Result preAppend(ObserverContext<RegionCoprocessorEnvironment> e, Append append)
539      throws IOException {
540    ctPreAppend.incrementAndGet();
541    return null;
542  }
543
544  @Override
545  public Result postAppend(ObserverContext<RegionCoprocessorEnvironment> e, Append append,
546      Result result) throws IOException {
547    ctPostAppend.incrementAndGet();
548    return null;
549  }
550
551  @Override
552  public void preBulkLoadHFile(ObserverContext<RegionCoprocessorEnvironment> ctx,
553                               List<Pair<byte[], String>> familyPaths) throws IOException {
554    RegionCoprocessorEnvironment e = ctx.getEnvironment();
555    assertNotNull(e);
556    assertNotNull(e.getRegion());
557    if (e.getRegion().getTableDescriptor().getTableName().equals(
558        TestRegionObserverInterface.TEST_TABLE)) {
559      assertNotNull(familyPaths);
560      assertEquals(1,familyPaths.size());
561      assertArrayEquals(TestRegionObserverInterface.A, familyPaths.get(0).getFirst());
562      String familyPath = familyPaths.get(0).getSecond();
563      String familyName = Bytes.toString(TestRegionObserverInterface.A);
564      assertEquals(familyPath.substring(familyPath.length()-familyName.length()-1),"/"+familyName);
565    }
566    ctPreBulkLoadHFile.incrementAndGet();
567  }
568
569  @Override
570  public void postBulkLoadHFile(ObserverContext<RegionCoprocessorEnvironment> ctx,
571      List<Pair<byte[], String>> familyPaths, Map<byte[], List<Path>> map)
572          throws IOException {
573    RegionCoprocessorEnvironment e = ctx.getEnvironment();
574    assertNotNull(e);
575    assertNotNull(e.getRegion());
576    if (e.getRegion().getTableDescriptor().getTableName().equals(
577        TestRegionObserverInterface.TEST_TABLE)) {
578      assertNotNull(familyPaths);
579      assertEquals(1,familyPaths.size());
580      assertArrayEquals(TestRegionObserverInterface.A, familyPaths.get(0).getFirst());
581      String familyPath = familyPaths.get(0).getSecond();
582      String familyName = Bytes.toString(TestRegionObserverInterface.A);
583      assertEquals(familyPath.substring(familyPath.length()-familyName.length()-1),"/"+familyName);
584    }
585    ctPostBulkLoadHFile.incrementAndGet();
586  }
587
588  @Override
589  public void preReplayWALs(ObserverContext<? extends RegionCoprocessorEnvironment> env,
590      RegionInfo info, Path edits) throws IOException {
591    ctPreReplayWALs.incrementAndGet();
592  }
593
594  @Override
595  public void postReplayWALs(ObserverContext<? extends RegionCoprocessorEnvironment> env,
596      RegionInfo info, Path edits) throws IOException {
597    ctPostReplayWALs.incrementAndGet();
598  }
599
600  @Override
601  public void preWALRestore(ObserverContext<? extends RegionCoprocessorEnvironment> env,
602      RegionInfo info, WALKey logKey, WALEdit logEdit) throws IOException {
603    String tableName = logKey.getTableName().getNameAsString();
604    if (tableName.equals(TABLE_SKIPPED)) {
605      // skip recovery of TABLE_SKIPPED for testing purpose
606      env.bypass();
607      return;
608    }
609    ctPreWALRestore.incrementAndGet();
610  }
611
612  @Override
613  public void postWALRestore(ObserverContext<? extends RegionCoprocessorEnvironment> env,
614                             RegionInfo info, WALKey logKey, WALEdit logEdit) throws IOException {
615    ctPostWALRestore.incrementAndGet();
616  }
617
618  @Override
619  public StoreFileReader preStoreFileReaderOpen(ObserverContext<RegionCoprocessorEnvironment> ctx,
620      FileSystem fs, Path p, FSDataInputStreamWrapper in, long size, CacheConfig cacheConf,
621      Reference r, StoreFileReader reader) throws IOException {
622    ctPreStoreFileReaderOpen.incrementAndGet();
623    return null;
624  }
625
626  @Override
627  public StoreFileReader postStoreFileReaderOpen(ObserverContext<RegionCoprocessorEnvironment> ctx,
628      FileSystem fs, Path p, FSDataInputStreamWrapper in, long size, CacheConfig cacheConf,
629      Reference r, StoreFileReader reader) throws IOException {
630    ctPostStoreFileReaderOpen.incrementAndGet();
631    return reader;
632  }
633
634  public boolean hadPreGet() {
635    return ctPreGet.get() > 0;
636  }
637
638  public boolean hadPostGet() {
639    return ctPostGet.get() > 0;
640  }
641
642  public boolean hadPrePut() {
643    return ctPrePut.get() > 0;
644  }
645
646  public boolean hadPostPut() {
647    return ctPostPut.get() > 0;
648  }
649
650  public boolean hadPreBatchMutate() {
651    return ctPreBatchMutate.get() > 0;
652  }
653
654  public boolean hadPostBatchMutate() {
655    return ctPostBatchMutate.get() > 0;
656  }
657
658  public boolean hadPostBatchMutateIndispensably() {
659    return ctPostBatchMutateIndispensably.get() > 0;
660  }
661
662  public boolean hadPostStartRegionOperation() {
663    return ctPostStartRegionOperation.get() > 0;
664  }
665
666  public boolean hadPostCloseRegionOperation() {
667    return ctPostCloseRegionOperation.get() > 0;
668  }
669
670  public boolean hadDelete() {
671    return !(ctBeforeDelete.get() > 0);
672  }
673
674  public int getCtPostStartRegionOperation() {
675    return ctPostStartRegionOperation.get();
676  }
677
678  public int getCtPostCloseRegionOperation() {
679    return ctPostCloseRegionOperation.get();
680  }
681
682  public boolean hadPreCheckAndPut() {
683    return ctPreCheckAndPut.get() > 0;
684  }
685
686  public boolean hadPreCheckAndPutAfterRowLock() {
687    return ctPreCheckAndPutAfterRowLock.get() > 0;
688  }
689
690  public boolean hadPostCheckAndPut() {
691    return ctPostCheckAndPut.get() > 0;
692  }
693
694  public boolean hadPreCheckAndDelete() {
695    return ctPreCheckAndDelete.get() > 0;
696  }
697
698  public boolean hadPreCheckAndDeleteAfterRowLock() {
699    return ctPreCheckAndDeleteAfterRowLock.get() > 0;
700  }
701
702  public boolean hadPostCheckAndDelete() {
703    return ctPostCheckAndDelete.get() > 0;
704  }
705
706  public boolean hadPreIncrement() {
707    return ctPreIncrement.get() > 0;
708  }
709
710  public boolean hadPreIncrementAfterRowLock() {
711    return ctPreIncrementAfterRowLock.get() > 0;
712  }
713
714  public boolean hadPostIncrement() {
715    return ctPostIncrement.get() > 0;
716  }
717
718  public boolean hadPreAppend() {
719    return ctPreAppend.get() > 0;
720  }
721
722  public boolean hadPreAppendAfterRowLock() {
723    return ctPreAppendAfterRowLock.get() > 0;
724  }
725
726  public boolean hadPostAppend() {
727    return ctPostAppend.get() > 0;
728  }
729
730  public boolean hadPrePreparedDeleteTS() {
731    return ctPrePrepareDeleteTS.get() > 0;
732  }
733
734  public boolean hadPreReplayWALs() {
735    return ctPreReplayWALs.get() > 0;
736  }
737
738  public boolean hadPostReplayWALs() {
739    return ctPostReplayWALs.get() > 0;
740  }
741
742  public boolean hadPreWALRestore() {
743    return ctPreWALRestore.get() > 0;
744  }
745
746  public boolean hadPostWALRestore() {
747    return ctPostWALRestore.get() > 0;
748  }
749
750  public boolean wasScannerNextCalled() {
751    return ctPreScannerNext.get() > 0 && ctPostScannerNext.get() > 0;
752  }
753  public boolean wasScannerFilterRowCalled() {
754    return ctPostScannerFilterRow.get() > 0;
755  }
756  public boolean wasScannerCloseCalled() {
757    return ctPreScannerClose.get() > 0 && ctPostScannerClose.get() > 0;
758  }
759  public boolean wasScannerOpenCalled() {
760    return ctPreScannerOpen.get() > 0 && ctPostScannerOpen.get() > 0;
761  }
762  public boolean hadDeleted() {
763    return ctPreDeleted.get() > 0 && ctPostDeleted.get() > 0;
764  }
765
766  public boolean hadPostBulkLoadHFile() {
767    return ctPostBulkLoadHFile.get() > 0;
768  }
769
770  public boolean hadPreBulkLoadHFile() {
771    return ctPreBulkLoadHFile.get() > 0;
772  }
773
774
775  public int getCtBeforeDelete() {
776    return ctBeforeDelete.get();
777  }
778
779  public int getCtPreOpen() {
780    return ctPreOpen.get();
781  }
782
783  public int getCtPostOpen() {
784    return ctPostOpen.get();
785  }
786
787  public int getCtPreClose() {
788    return ctPreClose.get();
789  }
790
791  public int getCtPostClose() {
792    return ctPostClose.get();
793  }
794
795  public int getCtPreFlush() {
796    return ctPreFlush.get();
797  }
798
799  public int getCtPostFlush() {
800    return ctPostFlush.get();
801  }
802
803  public int getCtPreCompactSelect() {
804    return ctPreCompactSelect.get();
805  }
806
807  public int getCtPostCompactSelect() {
808    return ctPostCompactSelect.get();
809  }
810
811  public int getCtPreCompact() {
812    return ctPreCompact.get();
813  }
814
815  public int getCtPostCompact() {
816    return ctPostCompact.get();
817  }
818
819  public int getCtPreGet() {
820    return ctPreGet.get();
821  }
822
823  public int getCtPostGet() {
824    return ctPostGet.get();
825  }
826
827  public int getCtPrePut() {
828    return ctPrePut.get();
829  }
830
831  public int getCtPostPut() {
832    return ctPostPut.get();
833  }
834
835  public int getCtPreDeleted() {
836    return ctPreDeleted.get();
837  }
838
839  public int getCtPostDeleted() {
840    return ctPostDeleted.get();
841  }
842
843  public int getCtPreIncrement() {
844    return ctPreIncrement.get();
845  }
846
847  public int getCtPostIncrement() {
848    return ctPostIncrement.get();
849  }
850
851  public int getCtPreReplayWALs() {
852    return ctPreReplayWALs.get();
853  }
854
855  public int getCtPostReplayWALs() {
856    return ctPostReplayWALs.get();
857  }
858
859  public int getCtPreWALRestore() {
860    return ctPreWALRestore.get();
861  }
862
863  public int getCtPostWALRestore() {
864    return ctPostWALRestore.get();
865  }
866
867  public boolean wasStoreFileReaderOpenCalled() {
868    return ctPreStoreFileReaderOpen.get() > 0 && ctPostStoreFileReaderOpen.get() > 0;
869  }
870}