001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.coprocessor; 019 020import static org.junit.Assert.assertArrayEquals; 021import static org.junit.Assert.assertEquals; 022import static org.junit.Assert.assertNotNull; 023import static org.junit.Assert.assertTrue; 024 025import java.io.IOException; 026import java.util.HashMap; 027import java.util.List; 028import java.util.Map; 029import java.util.Optional; 030import java.util.concurrent.atomic.AtomicBoolean; 031import java.util.concurrent.atomic.AtomicInteger; 032import org.apache.hadoop.fs.FileSystem; 033import org.apache.hadoop.fs.Path; 034import org.apache.hadoop.hbase.Cell; 035import org.apache.hadoop.hbase.CellUtil; 036import org.apache.hadoop.hbase.CompareOperator; 037import org.apache.hadoop.hbase.CoprocessorEnvironment; 038import org.apache.hadoop.hbase.KeepDeletedCells; 039import org.apache.hadoop.hbase.client.Append; 040import org.apache.hadoop.hbase.client.CheckAndMutate; 041import org.apache.hadoop.hbase.client.CheckAndMutateResult; 042import org.apache.hadoop.hbase.client.Delete; 043import org.apache.hadoop.hbase.client.Durability; 044import org.apache.hadoop.hbase.client.Get; 045import org.apache.hadoop.hbase.client.Increment; 046import org.apache.hadoop.hbase.client.Mutation; 047import org.apache.hadoop.hbase.client.Put; 048import org.apache.hadoop.hbase.client.RegionInfo; 049import org.apache.hadoop.hbase.client.Result; 050import org.apache.hadoop.hbase.client.Scan; 051import org.apache.hadoop.hbase.filter.ByteArrayComparable; 052import org.apache.hadoop.hbase.filter.Filter; 053import org.apache.hadoop.hbase.io.FSDataInputStreamWrapper; 054import org.apache.hadoop.hbase.io.Reference; 055import org.apache.hadoop.hbase.io.hfile.CacheConfig; 056import org.apache.hadoop.hbase.regionserver.FlushLifeCycleTracker; 057import org.apache.hadoop.hbase.regionserver.InternalScanner; 058import org.apache.hadoop.hbase.regionserver.MiniBatchOperationInProgress; 059import org.apache.hadoop.hbase.regionserver.Region.Operation; 060import org.apache.hadoop.hbase.regionserver.RegionScanner; 061import org.apache.hadoop.hbase.regionserver.ScanOptions; 062import org.apache.hadoop.hbase.regionserver.ScanType; 063import org.apache.hadoop.hbase.regionserver.Store; 064import org.apache.hadoop.hbase.regionserver.StoreFile; 065import org.apache.hadoop.hbase.regionserver.StoreFileReader; 066import org.apache.hadoop.hbase.regionserver.compactions.CompactionLifeCycleTracker; 067import org.apache.hadoop.hbase.regionserver.compactions.CompactionRequest; 068import org.apache.hadoop.hbase.util.Bytes; 069import org.apache.hadoop.hbase.util.Pair; 070import org.apache.hadoop.hbase.wal.WALEdit; 071import org.apache.hadoop.hbase.wal.WALKey; 072 073/** 074 * A sample region observer that tests the RegionObserver interface. It works with 075 * TestRegionObserverInterface to provide the test case. 076 */ 077public class SimpleRegionObserver implements RegionCoprocessor, RegionObserver { 078 079 final AtomicInteger ctBeforeDelete = new AtomicInteger(1); 080 final AtomicInteger ctPreOpen = new AtomicInteger(0); 081 final AtomicInteger ctPostOpen = new AtomicInteger(0); 082 final AtomicInteger ctPreClose = new AtomicInteger(0); 083 final AtomicInteger ctPostClose = new AtomicInteger(0); 084 final AtomicInteger ctPreFlush = new AtomicInteger(0); 085 final AtomicInteger ctPostFlush = new AtomicInteger(0); 086 final AtomicInteger ctPreCompactSelect = new AtomicInteger(0); 087 final AtomicInteger ctPostCompactSelect = new AtomicInteger(0); 088 final AtomicInteger ctPreCompact = new AtomicInteger(0); 089 final AtomicInteger ctPostCompact = new AtomicInteger(0); 090 final AtomicInteger ctPreGet = new AtomicInteger(0); 091 final AtomicInteger ctPostGet = new AtomicInteger(0); 092 final AtomicInteger ctPrePut = new AtomicInteger(0); 093 final AtomicInteger ctPostPut = new AtomicInteger(0); 094 final AtomicInteger ctPreDeleted = new AtomicInteger(0); 095 final AtomicInteger ctPrePrepareDeleteTS = new AtomicInteger(0); 096 final AtomicInteger ctPostDeleted = new AtomicInteger(0); 097 final AtomicInteger ctPreIncrement = new AtomicInteger(0); 098 final AtomicInteger ctPreIncrementAfterRowLock = new AtomicInteger(0); 099 final AtomicInteger ctPreAppend = new AtomicInteger(0); 100 final AtomicInteger ctPreAppendAfterRowLock = new AtomicInteger(0); 101 final AtomicInteger ctPostIncrement = new AtomicInteger(0); 102 final AtomicInteger ctPostAppend = new AtomicInteger(0); 103 final AtomicInteger ctPreCheckAndPut = new AtomicInteger(0); 104 final AtomicInteger ctPreCheckAndPutWithFilter = new AtomicInteger(0); 105 final AtomicInteger ctPreCheckAndPutAfterRowLock = new AtomicInteger(0); 106 final AtomicInteger ctPreCheckAndPutWithFilterAfterRowLock = new AtomicInteger(0); 107 final AtomicInteger ctPostCheckAndPut = new AtomicInteger(0); 108 final AtomicInteger ctPostCheckAndPutWithFilter = new AtomicInteger(0); 109 final AtomicInteger ctPreCheckAndDelete = new AtomicInteger(0); 110 final AtomicInteger ctPreCheckAndDeleteWithFilter = new AtomicInteger(0); 111 final AtomicInteger ctPreCheckAndDeleteAfterRowLock = new AtomicInteger(0); 112 final AtomicInteger ctPreCheckAndDeleteWithFilterAfterRowLock = new AtomicInteger(0); 113 final AtomicInteger ctPostCheckAndDelete = new AtomicInteger(0); 114 final AtomicInteger ctPostCheckAndDeleteWithFilter = new AtomicInteger(0); 115 final AtomicInteger ctPreCheckAndMutate = new AtomicInteger(0); 116 final AtomicInteger ctPreCheckAndMutateAfterRowLock = new AtomicInteger(0); 117 final AtomicInteger ctPostCheckAndMutate = new AtomicInteger(0); 118 final AtomicInteger ctPreScannerNext = new AtomicInteger(0); 119 final AtomicInteger ctPostScannerNext = new AtomicInteger(0); 120 final AtomicInteger ctPostScannerFilterRow = new AtomicInteger(0); 121 final AtomicInteger ctPreScannerClose = new AtomicInteger(0); 122 final AtomicInteger ctPostScannerClose = new AtomicInteger(0); 123 final AtomicInteger ctPreScannerOpen = new AtomicInteger(0); 124 final AtomicInteger ctPostScannerOpen = new AtomicInteger(0); 125 final AtomicInteger ctPreBulkLoadHFile = new AtomicInteger(0); 126 final AtomicInteger ctPostBulkLoadHFile = new AtomicInteger(0); 127 final AtomicInteger ctPreBatchMutate = new AtomicInteger(0); 128 final AtomicInteger ctPostBatchMutate = new AtomicInteger(0); 129 final AtomicInteger ctPreReplayWALs = new AtomicInteger(0); 130 final AtomicInteger ctPostReplayWALs = new AtomicInteger(0); 131 final AtomicInteger ctPreWALRestore = new AtomicInteger(0); 132 final AtomicInteger ctPostWALRestore = new AtomicInteger(0); 133 final AtomicInteger ctPreStoreFileReaderOpen = new AtomicInteger(0); 134 final AtomicInteger ctPostStoreFileReaderOpen = new AtomicInteger(0); 135 final AtomicInteger ctPostBatchMutateIndispensably = new AtomicInteger(0); 136 final AtomicInteger ctPostStartRegionOperation = new AtomicInteger(0); 137 final AtomicInteger ctPostCloseRegionOperation = new AtomicInteger(0); 138 final AtomicBoolean throwOnPostFlush = new AtomicBoolean(false); 139 final AtomicInteger ctPreWALAppend = new AtomicInteger(0); 140 141 static final String TABLE_SKIPPED = "SKIPPED_BY_PREWALRESTORE"; 142 Map<String, byte[]> extendedAttributes = new HashMap<String, byte[]>(); 143 static final byte[] WAL_EXTENDED_ATTRIBUTE_BYTES = Bytes.toBytes("foo"); 144 145 public void setThrowOnPostFlush(Boolean val) { 146 throwOnPostFlush.set(val); 147 } 148 149 @Override 150 public Optional<RegionObserver> getRegionObserver() { 151 return Optional.of(this); 152 } 153 154 @Override 155 public void start(CoprocessorEnvironment e) throws IOException { 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, Store store, 188 InternalScanner scanner, FlushLifeCycleTracker tracker) throws IOException { 189 ctPreFlush.incrementAndGet(); 190 return scanner; 191 } 192 193 @Override 194 public void postFlush(ObserverContext<RegionCoprocessorEnvironment> c, Store store, 195 StoreFile resultFile, FlushLifeCycleTracker tracker) throws IOException { 196 ctPostFlush.incrementAndGet(); 197 if (throwOnPostFlush.get()) { 198 throw new IOException("throwOnPostFlush is true in postFlush"); 199 } 200 } 201 202 public boolean wasFlushed() { 203 return ctPreFlush.get() > 0 && ctPostFlush.get() > 0; 204 } 205 206 @Override 207 public void preCompactSelection(ObserverContext<RegionCoprocessorEnvironment> c, Store store, 208 List<? extends StoreFile> candidates, CompactionLifeCycleTracker tracker) throws IOException { 209 ctPreCompactSelect.incrementAndGet(); 210 } 211 212 @Override 213 public void postCompactSelection(ObserverContext<RegionCoprocessorEnvironment> c, Store store, 214 List<? extends StoreFile> selected, CompactionLifeCycleTracker tracker, 215 CompactionRequest request) { 216 ctPostCompactSelect.incrementAndGet(); 217 } 218 219 @Override 220 public InternalScanner preCompact(ObserverContext<RegionCoprocessorEnvironment> c, Store store, 221 InternalScanner scanner, ScanType scanType, CompactionLifeCycleTracker tracker, 222 CompactionRequest request) throws IOException { 223 ctPreCompact.incrementAndGet(); 224 return scanner; 225 } 226 227 @Override 228 public void postCompact(ObserverContext<RegionCoprocessorEnvironment> c, Store store, 229 StoreFile resultFile, CompactionLifeCycleTracker tracker, CompactionRequest request) 230 throws IOException { 231 ctPostCompact.incrementAndGet(); 232 } 233 234 public boolean wasCompacted() { 235 return ctPreCompact.get() > 0 && ctPostCompact.get() > 0; 236 } 237 238 @Override 239 public void preScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c, final Scan scan) 240 throws IOException { 241 ctPreScannerOpen.incrementAndGet(); 242 } 243 244 @Override 245 public RegionScanner postScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c, 246 final Scan scan, final RegionScanner s) throws IOException { 247 ctPostScannerOpen.incrementAndGet(); 248 return s; 249 } 250 251 @Override 252 public boolean preScannerNext(final ObserverContext<RegionCoprocessorEnvironment> c, 253 final InternalScanner s, final List<Result> results, final int limit, final boolean hasMore) 254 throws IOException { 255 ctPreScannerNext.incrementAndGet(); 256 return hasMore; 257 } 258 259 @Override 260 public boolean postScannerNext(final ObserverContext<RegionCoprocessorEnvironment> c, 261 final InternalScanner s, final List<Result> results, final int limit, final boolean hasMore) 262 throws IOException { 263 ctPostScannerNext.incrementAndGet(); 264 return hasMore; 265 } 266 267 @Override 268 public boolean postScannerFilterRow(final ObserverContext<RegionCoprocessorEnvironment> e, 269 final InternalScanner s, final Cell currentRow, final boolean hasMore) throws IOException { 270 ctPostScannerFilterRow.incrementAndGet(); 271 return hasMore; 272 } 273 274 @Override 275 public void preScannerClose(final ObserverContext<RegionCoprocessorEnvironment> c, 276 final InternalScanner s) throws IOException { 277 ctPreScannerClose.incrementAndGet(); 278 } 279 280 @Override 281 public void postScannerClose(final ObserverContext<RegionCoprocessorEnvironment> c, 282 final InternalScanner s) throws IOException { 283 ctPostScannerClose.incrementAndGet(); 284 } 285 286 @Override 287 public void preGetOp(final ObserverContext<RegionCoprocessorEnvironment> c, final Get get, 288 final List<Cell> results) throws IOException { 289 RegionCoprocessorEnvironment e = c.getEnvironment(); 290 assertNotNull(e); 291 assertNotNull(e.getRegion()); 292 assertNotNull(get); 293 assertNotNull(results); 294 ctPreGet.incrementAndGet(); 295 } 296 297 @Override 298 public void postGetOp(final ObserverContext<RegionCoprocessorEnvironment> c, final Get get, 299 final List<Cell> results) { 300 RegionCoprocessorEnvironment e = c.getEnvironment(); 301 assertNotNull(e); 302 assertNotNull(e.getRegion()); 303 assertNotNull(get); 304 assertNotNull(results); 305 if ( 306 e.getRegion().getTableDescriptor().getTableName() 307 .equals(TestRegionObserverInterface.TEST_TABLE) 308 ) { 309 boolean foundA = false; 310 boolean foundB = false; 311 boolean foundC = false; 312 for (Cell kv : results) { 313 if (CellUtil.matchingFamily(kv, TestRegionObserverInterface.A)) { 314 foundA = true; 315 } 316 if (CellUtil.matchingFamily(kv, TestRegionObserverInterface.B)) { 317 foundB = true; 318 } 319 if (CellUtil.matchingFamily(kv, TestRegionObserverInterface.C)) { 320 foundC = true; 321 } 322 } 323 assertTrue(foundA); 324 assertTrue(foundB); 325 assertTrue(foundC); 326 } 327 ctPostGet.incrementAndGet(); 328 } 329 330 @Override 331 public void prePut(final ObserverContext<RegionCoprocessorEnvironment> c, final Put put, 332 final WALEdit edit, final Durability durability) throws IOException { 333 Map<byte[], List<Cell>> familyMap = put.getFamilyCellMap(); 334 RegionCoprocessorEnvironment e = c.getEnvironment(); 335 assertNotNull(e); 336 assertNotNull(e.getRegion()); 337 assertNotNull(familyMap); 338 if ( 339 e.getRegion().getTableDescriptor().getTableName() 340 .equals(TestRegionObserverInterface.TEST_TABLE) 341 ) { 342 List<Cell> cells = familyMap.get(TestRegionObserverInterface.A); 343 assertNotNull(cells); 344 assertNotNull(cells.get(0)); 345 Cell cell = cells.get(0); 346 assertTrue( 347 Bytes.equals(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength(), 348 TestRegionObserverInterface.A, 0, TestRegionObserverInterface.A.length)); 349 cells = familyMap.get(TestRegionObserverInterface.B); 350 assertNotNull(cells); 351 assertNotNull(cells.get(0)); 352 cell = cells.get(0); 353 assertTrue( 354 Bytes.equals(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength(), 355 TestRegionObserverInterface.B, 0, TestRegionObserverInterface.B.length)); 356 cells = familyMap.get(TestRegionObserverInterface.C); 357 assertNotNull(cells); 358 assertNotNull(cells.get(0)); 359 cell = cells.get(0); 360 assertTrue( 361 Bytes.equals(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength(), 362 TestRegionObserverInterface.C, 0, TestRegionObserverInterface.C.length)); 363 } 364 ctPrePut.incrementAndGet(); 365 } 366 367 @Override 368 public void postPut(final ObserverContext<RegionCoprocessorEnvironment> c, final Put put, 369 final WALEdit edit, final Durability durability) throws IOException { 370 Map<byte[], List<Cell>> familyMap = put.getFamilyCellMap(); 371 RegionCoprocessorEnvironment e = c.getEnvironment(); 372 assertNotNull(e); 373 assertNotNull(e.getRegion()); 374 assertNotNull(familyMap); 375 List<Cell> cells = familyMap.get(TestRegionObserverInterface.A); 376 if ( 377 e.getRegion().getTableDescriptor().getTableName() 378 .equals(TestRegionObserverInterface.TEST_TABLE) 379 ) { 380 assertNotNull(cells); 381 assertNotNull(cells.get(0)); 382 // KeyValue v1 expectation. Cast for now until we go all Cell all the time. TODO 383 Cell cell = cells.get(0); 384 assertTrue( 385 Bytes.equals(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength(), 386 TestRegionObserverInterface.A, 0, TestRegionObserverInterface.A.length)); 387 cells = familyMap.get(TestRegionObserverInterface.B); 388 assertNotNull(cells); 389 assertNotNull(cells.get(0)); 390 // KeyValue v1 expectation. Cast for now until we go all Cell all the time. TODO 391 cell = cells.get(0); 392 assertTrue( 393 Bytes.equals(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength(), 394 TestRegionObserverInterface.B, 0, TestRegionObserverInterface.B.length)); 395 cells = familyMap.get(TestRegionObserverInterface.C); 396 assertNotNull(cells); 397 assertNotNull(cells.get(0)); 398 // KeyValue v1 expectation. Cast for now until we go all Cell all the time. TODO 399 cell = cells.get(0); 400 assertTrue( 401 Bytes.equals(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength(), 402 TestRegionObserverInterface.C, 0, TestRegionObserverInterface.C.length)); 403 } 404 ctPostPut.incrementAndGet(); 405 } 406 407 @Override 408 public void preDelete(final ObserverContext<RegionCoprocessorEnvironment> c, final Delete delete, 409 final WALEdit edit, final Durability durability) throws IOException { 410 Map<byte[], List<Cell>> familyMap = delete.getFamilyCellMap(); 411 RegionCoprocessorEnvironment e = c.getEnvironment(); 412 assertNotNull(e); 413 assertNotNull(e.getRegion()); 414 assertNotNull(familyMap); 415 if (ctBeforeDelete.get() > 0) { 416 ctPreDeleted.incrementAndGet(); 417 } 418 } 419 420 @Override 421 public void prePrepareTimeStampForDeleteVersion(ObserverContext<RegionCoprocessorEnvironment> e, 422 Mutation delete, Cell cell, byte[] byteNow, Get get) throws IOException { 423 ctPrePrepareDeleteTS.incrementAndGet(); 424 } 425 426 @Override 427 public void postDelete(final ObserverContext<RegionCoprocessorEnvironment> c, final Delete delete, 428 final WALEdit edit, final Durability durability) throws IOException { 429 Map<byte[], List<Cell>> familyMap = delete.getFamilyCellMap(); 430 RegionCoprocessorEnvironment e = c.getEnvironment(); 431 assertNotNull(e); 432 assertNotNull(e.getRegion()); 433 assertNotNull(familyMap); 434 ctBeforeDelete.set(0); 435 ctPostDeleted.incrementAndGet(); 436 } 437 438 @Override 439 public void preBatchMutate(ObserverContext<RegionCoprocessorEnvironment> c, 440 MiniBatchOperationInProgress<Mutation> miniBatchOp) throws IOException { 441 RegionCoprocessorEnvironment e = c.getEnvironment(); 442 assertNotNull(e); 443 assertNotNull(e.getRegion()); 444 assertNotNull(miniBatchOp); 445 ctPreBatchMutate.incrementAndGet(); 446 } 447 448 @Override 449 public void postBatchMutate(final ObserverContext<RegionCoprocessorEnvironment> c, 450 final MiniBatchOperationInProgress<Mutation> miniBatchOp) throws IOException { 451 RegionCoprocessorEnvironment e = c.getEnvironment(); 452 assertNotNull(e); 453 assertNotNull(e.getRegion()); 454 assertNotNull(miniBatchOp); 455 ctPostBatchMutate.incrementAndGet(); 456 } 457 458 @Override 459 public void postStartRegionOperation(final ObserverContext<RegionCoprocessorEnvironment> ctx, 460 Operation op) throws IOException { 461 ctPostStartRegionOperation.incrementAndGet(); 462 } 463 464 @Override 465 public void postCloseRegionOperation(final ObserverContext<RegionCoprocessorEnvironment> ctx, 466 Operation op) throws IOException { 467 if (ctPostStartRegionOperation.get() > 0) { 468 ctPostCloseRegionOperation.incrementAndGet(); 469 } 470 } 471 472 @Override 473 public void postBatchMutateIndispensably(final ObserverContext<RegionCoprocessorEnvironment> ctx, 474 MiniBatchOperationInProgress<Mutation> miniBatchOp, final boolean success) throws IOException { 475 ctPostBatchMutateIndispensably.incrementAndGet(); 476 } 477 478 @Override 479 public Result preIncrement(final ObserverContext<RegionCoprocessorEnvironment> c, 480 final Increment increment) throws IOException { 481 ctPreIncrement.incrementAndGet(); 482 return null; 483 } 484 485 @Override 486 public Result preIncrementAfterRowLock(ObserverContext<RegionCoprocessorEnvironment> e, 487 Increment increment) throws IOException { 488 ctPreIncrementAfterRowLock.incrementAndGet(); 489 return null; 490 } 491 492 @Override 493 public Result postIncrement(final ObserverContext<RegionCoprocessorEnvironment> c, 494 final Increment increment, final Result result) throws IOException { 495 ctPostIncrement.incrementAndGet(); 496 return result; 497 } 498 499 @Override 500 public boolean preCheckAndPut(ObserverContext<RegionCoprocessorEnvironment> e, byte[] row, 501 byte[] family, byte[] qualifier, CompareOperator compareOp, ByteArrayComparable comparator, 502 Put put, boolean result) throws IOException { 503 ctPreCheckAndPut.incrementAndGet(); 504 return true; 505 } 506 507 @Override 508 public boolean preCheckAndPut(ObserverContext<RegionCoprocessorEnvironment> c, byte[] row, 509 Filter filter, Put put, boolean result) throws IOException { 510 ctPreCheckAndPutWithFilter.incrementAndGet(); 511 return true; 512 } 513 514 @Override 515 public boolean preCheckAndPutAfterRowLock(ObserverContext<RegionCoprocessorEnvironment> e, 516 byte[] row, byte[] family, byte[] qualifier, CompareOperator compareOp, 517 ByteArrayComparable comparator, Put put, boolean result) throws IOException { 518 ctPreCheckAndPutAfterRowLock.incrementAndGet(); 519 return true; 520 } 521 522 @Override 523 public boolean preCheckAndPutAfterRowLock(ObserverContext<RegionCoprocessorEnvironment> c, 524 byte[] row, Filter filter, Put put, boolean result) throws IOException { 525 ctPreCheckAndPutWithFilterAfterRowLock.incrementAndGet(); 526 return true; 527 } 528 529 @Override 530 public boolean postCheckAndPut(ObserverContext<RegionCoprocessorEnvironment> e, byte[] row, 531 byte[] family, byte[] qualifier, CompareOperator compareOp, ByteArrayComparable comparator, 532 Put put, boolean result) throws IOException { 533 ctPostCheckAndPut.incrementAndGet(); 534 return true; 535 } 536 537 @Override 538 public boolean postCheckAndPut(ObserverContext<RegionCoprocessorEnvironment> c, byte[] row, 539 Filter filter, Put put, boolean result) throws IOException { 540 ctPostCheckAndPutWithFilter.incrementAndGet(); 541 return true; 542 } 543 544 @Override 545 public boolean preCheckAndDelete(ObserverContext<RegionCoprocessorEnvironment> e, byte[] row, 546 byte[] family, byte[] qualifier, CompareOperator compareOp, ByteArrayComparable comparator, 547 Delete delete, boolean result) throws IOException { 548 ctPreCheckAndDelete.incrementAndGet(); 549 return true; 550 } 551 552 @Override 553 public boolean preCheckAndDelete(ObserverContext<RegionCoprocessorEnvironment> c, byte[] row, 554 Filter filter, Delete delete, boolean result) throws IOException { 555 ctPreCheckAndDeleteWithFilter.incrementAndGet(); 556 return true; 557 } 558 559 @Override 560 public boolean preCheckAndDeleteAfterRowLock(ObserverContext<RegionCoprocessorEnvironment> e, 561 byte[] row, byte[] family, byte[] qualifier, CompareOperator compareOp, 562 ByteArrayComparable comparator, Delete delete, boolean result) throws IOException { 563 ctPreCheckAndDeleteAfterRowLock.incrementAndGet(); 564 return true; 565 } 566 567 @Override 568 public boolean preCheckAndDeleteAfterRowLock(ObserverContext<RegionCoprocessorEnvironment> c, 569 byte[] row, Filter filter, Delete delete, boolean result) throws IOException { 570 ctPreCheckAndDeleteWithFilterAfterRowLock.incrementAndGet(); 571 return true; 572 } 573 574 @Override 575 public boolean postCheckAndDelete(ObserverContext<RegionCoprocessorEnvironment> e, byte[] row, 576 byte[] family, byte[] qualifier, CompareOperator compareOp, ByteArrayComparable comparator, 577 Delete delete, boolean result) throws IOException { 578 ctPostCheckAndDelete.incrementAndGet(); 579 return true; 580 } 581 582 @Override 583 public boolean postCheckAndDelete(ObserverContext<RegionCoprocessorEnvironment> e, byte[] row, 584 Filter filter, Delete delete, boolean result) throws IOException { 585 ctPostCheckAndDeleteWithFilter.incrementAndGet(); 586 return true; 587 } 588 589 @Override 590 public CheckAndMutateResult preCheckAndMutate(ObserverContext<RegionCoprocessorEnvironment> c, 591 CheckAndMutate checkAndMutate, CheckAndMutateResult result) throws IOException { 592 ctPreCheckAndMutate.incrementAndGet(); 593 return RegionObserver.super.preCheckAndMutate(c, checkAndMutate, result); 594 } 595 596 @Override 597 public CheckAndMutateResult preCheckAndMutateAfterRowLock( 598 ObserverContext<RegionCoprocessorEnvironment> c, CheckAndMutate checkAndMutate, 599 CheckAndMutateResult result) throws IOException { 600 ctPreCheckAndMutateAfterRowLock.incrementAndGet(); 601 return RegionObserver.super.preCheckAndMutateAfterRowLock(c, checkAndMutate, result); 602 } 603 604 @Override 605 public CheckAndMutateResult postCheckAndMutate(ObserverContext<RegionCoprocessorEnvironment> c, 606 CheckAndMutate checkAndMutate, CheckAndMutateResult result) throws IOException { 607 ctPostCheckAndMutate.incrementAndGet(); 608 return RegionObserver.super.postCheckAndMutate(c, checkAndMutate, result); 609 } 610 611 @Override 612 public Result preAppendAfterRowLock(ObserverContext<RegionCoprocessorEnvironment> e, 613 Append append) throws IOException { 614 ctPreAppendAfterRowLock.incrementAndGet(); 615 return null; 616 } 617 618 @Override 619 public Result preAppend(ObserverContext<RegionCoprocessorEnvironment> e, Append append) 620 throws IOException { 621 ctPreAppend.incrementAndGet(); 622 return null; 623 } 624 625 @Override 626 public Result postAppend(ObserverContext<RegionCoprocessorEnvironment> e, Append append, 627 Result result) throws IOException { 628 ctPostAppend.incrementAndGet(); 629 return null; 630 } 631 632 @Override 633 public void preBulkLoadHFile(ObserverContext<RegionCoprocessorEnvironment> ctx, 634 List<Pair<byte[], String>> familyPaths) throws IOException { 635 RegionCoprocessorEnvironment e = ctx.getEnvironment(); 636 assertNotNull(e); 637 assertNotNull(e.getRegion()); 638 if ( 639 e.getRegion().getTableDescriptor().getTableName() 640 .equals(TestRegionObserverInterface.TEST_TABLE) 641 ) { 642 assertNotNull(familyPaths); 643 assertEquals(1, familyPaths.size()); 644 assertArrayEquals(TestRegionObserverInterface.A, familyPaths.get(0).getFirst()); 645 String familyPath = familyPaths.get(0).getSecond(); 646 String familyName = Bytes.toString(TestRegionObserverInterface.A); 647 assertEquals(familyPath.substring(familyPath.length() - familyName.length() - 1), 648 "/" + familyName); 649 } 650 ctPreBulkLoadHFile.incrementAndGet(); 651 } 652 653 @Override 654 public void postBulkLoadHFile(ObserverContext<RegionCoprocessorEnvironment> ctx, 655 List<Pair<byte[], String>> familyPaths, Map<byte[], List<Path>> map) throws IOException { 656 RegionCoprocessorEnvironment e = ctx.getEnvironment(); 657 assertNotNull(e); 658 assertNotNull(e.getRegion()); 659 if ( 660 e.getRegion().getTableDescriptor().getTableName() 661 .equals(TestRegionObserverInterface.TEST_TABLE) 662 ) { 663 assertNotNull(familyPaths); 664 assertEquals(1, familyPaths.size()); 665 assertArrayEquals(TestRegionObserverInterface.A, familyPaths.get(0).getFirst()); 666 String familyPath = familyPaths.get(0).getSecond(); 667 String familyName = Bytes.toString(TestRegionObserverInterface.A); 668 assertEquals(familyPath.substring(familyPath.length() - familyName.length() - 1), 669 "/" + familyName); 670 } 671 ctPostBulkLoadHFile.incrementAndGet(); 672 } 673 674 @Override 675 public void preReplayWALs(ObserverContext<? extends RegionCoprocessorEnvironment> env, 676 RegionInfo info, Path edits) throws IOException { 677 ctPreReplayWALs.incrementAndGet(); 678 } 679 680 @Override 681 public void postReplayWALs(ObserverContext<? extends RegionCoprocessorEnvironment> env, 682 RegionInfo info, Path edits) throws IOException { 683 ctPostReplayWALs.incrementAndGet(); 684 } 685 686 @Override 687 public void preWALRestore(ObserverContext<? extends RegionCoprocessorEnvironment> env, 688 RegionInfo info, WALKey logKey, WALEdit logEdit) throws IOException { 689 String tableName = logKey.getTableName().getNameAsString(); 690 if (tableName.equals(TABLE_SKIPPED)) { 691 // skip recovery of TABLE_SKIPPED for testing purpose 692 env.bypass(); 693 return; 694 } 695 ctPreWALRestore.incrementAndGet(); 696 } 697 698 @Override 699 public void postWALRestore(ObserverContext<? extends RegionCoprocessorEnvironment> env, 700 RegionInfo info, WALKey logKey, WALEdit logEdit) throws IOException { 701 ctPostWALRestore.incrementAndGet(); 702 } 703 704 @Override 705 public StoreFileReader preStoreFileReaderOpen(ObserverContext<RegionCoprocessorEnvironment> ctx, 706 FileSystem fs, Path p, FSDataInputStreamWrapper in, long size, CacheConfig cacheConf, 707 Reference r, StoreFileReader reader) throws IOException { 708 ctPreStoreFileReaderOpen.incrementAndGet(); 709 return null; 710 } 711 712 @Override 713 public StoreFileReader postStoreFileReaderOpen(ObserverContext<RegionCoprocessorEnvironment> ctx, 714 FileSystem fs, Path p, FSDataInputStreamWrapper in, long size, CacheConfig cacheConf, 715 Reference r, StoreFileReader reader) throws IOException { 716 ctPostStoreFileReaderOpen.incrementAndGet(); 717 return reader; 718 } 719 720 @Override 721 public void preStoreScannerOpen(ObserverContext<RegionCoprocessorEnvironment> ctx, Store store, 722 ScanOptions options) throws IOException { 723 if (options.getScan().getTimeRange().isAllTime()) { 724 setScanOptions(options); 725 } 726 } 727 728 @Override 729 public void preCompactScannerOpen(ObserverContext<RegionCoprocessorEnvironment> c, Store store, 730 ScanType scanType, ScanOptions options, CompactionLifeCycleTracker tracker, 731 CompactionRequest request) throws IOException { 732 setScanOptions(options); 733 } 734 735 public void preFlushScannerOpen(ObserverContext<RegionCoprocessorEnvironment> c, Store store, 736 ScanOptions options, FlushLifeCycleTracker tracker) throws IOException { 737 setScanOptions(options); 738 } 739 740 public void preMemStoreCompactionCompactScannerOpen( 741 ObserverContext<RegionCoprocessorEnvironment> c, Store store, ScanOptions options) 742 throws IOException { 743 setScanOptions(options); 744 } 745 746 private void setScanOptions(ScanOptions options) { 747 options.setMaxVersions(TestRegionCoprocessorHost.MAX_VERSIONS); 748 options.setMinVersions(TestRegionCoprocessorHost.MIN_VERSIONS); 749 options.setKeepDeletedCells(KeepDeletedCells.TRUE); 750 options.setTTL(TestRegionCoprocessorHost.TTL); 751 options.setTimeToPurgeDeletes(TestRegionCoprocessorHost.TIME_TO_PURGE_DELETES); 752 } 753 754 @Override 755 public void preWALAppend(ObserverContext<RegionCoprocessorEnvironment> ctx, WALKey key, 756 WALEdit edit) throws IOException { 757 ctPreWALAppend.incrementAndGet(); 758 759 key.addExtendedAttribute(Integer.toString(ctPreWALAppend.get()), Bytes.toBytes("foo")); 760 } 761 762 public boolean hadPreGet() { 763 return ctPreGet.get() > 0; 764 } 765 766 public boolean hadPostGet() { 767 return ctPostGet.get() > 0; 768 } 769 770 public boolean hadPrePut() { 771 return ctPrePut.get() > 0; 772 } 773 774 public boolean hadPostPut() { 775 return ctPostPut.get() > 0; 776 } 777 778 public boolean hadPreBatchMutate() { 779 return ctPreBatchMutate.get() > 0; 780 } 781 782 public int getPreBatchMutate() { 783 return ctPreBatchMutate.get(); 784 } 785 786 public boolean hadPostBatchMutate() { 787 return ctPostBatchMutate.get() > 0; 788 } 789 790 public int getPostBatchMutate() { 791 return ctPostBatchMutate.get(); 792 } 793 794 public boolean hadPostBatchMutateIndispensably() { 795 return ctPostBatchMutateIndispensably.get() > 0; 796 } 797 798 public int getPostBatchMutateIndispensably() { 799 return ctPostBatchMutateIndispensably.get(); 800 } 801 802 public boolean hadPostStartRegionOperation() { 803 return ctPostStartRegionOperation.get() > 0; 804 } 805 806 public boolean hadPostCloseRegionOperation() { 807 return ctPostCloseRegionOperation.get() > 0; 808 } 809 810 public boolean hadDelete() { 811 return !(ctBeforeDelete.get() > 0); 812 } 813 814 public int getCtPostStartRegionOperation() { 815 return ctPostStartRegionOperation.get(); 816 } 817 818 public int getCtPostCloseRegionOperation() { 819 return ctPostCloseRegionOperation.get(); 820 } 821 822 public int getPreCheckAndPut() { 823 return ctPreCheckAndPut.get(); 824 } 825 826 public int getPreCheckAndPutWithFilter() { 827 return ctPreCheckAndPutWithFilter.get(); 828 } 829 830 public int getPreCheckAndPutAfterRowLock() { 831 return ctPreCheckAndPutAfterRowLock.get(); 832 } 833 834 public int getPreCheckAndPutWithFilterAfterRowLock() { 835 return ctPreCheckAndPutWithFilterAfterRowLock.get(); 836 } 837 838 public int getPostCheckAndPut() { 839 return ctPostCheckAndPut.get(); 840 } 841 842 public int getPostCheckAndPutWithFilter() { 843 return ctPostCheckAndPutWithFilter.get(); 844 } 845 846 public int getPreCheckAndDelete() { 847 return ctPreCheckAndDelete.get(); 848 } 849 850 public int getPreCheckAndDeleteWithFilter() { 851 return ctPreCheckAndDeleteWithFilter.get(); 852 } 853 854 public int getPreCheckAndDeleteAfterRowLock() { 855 return ctPreCheckAndDeleteAfterRowLock.get(); 856 } 857 858 public int getPreCheckAndDeleteWithFilterAfterRowLock() { 859 return ctPreCheckAndDeleteWithFilterAfterRowLock.get(); 860 } 861 862 public int getPostCheckAndDelete() { 863 return ctPostCheckAndDelete.get(); 864 } 865 866 public int getPostCheckAndDeleteWithFilter() { 867 return ctPostCheckAndDeleteWithFilter.get(); 868 } 869 870 public int getPreCheckAndMutate() { 871 return ctPreCheckAndMutate.get(); 872 } 873 874 public int getPreCheckAndMutateAfterRowLock() { 875 return ctPreCheckAndMutateAfterRowLock.get(); 876 } 877 878 public int getPostCheckAndMutate() { 879 return ctPostCheckAndMutate.get(); 880 } 881 882 public boolean hadPreIncrement() { 883 return ctPreIncrement.get() > 0; 884 } 885 886 public boolean hadPreIncrementAfterRowLock() { 887 return ctPreIncrementAfterRowLock.get() > 0; 888 } 889 890 public boolean hadPostIncrement() { 891 return ctPostIncrement.get() > 0; 892 } 893 894 public boolean hadPreAppend() { 895 return ctPreAppend.get() > 0; 896 } 897 898 public boolean hadPreAppendAfterRowLock() { 899 return ctPreAppendAfterRowLock.get() > 0; 900 } 901 902 public boolean hadPostAppend() { 903 return ctPostAppend.get() > 0; 904 } 905 906 public boolean hadPrePreparedDeleteTS() { 907 return ctPrePrepareDeleteTS.get() > 0; 908 } 909 910 public boolean hadPreReplayWALs() { 911 return ctPreReplayWALs.get() > 0; 912 } 913 914 public boolean hadPostReplayWALs() { 915 return ctPostReplayWALs.get() > 0; 916 } 917 918 public boolean hadPreWALRestore() { 919 return ctPreWALRestore.get() > 0; 920 } 921 922 public boolean hadPostWALRestore() { 923 return ctPostWALRestore.get() > 0; 924 } 925 926 public boolean wasScannerNextCalled() { 927 return ctPreScannerNext.get() > 0 && ctPostScannerNext.get() > 0; 928 } 929 930 public boolean wasScannerFilterRowCalled() { 931 return ctPostScannerFilterRow.get() > 0; 932 } 933 934 public boolean wasScannerCloseCalled() { 935 return ctPreScannerClose.get() > 0 && ctPostScannerClose.get() > 0; 936 } 937 938 public boolean wasScannerOpenCalled() { 939 return ctPreScannerOpen.get() > 0 && ctPostScannerOpen.get() > 0; 940 } 941 942 public boolean hadDeleted() { 943 return ctPreDeleted.get() > 0 && ctPostDeleted.get() > 0; 944 } 945 946 public boolean hadPostBulkLoadHFile() { 947 return ctPostBulkLoadHFile.get() > 0; 948 } 949 950 public boolean hadPreBulkLoadHFile() { 951 return ctPreBulkLoadHFile.get() > 0; 952 } 953 954 public int getCtBeforeDelete() { 955 return ctBeforeDelete.get(); 956 } 957 958 public int getCtPreOpen() { 959 return ctPreOpen.get(); 960 } 961 962 public int getCtPostOpen() { 963 return ctPostOpen.get(); 964 } 965 966 public int getCtPreClose() { 967 return ctPreClose.get(); 968 } 969 970 public int getCtPostClose() { 971 return ctPostClose.get(); 972 } 973 974 public int getCtPreFlush() { 975 return ctPreFlush.get(); 976 } 977 978 public int getCtPostFlush() { 979 return ctPostFlush.get(); 980 } 981 982 public int getCtPreCompactSelect() { 983 return ctPreCompactSelect.get(); 984 } 985 986 public int getCtPostCompactSelect() { 987 return ctPostCompactSelect.get(); 988 } 989 990 public int getCtPreCompact() { 991 return ctPreCompact.get(); 992 } 993 994 public int getCtPostCompact() { 995 return ctPostCompact.get(); 996 } 997 998 public int getCtPreGet() { 999 return ctPreGet.get(); 1000 } 1001 1002 public int getCtPostGet() { 1003 return ctPostGet.get(); 1004 } 1005 1006 public int getCtPrePut() { 1007 return ctPrePut.get(); 1008 } 1009 1010 public int getCtPostPut() { 1011 return ctPostPut.get(); 1012 } 1013 1014 public int getCtPreDeleted() { 1015 return ctPreDeleted.get(); 1016 } 1017 1018 public int getCtPostDeleted() { 1019 return ctPostDeleted.get(); 1020 } 1021 1022 public int getCtPreIncrement() { 1023 return ctPreIncrement.get(); 1024 } 1025 1026 public int getCtPostIncrement() { 1027 return ctPostIncrement.get(); 1028 } 1029 1030 public int getCtPreReplayWALs() { 1031 return ctPreReplayWALs.get(); 1032 } 1033 1034 public int getCtPostReplayWALs() { 1035 return ctPostReplayWALs.get(); 1036 } 1037 1038 public int getCtPreWALRestore() { 1039 return ctPreWALRestore.get(); 1040 } 1041 1042 public int getCtPostWALRestore() { 1043 return ctPostWALRestore.get(); 1044 } 1045 1046 public int getCtPreWALAppend() { 1047 return ctPreWALAppend.get(); 1048 } 1049 1050 public boolean wasStoreFileReaderOpenCalled() { 1051 return ctPreStoreFileReaderOpen.get() > 0 && ctPostStoreFileReaderOpen.get() > 0; 1052 } 1053}