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