package coprocessor; import java.io.IOException; import java.util.BitSet; import java.util.List; import java.util.NavigableSet; import com.google.common.collect.ImmutableList; import com.google.protobuf.RpcCallback; import com.google.protobuf.RpcController; import com.google.protobuf.Service; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.Coprocessor; import org.apache.hadoop.hbase.CoprocessorEnvironment; import org.apache.hadoop.hbase.HRegionInfo; import org.apache.hadoop.hbase.client.Append; import org.apache.hadoop.hbase.client.Delete; import org.apache.hadoop.hbase.client.Durability; import org.apache.hadoop.hbase.client.Get; import org.apache.hadoop.hbase.client.Increment; import org.apache.hadoop.hbase.client.Mutation; import org.apache.hadoop.hbase.client.Put; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.client.Scan; import org.apache.hadoop.hbase.coprocessor.CoprocessorException; import org.apache.hadoop.hbase.coprocessor.CoprocessorService; import org.apache.hadoop.hbase.coprocessor.ObserverContext; import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment; import org.apache.hadoop.hbase.coprocessor.RegionObserver; import org.apache.hadoop.hbase.filter.ByteArrayComparable; import org.apache.hadoop.hbase.filter.CompareFilter; import org.apache.hadoop.hbase.io.FSDataInputStreamWrapper; import org.apache.hadoop.hbase.io.Reference; import org.apache.hadoop.hbase.io.hfile.CacheConfig; import org.apache.hadoop.hbase.protobuf.ResponseConverter; import org.apache.hadoop.hbase.regionserver.DeleteTracker; import org.apache.hadoop.hbase.regionserver.HRegion; import org.apache.hadoop.hbase.regionserver.InternalScanner; import org.apache.hadoop.hbase.regionserver.KeyValueScanner; import org.apache.hadoop.hbase.regionserver.MiniBatchOperationInProgress; import org.apache.hadoop.hbase.regionserver.Region; import org.apache.hadoop.hbase.regionserver.RegionScanner; import org.apache.hadoop.hbase.regionserver.ScanType; import org.apache.hadoop.hbase.regionserver.Store; import org.apache.hadoop.hbase.regionserver.StoreFile; import org.apache.hadoop.hbase.regionserver.compactions.CompactionRequest; import org.apache.hadoop.hbase.regionserver.wal.HLogKey; import org.apache.hadoop.hbase.regionserver.wal.WALEdit; import org.apache.hadoop.hbase.util.Pair; import org.apache.hadoop.hbase.wal.WALKey; import coprocessor.generated.ScanControlProtos; // cc ScanControlObserverEndpoint Observer and endpoint for scan operations // vv ScanControlObserverEndpoint @SuppressWarnings("deprecation") // because of API usage public class ScanControlObserverEndpoint extends ScanControlProtos.ScanControlService implements Coprocessor, CoprocessorService, RegionObserver { private RegionCoprocessorEnvironment env; private BitSet stopRows = new BitSet(); // Lifecycle methods @Override public void start(CoprocessorEnvironment env) throws IOException { if (env instanceof RegionCoprocessorEnvironment) { this.env = (RegionCoprocessorEnvironment) env; Configuration conf = env.getConfiguration(); String rows = conf.get("com.larsgeorge.copro.stoprows", "5"); for (String row : rows.split(",")) { stopRows.set(Integer.parseInt(row)); } } else { throw new CoprocessorException("Must be loaded on a table region!"); } } @Override public void stop(CoprocessorEnvironment env) throws IOException { // nothing to do when coprocessor is shutting down } @Override public Service getService() { return this; } // Endpoint methods @Override public void resumeScan(RpcController controller, ScanControlProtos.ScanControlRequest request, RpcCallback<ScanControlProtos.ScanControlResponse> done) { ScanControlProtos.ScanControlResponse response = null; try { response = ScanControlProtos.ScanControlResponse.getDefaultInstance(); } catch (Exception e) { ResponseConverter.setControllerException(controller, new IOException(e)); } done.run(response); } // RegionObserver Methods @Override public RegionScanner preScannerOpen( ObserverContext<RegionCoprocessorEnvironment> c, Scan scan, RegionScanner s) throws IOException { return null; } @Override public boolean preScannerNext(ObserverContext<RegionCoprocessorEnvironment> c, InternalScanner s, List<Result> result, int limit, boolean hasNext) throws IOException { return false; } @Override public boolean postScannerNext( ObserverContext<RegionCoprocessorEnvironment> c, InternalScanner s, List<Result> result, int limit, boolean hasNext) throws IOException { return false; } // RegionObserver Stubs @Override public void preOpen(ObserverContext<RegionCoprocessorEnvironment> c) throws IOException { } @Override public void postOpen(ObserverContext<RegionCoprocessorEnvironment> c) { } @Override public void postLogReplay(ObserverContext<RegionCoprocessorEnvironment> c) { } @Override public InternalScanner preFlushScannerOpen( ObserverContext<RegionCoprocessorEnvironment> c, Store store, KeyValueScanner memstoreScanner, InternalScanner s) throws IOException { return null; } @Override public void preFlush(ObserverContext<RegionCoprocessorEnvironment> c) throws IOException { } @Override public InternalScanner preFlush( ObserverContext<RegionCoprocessorEnvironment> c, Store store, InternalScanner scanner) throws IOException { return null; } @Override public void postFlush(ObserverContext<RegionCoprocessorEnvironment> c) throws IOException { } @Override public void postFlush(ObserverContext<RegionCoprocessorEnvironment> c, Store store, StoreFile resultFile) throws IOException { } @Override public void preCompactSelection( ObserverContext<RegionCoprocessorEnvironment> c, Store store, List<StoreFile> candidates, CompactionRequest request) throws IOException { } @Override public void preCompactSelection( ObserverContext<RegionCoprocessorEnvironment> c, Store store, List<StoreFile> candidates) throws IOException { } @Override public void postCompactSelection( ObserverContext<RegionCoprocessorEnvironment> c, Store store, ImmutableList<StoreFile> selected, CompactionRequest request) { } @Override public void postCompactSelection( ObserverContext<RegionCoprocessorEnvironment> c, Store store, ImmutableList<StoreFile> selected) { } @Override public InternalScanner preCompact( ObserverContext<RegionCoprocessorEnvironment> c, Store store, InternalScanner scanner, ScanType scanType, CompactionRequest request) throws IOException { return null; } @Override public InternalScanner preCompact( ObserverContext<RegionCoprocessorEnvironment> c, Store store, InternalScanner scanner, ScanType scanType) throws IOException { return null; } @Override public InternalScanner preCompactScannerOpen( ObserverContext<RegionCoprocessorEnvironment> c, Store store, List<? extends KeyValueScanner> scanners, ScanType scanType, long earliestPutTs, InternalScanner s, CompactionRequest request) throws IOException { return null; } @Override public InternalScanner preCompactScannerOpen( ObserverContext<RegionCoprocessorEnvironment> c, Store store, List<? extends KeyValueScanner> scanners, ScanType scanType, long earliestPutTs, InternalScanner s) throws IOException { return null; } @Override public void postCompact(ObserverContext<RegionCoprocessorEnvironment> c, Store store, StoreFile resultFile, CompactionRequest request) throws IOException { } @Override public void postCompact(ObserverContext<RegionCoprocessorEnvironment> c, Store store, StoreFile resultFile) throws IOException { } @Override public void preSplit(ObserverContext<RegionCoprocessorEnvironment> c) throws IOException { } @Override public void preSplit(ObserverContext<RegionCoprocessorEnvironment> c, byte[] splitRow) throws IOException { } @Override public void postSplit(ObserverContext<RegionCoprocessorEnvironment> c, Region l, Region r) throws IOException { } @Override public void preSplitBeforePONR( ObserverContext<RegionCoprocessorEnvironment> ctx, byte[] splitKey, List<Mutation> metaEntries) throws IOException { } @Override public void preSplitAfterPONR( ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException { } @Override public void preRollBackSplit( ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException { } @Override public void postRollBackSplit( ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException { } @Override public void postCompleteSplit( ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException { } @Override public void preClose(ObserverContext<RegionCoprocessorEnvironment> c, boolean abortRequested) throws IOException { } @Override public void postClose(ObserverContext<RegionCoprocessorEnvironment> c, boolean abortRequested) { } @Override public void preGetClosestRowBefore( ObserverContext<RegionCoprocessorEnvironment> c, byte[] row, byte[] family, Result result) throws IOException { } @Override public void postGetClosestRowBefore( ObserverContext<RegionCoprocessorEnvironment> c, byte[] row, byte[] family, Result result) throws IOException { } @Override public void preGetOp(ObserverContext<RegionCoprocessorEnvironment> c, Get get, List<Cell> result) throws IOException { } @Override public void postGetOp(ObserverContext<RegionCoprocessorEnvironment> c, Get get, List<Cell> result) throws IOException { } @Override public boolean preExists(ObserverContext<RegionCoprocessorEnvironment> c, Get get, boolean exists) throws IOException { return false; } @Override public boolean postExists(ObserverContext<RegionCoprocessorEnvironment> c, Get get, boolean exists) throws IOException { return false; } @Override public void prePut(ObserverContext<RegionCoprocessorEnvironment> c, Put put, WALEdit edit, Durability durability) throws IOException { } @Override public void postPut(ObserverContext<RegionCoprocessorEnvironment> c, Put put, WALEdit edit, Durability durability) throws IOException { } @Override public void preDelete(ObserverContext<RegionCoprocessorEnvironment> c, Delete delete, WALEdit edit, Durability durability) throws IOException { } @Override public void prePrepareTimeStampForDeleteVersion( ObserverContext<RegionCoprocessorEnvironment> c, Mutation mutation, Cell cell, byte[] byteNow, Get get) throws IOException { } @Override public void postDelete(ObserverContext<RegionCoprocessorEnvironment> c, Delete delete, WALEdit edit, Durability durability) throws IOException { } @Override public void preBatchMutate(ObserverContext<RegionCoprocessorEnvironment> c, MiniBatchOperationInProgress<Mutation> miniBatchOp) throws IOException { } @Override public void postBatchMutate(ObserverContext<RegionCoprocessorEnvironment> c, MiniBatchOperationInProgress<Mutation> miniBatchOp) throws IOException { } @Override public void postStartRegionOperation( ObserverContext<RegionCoprocessorEnvironment> ctx, HRegion.Operation operation) throws IOException { } @Override public void postCloseRegionOperation( ObserverContext<RegionCoprocessorEnvironment> ctx, HRegion.Operation operation) throws IOException { } @Override public void postBatchMutateIndispensably( ObserverContext<RegionCoprocessorEnvironment> ctx, MiniBatchOperationInProgress<Mutation> miniBatchOp, boolean success) throws IOException { } @Override public boolean preCheckAndPut(ObserverContext<RegionCoprocessorEnvironment> c, byte[] row, byte[] family, byte[] qualifier, CompareFilter.CompareOp compareOp, ByteArrayComparable comparator, Put put, boolean result) throws IOException { return false; } @Override public boolean preCheckAndPutAfterRowLock( ObserverContext<RegionCoprocessorEnvironment> c, byte[] row, byte[] family, byte[] qualifier, CompareFilter.CompareOp compareOp, ByteArrayComparable comparator, Put put, boolean result) throws IOException { return false; } @Override public boolean postCheckAndPut( ObserverContext<RegionCoprocessorEnvironment> c, byte[] row, byte[] family, byte[] qualifier, CompareFilter.CompareOp compareOp, ByteArrayComparable comparator, Put put, boolean result) throws IOException { return false; } @Override public boolean preCheckAndDelete( ObserverContext<RegionCoprocessorEnvironment> c, byte[] row, byte[] family, byte[] qualifier, CompareFilter.CompareOp compareOp, ByteArrayComparable comparator, Delete delete, boolean result) throws IOException { return false; } @Override public boolean preCheckAndDeleteAfterRowLock( ObserverContext<RegionCoprocessorEnvironment> c, byte[] row, byte[] family, byte[] qualifier, CompareFilter.CompareOp compareOp, ByteArrayComparable comparator, Delete delete, boolean result) throws IOException { return false; } @Override public boolean postCheckAndDelete( ObserverContext<RegionCoprocessorEnvironment> c, byte[] row, byte[] family, byte[] qualifier, CompareFilter.CompareOp compareOp, ByteArrayComparable comparator, Delete delete, boolean result) throws IOException { return false; } @Override public long preIncrementColumnValue( ObserverContext<RegionCoprocessorEnvironment> c, byte[] row, byte[] family, byte[] qualifier, long amount, boolean writeToWAL) throws IOException { return 0; } @Override public long postIncrementColumnValue( ObserverContext<RegionCoprocessorEnvironment> c, byte[] row, byte[] family, byte[] qualifier, long amount, boolean writeToWAL, long result) throws IOException { return 0; } @Override public Result preAppend(ObserverContext<RegionCoprocessorEnvironment> c, Append append) throws IOException { return null; } @Override public Result preAppendAfterRowLock( ObserverContext<RegionCoprocessorEnvironment> c, Append append) throws IOException { return null; } @Override public Result postAppend(ObserverContext<RegionCoprocessorEnvironment> c, Append append, Result result) throws IOException { return null; } @Override public Result preIncrement(ObserverContext<RegionCoprocessorEnvironment> c, Increment increment) throws IOException { return null; } @Override public Result preIncrementAfterRowLock( ObserverContext<RegionCoprocessorEnvironment> c, Increment increment) throws IOException { return null; } @Override public Result postIncrement(ObserverContext<RegionCoprocessorEnvironment> c, Increment increment, Result result) throws IOException { return null; } @Override public KeyValueScanner preStoreScannerOpen( ObserverContext<RegionCoprocessorEnvironment> c, Store store, Scan scan, NavigableSet<byte[]> targetCols, KeyValueScanner s) throws IOException { return null; } @Override public RegionScanner postScannerOpen( ObserverContext<RegionCoprocessorEnvironment> c, Scan scan, RegionScanner s) throws IOException { return null; } @Override public boolean postScannerFilterRow( ObserverContext<RegionCoprocessorEnvironment> c, InternalScanner s, byte[] currentRow, int offset, short length, boolean hasMore) throws IOException { return false; } @Override public void preScannerClose(ObserverContext<RegionCoprocessorEnvironment> c, InternalScanner s) throws IOException { } @Override public void postScannerClose(ObserverContext<RegionCoprocessorEnvironment> c, InternalScanner s) throws IOException { } @Override public void preWALRestore( ObserverContext<? extends RegionCoprocessorEnvironment> ctx, HRegionInfo info, WALKey logKey, WALEdit logEdit) throws IOException { } @Override public void preWALRestore(ObserverContext<RegionCoprocessorEnvironment> ctx, HRegionInfo info, HLogKey logKey, WALEdit logEdit) throws IOException { } @Override public void postWALRestore( ObserverContext<? extends RegionCoprocessorEnvironment> ctx, HRegionInfo info, WALKey logKey, WALEdit logEdit) throws IOException { } @Override public void postWALRestore(ObserverContext<RegionCoprocessorEnvironment> ctx, HRegionInfo info, HLogKey logKey, WALEdit logEdit) throws IOException { } @Override public void preBulkLoadHFile( ObserverContext<RegionCoprocessorEnvironment> ctx, List<Pair<byte[], String>> familyPaths) throws IOException { } @Override public boolean postBulkLoadHFile( ObserverContext<RegionCoprocessorEnvironment> ctx, List<Pair<byte[], String>> familyPaths, boolean hasLoaded) throws IOException { return false; } @Override public StoreFile.Reader preStoreFileReaderOpen( ObserverContext<RegionCoprocessorEnvironment> ctx, FileSystem fs, Path p, FSDataInputStreamWrapper in, long size, CacheConfig cacheConf, Reference r, StoreFile.Reader reader) throws IOException { return null; } @Override public StoreFile.Reader postStoreFileReaderOpen( ObserverContext<RegionCoprocessorEnvironment> ctx, FileSystem fs, Path p, FSDataInputStreamWrapper in, long size, CacheConfig cacheConf, Reference r, StoreFile.Reader reader) throws IOException { return null; } @Override public Cell postMutationBeforeWAL( ObserverContext<RegionCoprocessorEnvironment> ctx, MutationType opType, Mutation mutation, Cell oldCell, Cell newCell) throws IOException { return null; } @Override public DeleteTracker postInstantiateDeleteTracker( ObserverContext<RegionCoprocessorEnvironment> ctx, DeleteTracker delTracker) throws IOException { return null; } // vv ScanControlObserverEndpoint } // ^^ ScanControlObserverEndpoint