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