/* * Copyright 2010 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.hadoop.hbase.coprocessor; import java.io.IOException; import java.util.List; import com.google.common.collect.ImmutableList; import org.apache.hadoop.hbase.Coprocessor; import org.apache.hadoop.hbase.HRegionInfo; import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.client.Delete; import org.apache.hadoop.hbase.client.Get; 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.client.Increment; import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp; import org.apache.hadoop.hbase.filter.WritableByteArrayComparable; import org.apache.hadoop.hbase.regionserver.HRegion; import org.apache.hadoop.hbase.regionserver.InternalScanner; import org.apache.hadoop.hbase.regionserver.RegionScanner; import org.apache.hadoop.hbase.regionserver.Store; import org.apache.hadoop.hbase.regionserver.StoreFile; import org.apache.hadoop.hbase.regionserver.wal.HLogKey; import org.apache.hadoop.hbase.regionserver.wal.WALEdit; /** * Coprocessors implement this interface to observe and mediate client actions * on the region. */ public interface RegionObserver extends Coprocessor { /** * Called before the region is reported as open to the master. * @param c the environment provided by the region server */ void preOpen(final ObserverContext<RegionCoprocessorEnvironment> c); /** * Called after the region is reported as open to the master. * @param c the environment provided by the region server */ void postOpen(final ObserverContext<RegionCoprocessorEnvironment> c); /** * Called before the memstore is flushed to disk. * @param c the environment provided by the region server */ void preFlush(final ObserverContext<RegionCoprocessorEnvironment> c); /** * Called after the memstore is flushed to disk. * @param c the environment provided by the region server */ void postFlush(final ObserverContext<RegionCoprocessorEnvironment> c); /** * Called prior to selecting the {@link StoreFile}s to compact from the list * of available candidates. To alter the files used for compaction, you may * mutate the passed in list of candidates. * @param c the environment provided by the region server * @param store the store where compaction is being requested * @param candidates the store files currently available for compaction */ void preCompactSelection(final ObserverContext<RegionCoprocessorEnvironment> c, final Store store, final List<StoreFile> candidates); /** * Called after the {@link StoreFile}s to compact have been selected from the * available candidates. * @param c the environment provided by the region server * @param store the store being compacted * @param selected the store files selected to compact */ void postCompactSelection(final ObserverContext<RegionCoprocessorEnvironment> c, final Store store, final ImmutableList<StoreFile> selected); /** * Called prior to writing the {@link StoreFile}s selected for compaction into * a new {@code StoreFile}. To override or modify the compaction process, * implementing classes have two options: * <ul> * <li>Wrap the provided {@link InternalScanner} with a custom * implementation that is returned from this method. The custom scanner * can then inspect {@link KeyValue}s from the wrapped scanner, applying * its own policy to what gets written.</li> * <li>Call {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} * and provide a custom implementation for writing of new * {@link StoreFile}s. <strong>Note: any implementations bypassing * core compaction using this approach must write out new store files * themselves or the existing data will no longer be available after * compaction.</strong></li> * </ul> * @param c the environment provided by the region server * @param store the store being compacted * @param scanner the scanner over existing data used in the store file * rewriting * @return the scanner to use during compaction. Should not be {@code null} * unless the implementation is writing new store files on its own. */ InternalScanner preCompact(final ObserverContext<RegionCoprocessorEnvironment> c, final Store store, final InternalScanner scanner); /** * Called after compaction has completed and the new store file has been * moved in to place. * @param c the environment provided by the region server * @param store the store being compacted * @param resultFile the new store file written out during compaction */ void postCompact(final ObserverContext<RegionCoprocessorEnvironment> c, final Store store, StoreFile resultFile); /** * Called before the region is split. * @param c the environment provided by the region server * (e.getRegion() returns the parent region) */ void preSplit(final ObserverContext<RegionCoprocessorEnvironment> c); /** * Called after the region is split. * @param c the environment provided by the region server * (e.getRegion() returns the parent region) * @param l the left daughter region * @param r the right daughter region */ void postSplit(final ObserverContext<RegionCoprocessorEnvironment> c, final HRegion l, final HRegion r); /** * Called before the region is reported as closed to the master. * @param c the environment provided by the region server * @param abortRequested true if the region server is aborting */ void preClose(final ObserverContext<RegionCoprocessorEnvironment> c, boolean abortRequested); /** * Called after the region is reported as closed to the master. * @param c the environment provided by the region server * @param abortRequested true if the region server is aborting */ void postClose(final ObserverContext<RegionCoprocessorEnvironment> c, boolean abortRequested); /** * Called before a client makes a GetClosestRowBefore request. * <p> * Call CoprocessorEnvironment#bypass to skip default actions * <p> * Call CoprocessorEnvironment#complete to skip any subsequent chained * coprocessors * @param c the environment provided by the region server * @param row the row * @param family the family * @param result The result to return to the client if default processing * is bypassed. Can be modified. Will not be used if default processing * is not bypassed. * @throws IOException if an error occurred on the coprocessor */ void preGetClosestRowBefore(final ObserverContext<RegionCoprocessorEnvironment> c, final byte [] row, final byte [] family, final Result result) throws IOException; /** * Called after a client makes a GetClosestRowBefore request. * <p> * Call CoprocessorEnvironment#complete to skip any subsequent chained * coprocessors * @param c the environment provided by the region server * @param row the row * @param family the desired family * @param result the result to return to the client, modify as necessary * @throws IOException if an error occurred on the coprocessor */ void postGetClosestRowBefore(final ObserverContext<RegionCoprocessorEnvironment> c, final byte [] row, final byte [] family, final Result result) throws IOException; /** * Called before the client performs a Get * <p> * Call CoprocessorEnvironment#bypass to skip default actions * <p> * Call CoprocessorEnvironment#complete to skip any subsequent chained * coprocessors * @param c the environment provided by the region server * @param get the Get request * @param result The result to return to the client if default processing * is bypassed. Can be modified. Will not be used if default processing * is not bypassed. * @throws IOException if an error occurred on the coprocessor */ void preGet(final ObserverContext<RegionCoprocessorEnvironment> c, final Get get, final List<KeyValue> result) throws IOException; /** * Called after the client performs a Get * <p> * Call CoprocessorEnvironment#complete to skip any subsequent chained * coprocessors * @param c the environment provided by the region server * @param get the Get request * @param result the result to return to the client, modify as necessary * @throws IOException if an error occurred on the coprocessor */ void postGet(final ObserverContext<RegionCoprocessorEnvironment> c, final Get get, final List<KeyValue> result) throws IOException; /** * Called before the client tests for existence using a Get. * <p> * Call CoprocessorEnvironment#bypass to skip default actions * <p> * Call CoprocessorEnvironment#complete to skip any subsequent chained * coprocessors * @param c the environment provided by the region server * @param get the Get request * @param exists * @return the value to return to the client if bypassing default processing * @throws IOException if an error occurred on the coprocessor */ boolean preExists(final ObserverContext<RegionCoprocessorEnvironment> c, final Get get, final boolean exists) throws IOException; /** * Called after the client tests for existence using a Get. * <p> * Call CoprocessorEnvironment#complete to skip any subsequent chained * coprocessors * @param c the environment provided by the region server * @param get the Get request * @param exists the result returned by the region server * @return the result to return to the client * @throws IOException if an error occurred on the coprocessor */ boolean postExists(final ObserverContext<RegionCoprocessorEnvironment> c, final Get get, final boolean exists) throws IOException; /** * Called before the client stores a value. * <p> * Call CoprocessorEnvironment#bypass to skip default actions * <p> * Call CoprocessorEnvironment#complete to skip any subsequent chained * coprocessors * @param c the environment provided by the region server * @param put The Put object * @param edit The WALEdit object that will be written to the wal * @param writeToWAL true if the change should be written to the WAL * @throws IOException if an error occurred on the coprocessor */ void prePut(final ObserverContext<RegionCoprocessorEnvironment> c, final Put put, final WALEdit edit, final boolean writeToWAL) throws IOException; /** * Called after the client stores a value. * <p> * Call CoprocessorEnvironment#complete to skip any subsequent chained * coprocessors * @param c the environment provided by the region server * @param put The Put object * @param edit The WALEdit object for the wal * @param writeToWAL true if the change should be written to the WAL * @throws IOException if an error occurred on the coprocessor */ void postPut(final ObserverContext<RegionCoprocessorEnvironment> c, final Put put, final WALEdit edit, final boolean writeToWAL) throws IOException; /** * Called before the client deletes a value. * <p> * Call CoprocessorEnvironment#bypass to skip default actions * <p> * Call CoprocessorEnvironment#complete to skip any subsequent chained * coprocessors * @param c the environment provided by the region server * @param delete The Delete object * @param edit The WALEdit object for the wal * @param writeToWAL true if the change should be written to the WAL * @throws IOException if an error occurred on the coprocessor */ void preDelete(final ObserverContext<RegionCoprocessorEnvironment> c, final Delete delete, final WALEdit edit, final boolean writeToWAL) throws IOException; /** * Called after the client deletes a value. * <p> * Call CoprocessorEnvironment#complete to skip any subsequent chained * coprocessors * @param c the environment provided by the region server * @param delete The Delete object * @param edit The WALEdit object for the wal * @param writeToWAL true if the change should be written to the WAL * @throws IOException if an error occurred on the coprocessor */ void postDelete(final ObserverContext<RegionCoprocessorEnvironment> c, final Delete delete, final WALEdit edit, final boolean writeToWAL) throws IOException; /** * Called before checkAndPut * <p> * Call CoprocessorEnvironment#bypass to skip default actions * <p> * Call CoprocessorEnvironment#complete to skip any subsequent chained * coprocessors * @param c the environment provided by the region server * @param row row to check * @param family column family * @param qualifier column qualifier * @param compareOp the comparison operation * @param comparator the comparator * @param put data to put if check succeeds * @param result * @return the return value to return to client if bypassing default * processing * @throws IOException if an error occurred on the coprocessor */ boolean preCheckAndPut(final ObserverContext<RegionCoprocessorEnvironment> c, final byte [] row, final byte [] family, final byte [] qualifier, final CompareOp compareOp, final WritableByteArrayComparable comparator, final Put put, final boolean result) throws IOException; /** * Called after checkAndPut * <p> * Call CoprocessorEnvironment#complete to skip any subsequent chained * coprocessors * @param c the environment provided by the region server * @param row row to check * @param family column family * @param qualifier column qualifier * @param compareOp the comparison operation * @param comparator the comparator * @param put data to put if check succeeds * @param result from the checkAndPut * @return the possibly transformed return value to return to client * @throws IOException if an error occurred on the coprocessor */ boolean postCheckAndPut(final ObserverContext<RegionCoprocessorEnvironment> c, final byte [] row, final byte [] family, final byte [] qualifier, final CompareOp compareOp, final WritableByteArrayComparable comparator, final Put put, final boolean result) throws IOException; /** * Called before checkAndDelete * <p> * Call CoprocessorEnvironment#bypass to skip default actions * <p> * Call CoprocessorEnvironment#complete to skip any subsequent chained * coprocessors * @param c the environment provided by the region server * @param row row to check * @param family column family * @param qualifier column qualifier * @param compareOp the comparison operation * @param comparator the comparator * @param delete delete to commit if check succeeds * @param result * @return the value to return to client if bypassing default processing * @throws IOException if an error occurred on the coprocessor */ boolean preCheckAndDelete(final ObserverContext<RegionCoprocessorEnvironment> c, final byte [] row, final byte [] family, final byte [] qualifier, final CompareOp compareOp, final WritableByteArrayComparable comparator, final Delete delete, final boolean result) throws IOException; /** * Called after checkAndDelete * <p> * Call CoprocessorEnvironment#complete to skip any subsequent chained * coprocessors * @param c the environment provided by the region server * @param row row to check * @param family column family * @param qualifier column qualifier * @param compareOp the comparison operation * @param comparator the comparator * @param delete delete to commit if check succeeds * @param result from the CheckAndDelete * @return the possibly transformed returned value to return to client * @throws IOException if an error occurred on the coprocessor */ boolean postCheckAndDelete(final ObserverContext<RegionCoprocessorEnvironment> c, final byte [] row, final byte [] family, final byte [] qualifier, final CompareOp compareOp, final WritableByteArrayComparable comparator, final Delete delete, final boolean result) throws IOException; /** * Called before incrementColumnValue * <p> * Call CoprocessorEnvironment#bypass to skip default actions * <p> * Call CoprocessorEnvironment#complete to skip any subsequent chained * coprocessors * @param c the environment provided by the region server * @param row row to check * @param family column family * @param qualifier column qualifier * @param amount long amount to increment * @param writeToWAL true if the change should be written to the WAL * @return value to return to the client if bypassing default processing * @throws IOException if an error occurred on the coprocessor */ long preIncrementColumnValue(final ObserverContext<RegionCoprocessorEnvironment> c, final byte [] row, final byte [] family, final byte [] qualifier, final long amount, final boolean writeToWAL) throws IOException; /** * Called after incrementColumnValue * <p> * Call CoprocessorEnvironment#complete to skip any subsequent chained * coprocessors * @param c the environment provided by the region server * @param row row to check * @param family column family * @param qualifier column qualifier * @param amount long amount to increment * @param writeToWAL true if the change should be written to the WAL * @param result the result returned by incrementColumnValue * @return the result to return to the client * @throws IOException if an error occurred on the coprocessor */ long postIncrementColumnValue(final ObserverContext<RegionCoprocessorEnvironment> c, final byte [] row, final byte [] family, final byte [] qualifier, final long amount, final boolean writeToWAL, final long result) throws IOException; /** * Called before Increment * <p> * Call CoprocessorEnvironment#bypass to skip default actions * <p> * Call CoprocessorEnvironment#complete to skip any subsequent chained * coprocessors * @param c the environment provided by the region server * @param increment increment object * @return result to return to the client if bypassing default processing * @throws IOException if an error occurred on the coprocessor */ Result preIncrement(final ObserverContext<RegionCoprocessorEnvironment> c, final Increment increment) throws IOException; /** * Called after increment * <p> * Call CoprocessorEnvironment#complete to skip any subsequent chained * coprocessors * @param c the environment provided by the region server * @param increment increment object * @param result the result returned by increment * @return the result to return to the client * @throws IOException if an error occurred on the coprocessor */ Result postIncrement(final ObserverContext<RegionCoprocessorEnvironment> c, final Increment increment, final Result result) throws IOException; /** * Called before the client opens a new scanner. * <p> * Call CoprocessorEnvironment#bypass to skip default actions * <p> * Call CoprocessorEnvironment#complete to skip any subsequent chained * coprocessors * @param c the environment provided by the region server * @param scan the Scan specification * @param s if not null, the base scanner * @return an RegionScanner instance to use instead of the base scanner if * overriding default behavior, null otherwise * @throws IOException if an error occurred on the coprocessor */ RegionScanner preScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c, final Scan scan, final RegionScanner s) throws IOException; /** * Called after the client opens a new scanner. * <p> * Call CoprocessorEnvironment#complete to skip any subsequent chained * coprocessors * @param c the environment provided by the region server * @param scan the Scan specification * @param s if not null, the base scanner * @return the scanner instance to use * @throws IOException if an error occurred on the coprocessor */ RegionScanner postScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c, final Scan scan, final RegionScanner s) throws IOException; /** * Called before the client asks for the next row on a scanner. * <p> * Call CoprocessorEnvironment#bypass to skip default actions * <p> * Call CoprocessorEnvironment#complete to skip any subsequent chained * coprocessors * @param c the environment provided by the region server * @param s the scanner * @param result The result to return to the client if default processing * is bypassed. Can be modified. Will not be returned if default processing * is not bypassed. * @param limit the maximum number of results to return * @param hasNext the 'has more' indication * @return 'has more' indication that should be sent to client * @throws IOException if an error occurred on the coprocessor */ boolean preScannerNext(final ObserverContext<RegionCoprocessorEnvironment> c, final InternalScanner s, final List<Result> result, final int limit, final boolean hasNext) throws IOException; /** * Called after the client asks for the next row on a scanner. * <p> * Call CoprocessorEnvironment#complete to skip any subsequent chained * coprocessors * @param c the environment provided by the region server * @param s the scanner * @param result the result to return to the client, can be modified * @param limit the maximum number of results to return * @param hasNext the 'has more' indication * @return 'has more' indication that should be sent to client * @throws IOException if an error occurred on the coprocessor */ boolean postScannerNext(final ObserverContext<RegionCoprocessorEnvironment> c, final InternalScanner s, final List<Result> result, final int limit, final boolean hasNext) throws IOException; /** * Called before the client closes a scanner. * <p> * Call CoprocessorEnvironment#bypass to skip default actions * <p> * Call CoprocessorEnvironment#complete to skip any subsequent chained * coprocessors * @param c the environment provided by the region server * @param s the scanner * @throws IOException if an error occurred on the coprocessor */ void preScannerClose(final ObserverContext<RegionCoprocessorEnvironment> c, final InternalScanner s) throws IOException; /** * Called after the client closes a scanner. * <p> * Call CoprocessorEnvironment#complete to skip any subsequent chained * coprocessors * @param c the environment provided by the region server * @param s the scanner * @throws IOException if an error occurred on the coprocessor */ void postScannerClose(final ObserverContext<RegionCoprocessorEnvironment> c, final InternalScanner s) throws IOException; /** * Called before a {@link org.apache.hadoop.hbase.regionserver.wal.WALEdit} * replayed for this region. * * @param ctx * @param info * @param logKey * @param logEdit * @throws IOException */ void preWALRestore(final ObserverContext<RegionCoprocessorEnvironment> ctx, HRegionInfo info, HLogKey logKey, WALEdit logEdit) throws IOException; /** * Called after a {@link org.apache.hadoop.hbase.regionserver.wal.WALEdit} * replayed for this region. * * @param ctx * @param info * @param logKey * @param logEdit * @throws IOException */ void postWALRestore(final ObserverContext<RegionCoprocessorEnvironment> ctx, HRegionInfo info, HLogKey logKey, WALEdit logEdit) throws IOException; }