View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.hadoop.hbase.coprocessor;
21  
22  import java.io.IOException;
23  import java.util.List;
24  import java.util.NavigableSet;
25  
26  import org.apache.hadoop.hbase.classification.InterfaceAudience;
27  import org.apache.hadoop.hbase.classification.InterfaceStability;
28  import org.apache.hadoop.fs.FileSystem;
29  import org.apache.hadoop.fs.Path;
30  import org.apache.hadoop.hbase.Cell;
31  import org.apache.hadoop.hbase.Coprocessor;
32  import org.apache.hadoop.hbase.HBaseInterfaceAudience;
33  import org.apache.hadoop.hbase.HRegionInfo;
34  import org.apache.hadoop.hbase.client.Append;
35  import org.apache.hadoop.hbase.client.Delete;
36  import org.apache.hadoop.hbase.client.Durability;
37  import org.apache.hadoop.hbase.client.Get;
38  import org.apache.hadoop.hbase.client.Increment;
39  import org.apache.hadoop.hbase.client.Mutation;
40  import org.apache.hadoop.hbase.client.Put;
41  import org.apache.hadoop.hbase.client.Result;
42  import org.apache.hadoop.hbase.client.Scan;
43  import org.apache.hadoop.hbase.filter.ByteArrayComparable;
44  import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
45  import org.apache.hadoop.hbase.io.FSDataInputStreamWrapper;
46  import org.apache.hadoop.hbase.io.Reference;
47  import org.apache.hadoop.hbase.io.hfile.CacheConfig;
48  import org.apache.hadoop.hbase.regionserver.DeleteTracker;
49  import org.apache.hadoop.hbase.regionserver.Region;
50  import org.apache.hadoop.hbase.regionserver.Region.Operation;
51  import org.apache.hadoop.hbase.regionserver.InternalScanner;
52  import org.apache.hadoop.hbase.regionserver.KeyValueScanner;
53  import org.apache.hadoop.hbase.regionserver.MiniBatchOperationInProgress;
54  import org.apache.hadoop.hbase.regionserver.RegionScanner;
55  import org.apache.hadoop.hbase.regionserver.ScanType;
56  import org.apache.hadoop.hbase.regionserver.Store;
57  import org.apache.hadoop.hbase.regionserver.StoreFile;
58  import org.apache.hadoop.hbase.regionserver.compactions.CompactionRequest;
59  import org.apache.hadoop.hbase.regionserver.wal.HLogKey;
60  import org.apache.hadoop.hbase.wal.WALKey;
61  import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
62  import org.apache.hadoop.hbase.util.Pair;
63  
64  import com.google.common.collect.ImmutableList;
65  
66  /**
67   * Coprocessors implement this interface to observe and mediate client actions
68   * on the region.
69   */
70  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.COPROC)
71  @InterfaceStability.Evolving
72  // TODO as method signatures need to break, update to
73  // ObserverContext<? extends RegionCoprocessorEnvironment>
74  // so we can use additional environment state that isn't exposed to coprocessors.
75  public interface RegionObserver extends Coprocessor {
76  
77    /** Mutation type for postMutationBeforeWAL hook */
78    public enum MutationType {
79      APPEND, INCREMENT
80    }
81  
82    /**
83     * Called before the region is reported as open to the master.
84     * @param c the environment provided by the region server
85     * @throws IOException if an error occurred on the coprocessor
86     */
87    void preOpen(final ObserverContext<RegionCoprocessorEnvironment> c) throws IOException;
88  
89    /**
90     * Called after the region is reported as open to the master.
91     * @param c the environment provided by the region server
92     */
93    void postOpen(final ObserverContext<RegionCoprocessorEnvironment> c);
94  
95    /**
96     * Called after the log replay on the region is over.
97     * @param c the environment provided by the region server
98     */
99    void postLogReplay(final ObserverContext<RegionCoprocessorEnvironment> c);
100 
101   /**
102    * Called before a memstore is flushed to disk and prior to creating the scanner to read from
103    * the memstore.  To override or modify how a memstore is flushed,
104    * implementing classes can return a new scanner to provide the KeyValues to be
105    * stored into the new {@code StoreFile} or null to perform the default processing.
106    * Calling {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} has no
107    * effect in this hook.
108    * @param c the environment provided by the region server
109    * @param store the store being flushed
110    * @param memstoreScanner the scanner for the memstore that is flushed
111    * @param s the base scanner, if not {@code null}, from previous RegionObserver in the chain
112    * @return the scanner to use during the flush.  {@code null} if the default implementation
113    * is to be used.
114    * @throws IOException if an error occurred on the coprocessor
115    * @deprecated Use {@link #preFlushScannerOpen(ObserverContext, Store, KeyValueScanner,
116    *             InternalScanner, long)}
117    */
118   @Deprecated
119   InternalScanner preFlushScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c,
120       final Store store, final KeyValueScanner memstoreScanner, final InternalScanner s)
121       throws IOException;
122 
123   /**
124    * Called before a memstore is flushed to disk and prior to creating the scanner to read from
125    * the memstore.  To override or modify how a memstore is flushed,
126    * implementing classes can return a new scanner to provide the KeyValues to be
127    * stored into the new {@code StoreFile} or null to perform the default processing.
128    * Calling {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} has no
129    * effect in this hook.
130    * @param c the environment provided by the region server
131    * @param store the store being flushed
132    * @param memstoreScanner the scanner for the memstore that is flushed
133    * @param s the base scanner, if not {@code null}, from previous RegionObserver in the chain
134    * @param readPoint the readpoint to create scanner
135    * @return the scanner to use during the flush.  {@code null} if the default implementation
136    * is to be used.
137    * @throws IOException if an error occurred on the coprocessor
138    */
139   InternalScanner preFlushScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c,
140       final Store store, final KeyValueScanner memstoreScanner, final InternalScanner s,
141       final long readPoint) throws IOException;
142 
143   /**
144    * Called before the memstore is flushed to disk.
145    * @param c the environment provided by the region server
146    * @throws IOException if an error occurred on the coprocessor
147    * @deprecated use {@link #preFlush(ObserverContext, Store, InternalScanner)} instead
148    */
149   void preFlush(final ObserverContext<RegionCoprocessorEnvironment> c) throws IOException;
150 
151   /**
152    * Called before a Store's memstore is flushed to disk.
153    * @param c the environment provided by the region server
154    * @param store the store where compaction is being requested
155    * @param scanner the scanner over existing data used in the store file
156    * @return the scanner to use during compaction.  Should not be {@code null}
157    * unless the implementation is writing new store files on its own.
158    * @throws IOException if an error occurred on the coprocessor
159    */
160   InternalScanner preFlush(final ObserverContext<RegionCoprocessorEnvironment> c, final Store store,
161       final InternalScanner scanner) throws IOException;
162 
163   /**
164    * Called after the memstore is flushed to disk.
165    * @param c the environment provided by the region server
166    * @throws IOException if an error occurred on the coprocessor
167    * @deprecated use {@link #preFlush(ObserverContext, Store, InternalScanner)} instead.
168    */
169   void postFlush(final ObserverContext<RegionCoprocessorEnvironment> c) throws IOException;
170 
171   /**
172    * Called after a Store's memstore is flushed to disk.
173    * @param c the environment provided by the region server
174    * @param store the store being flushed
175    * @param resultFile the new store file written out during compaction
176    * @throws IOException if an error occurred on the coprocessor
177    */
178   void postFlush(final ObserverContext<RegionCoprocessorEnvironment> c, final Store store,
179       final StoreFile resultFile) throws IOException;
180 
181   /**
182    * Called prior to selecting the {@link StoreFile StoreFiles} to compact from the list of
183    * available candidates. To alter the files used for compaction, you may mutate the passed in list
184    * of candidates.
185    * @param c the environment provided by the region server
186    * @param store the store where compaction is being requested
187    * @param candidates the store files currently available for compaction
188    * @param request custom compaction request
189    * @throws IOException if an error occurred on the coprocessor
190    */
191   void preCompactSelection(final ObserverContext<RegionCoprocessorEnvironment> c,
192       final Store store, final List<StoreFile> candidates, final CompactionRequest request)
193       throws IOException;
194 
195   /**
196    * Called prior to selecting the {@link StoreFile}s to compact from the list of available
197    * candidates. To alter the files used for compaction, you may mutate the passed in list of
198    * candidates.
199    * @param c the environment provided by the region server
200    * @param store the store where compaction is being requested
201    * @param candidates the store files currently available for compaction
202    * @throws IOException if an error occurred on the coprocessor
203    * @deprecated Use {@link #preCompactSelection(ObserverContext, Store, List, CompactionRequest)}
204    *             instead
205    */
206   @Deprecated
207   void preCompactSelection(final ObserverContext<RegionCoprocessorEnvironment> c,
208       final Store store, final List<StoreFile> candidates) throws IOException;
209 
210   /**
211    * Called after the {@link StoreFile}s to compact have been selected from the available
212    * candidates.
213    * @param c the environment provided by the region server
214    * @param store the store being compacted
215    * @param selected the store files selected to compact
216    * @param request custom compaction request
217    */
218   void postCompactSelection(final ObserverContext<RegionCoprocessorEnvironment> c,
219       final Store store, final ImmutableList<StoreFile> selected, CompactionRequest request);
220 
221   /**
222    * Called after the {@link StoreFile}s to compact have been selected from the available
223    * candidates.
224    * @param c the environment provided by the region server
225    * @param store the store being compacted
226    * @param selected the store files selected to compact
227    * @deprecated use {@link #postCompactSelection(ObserverContext, Store, ImmutableList,
228    *             CompactionRequest)} instead.
229    */
230   @Deprecated
231   void postCompactSelection(final ObserverContext<RegionCoprocessorEnvironment> c,
232       final Store store, final ImmutableList<StoreFile> selected);
233 
234   /**
235    * Called prior to writing the {@link StoreFile}s selected for compaction into a new
236    * {@code StoreFile}. To override or modify the compaction process, implementing classes have two
237    * options:
238    * <ul>
239    * <li>Wrap the provided {@link InternalScanner} with a custom implementation that is returned
240    * from this method. The custom scanner can then inspect 
241    * {@link org.apache.hadoop.hbase.KeyValue}s from the wrapped
242    * scanner, applying its own policy to what gets written.</li>
243    * <li>Call {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} and provide a
244    * custom implementation for writing of new {@link StoreFile}s. <strong>Note: any implementations
245    * bypassing core compaction using this approach must write out new store files themselves or the
246    * existing data will no longer be available after compaction.</strong></li>
247    * </ul>
248    * @param c the environment provided by the region server
249    * @param store the store being compacted
250    * @param scanner the scanner over existing data used in the store file rewriting
251    * @param scanType type of Scan
252    * @param request the requested compaction
253    * @return the scanner to use during compaction. Should not be {@code null} unless the
254    *         implementation is writing new store files on its own.
255    * @throws IOException if an error occurred on the coprocessor
256    */
257   InternalScanner preCompact(final ObserverContext<RegionCoprocessorEnvironment> c,
258       final Store store, final InternalScanner scanner, final ScanType scanType,
259       CompactionRequest request) throws IOException;
260 
261   /**
262    * Called prior to writing the {@link StoreFile}s selected for compaction into a new
263    * {@code StoreFile}. To override or modify the compaction process, implementing classes have two
264    * options:
265    * <ul>
266    * <li>Wrap the provided {@link InternalScanner} with a custom implementation that is returned
267    * from this method. The custom scanner can then inspect 
268    * {@link org.apache.hadoop.hbase.KeyValue}s from the wrapped
269    * scanner, applying its own policy to what gets written.</li>
270    * <li>Call {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} and provide a
271    * custom implementation for writing of new {@link StoreFile}s. <strong>Note: any implementations
272    * bypassing core compaction using this approach must write out new store files themselves or the
273    * existing data will no longer be available after compaction.</strong></li>
274    * </ul>
275    * @param c the environment provided by the region server
276    * @param store the store being compacted
277    * @param scanner the scanner over existing data used in the store file rewriting
278    * @param scanType type of Scan
279    * @return the scanner to use during compaction. Should not be {@code null} unless the
280    *         implementation is writing new store files on its own.
281    * @throws IOException if an error occurred on the coprocessor
282    * @deprecated use
283    *             {@link #preCompact(ObserverContext, Store, InternalScanner,
284    *             ScanType, CompactionRequest)} instead
285    */
286   @Deprecated
287   InternalScanner preCompact(final ObserverContext<RegionCoprocessorEnvironment> c,
288       final Store store, final InternalScanner scanner, final ScanType scanType) throws IOException;
289 
290   /**
291    * Called prior to writing the {@link StoreFile}s selected for compaction into a new
292    * {@code StoreFile} and prior to creating the scanner used to read the input files. To override
293    * or modify the compaction process, implementing classes can return a new scanner to provide the
294    * KeyValues to be stored into the new {@code StoreFile} or null to perform the default
295    * processing. Calling {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} has no
296    * effect in this hook.
297    * @param c the environment provided by the region server
298    * @param store the store being compacted
299    * @param scanners the list {@link org.apache.hadoop.hbase.regionserver.StoreFileScanner}s 
300    *        to be read from
301    * @param scanType the {@link ScanType} indicating whether this is a major or minor compaction
302    * @param earliestPutTs timestamp of the earliest put that was found in any of the involved store
303    *          files
304    * @param s the base scanner, if not {@code null}, from previous RegionObserver in the chain
305    * @param request the requested compaction
306    * @return the scanner to use during compaction. {@code null} if the default implementation is to
307    *         be used.
308    * @throws IOException if an error occurred on the coprocessor
309    * @deprecated Use {@link #preCompactScannerOpen(ObserverContext, Store, List, ScanType, long,
310    *             InternalScanner, CompactionRequest, long)} instead.
311    */
312   @Deprecated
313   InternalScanner preCompactScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c,
314       final Store store, List<? extends KeyValueScanner> scanners, final ScanType scanType,
315       final long earliestPutTs, final InternalScanner s, CompactionRequest request)
316       throws IOException;
317 
318   /**
319    * Called prior to writing the {@link StoreFile}s selected for compaction into a new
320    * {@code StoreFile} and prior to creating the scanner used to read the input files. To override
321    * or modify the compaction process, implementing classes can return a new scanner to provide the
322    * KeyValues to be stored into the new {@code StoreFile} or null to perform the default
323    * processing. Calling {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} has no
324    * effect in this hook.
325    * @param c the environment provided by the region server
326    * @param store the store being compacted
327    * @param scanners the list {@link org.apache.hadoop.hbase.regionserver.StoreFileScanner}s 
328    *        to be read from
329    * @param scanType the {@link ScanType} indicating whether this is a major or minor compaction
330    * @param earliestPutTs timestamp of the earliest put that was found in any of the involved store
331    *          files
332    * @param s the base scanner, if not {@code null}, from previous RegionObserver in the chain
333    * @param request compaction request
334    * @param readPoint the readpoint to create scanner
335    * @return the scanner to use during compaction. {@code null} if the default implementation is to
336    *          be used.
337    * @throws IOException if an error occurred on the coprocessor
338    */
339   InternalScanner preCompactScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c,
340       final Store store, List<? extends KeyValueScanner> scanners, final ScanType scanType,
341       final long earliestPutTs, final InternalScanner s, final CompactionRequest request,
342       final long readPoint) throws IOException;
343 
344   /**
345    * Called prior to writing the {@link StoreFile}s selected for compaction into a new
346    * {@code StoreFile} and prior to creating the scanner used to read the input files. To override
347    * or modify the compaction process, implementing classes can return a new scanner to provide the
348    * KeyValues to be stored into the new {@code StoreFile} or null to perform the default
349    * processing. Calling {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} has no
350    * effect in this hook.
351    * @param c the environment provided by the region server
352    * @param store the store being compacted
353    * @param scanners the list {@link org.apache.hadoop.hbase.regionserver.StoreFileScanner}s
354    *  to be read from
355    * @param scanType the {@link ScanType} indicating whether this is a major or minor compaction
356    * @param earliestPutTs timestamp of the earliest put that was found in any of the involved store
357    *          files
358    * @param s the base scanner, if not {@code null}, from previous RegionObserver in the chain
359    * @return the scanner to use during compaction. {@code null} if the default implementation is to
360    *         be used.
361    * @throws IOException if an error occurred on the coprocessor
362    * @deprecated Use
363    *             {@link #preCompactScannerOpen(ObserverContext, Store, List, ScanType, long,
364    *             InternalScanner, CompactionRequest, long)} instead.
365    */
366   @Deprecated
367   InternalScanner preCompactScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c,
368       final Store store, List<? extends KeyValueScanner> scanners, final ScanType scanType,
369       final long earliestPutTs, final InternalScanner s) throws IOException;
370 
371   /**
372    * Called after compaction has completed and the new store file has been moved in to place.
373    * @param c the environment provided by the region server
374    * @param store the store being compacted
375    * @param resultFile the new store file written out during compaction
376    * @param request the requested compaction
377    * @throws IOException if an error occurred on the coprocessor
378    */
379   void postCompact(final ObserverContext<RegionCoprocessorEnvironment> c, final Store store,
380       StoreFile resultFile, CompactionRequest request) throws IOException;
381 
382   /**
383    * Called after compaction has completed and the new store file has been moved in to place.
384    * @param c the environment provided by the region server
385    * @param store the store being compacted
386    * @param resultFile the new store file written out during compaction
387    * @throws IOException if an error occurred on the coprocessor
388    * @deprecated Use {@link #postCompact(ObserverContext, Store, StoreFile, CompactionRequest)}
389    *             instead
390    */
391   @Deprecated
392   void postCompact(final ObserverContext<RegionCoprocessorEnvironment> c, final Store store,
393       StoreFile resultFile) throws IOException;
394 
395   /**
396    * Called before the region is split.
397    * @param c the environment provided by the region server
398    * (e.getRegion() returns the parent region)
399    * @throws IOException if an error occurred on the coprocessor
400    * @deprecated Use preSplit(
401    *    final ObserverContext&lt;RegionCoprocessorEnvironment&gt; c, byte[] splitRow)
402    */
403   void preSplit(final ObserverContext<RegionCoprocessorEnvironment> c) throws IOException;
404 
405   /**
406    * Called before the region is split.
407    * @param c the environment provided by the region server
408    * (e.getRegion() returns the parent region)
409    * @throws IOException if an error occurred on the coprocessor
410    */
411   void preSplit(final ObserverContext<RegionCoprocessorEnvironment> c, byte[] splitRow)
412       throws IOException;
413 
414   /**
415    * Called after the region is split.
416    * @param c the environment provided by the region server
417    * (e.getRegion() returns the parent region)
418    * @param l the left daughter region
419    * @param r the right daughter region
420    * @throws IOException if an error occurred on the coprocessor
421    * @deprecated Use postCompleteSplit() instead
422    */
423   void postSplit(final ObserverContext<RegionCoprocessorEnvironment> c, final Region l,
424       final Region r) throws IOException;
425 
426   /**
427    * This will be called before PONR step as part of split transaction. Calling
428    * {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} rollback the split
429    * @param ctx
430    * @param splitKey
431    * @param metaEntries
432    * @throws IOException
433    */
434   void preSplitBeforePONR(final ObserverContext<RegionCoprocessorEnvironment> ctx,
435       byte[] splitKey, List<Mutation> metaEntries) throws IOException;
436 
437   
438   /**
439    * This will be called after PONR step as part of split transaction
440    * Calling {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} has no
441    * effect in this hook.
442    * @param ctx
443    * @throws IOException
444    */
445   void preSplitAfterPONR(final ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException;
446   
447   /**
448    * This will be called before the roll back of the split region is completed 
449    * @param ctx
450    * @throws IOException
451    */
452   void preRollBackSplit(final ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException;
453 
454   /**
455    * This will be called after the roll back of the split region is completed
456    * @param ctx
457    * @throws IOException
458    */
459   void postRollBackSplit(final ObserverContext<RegionCoprocessorEnvironment> ctx)
460     throws IOException;
461 
462   /**
463    * Called after any split request is processed.  This will be called irrespective of success or
464    * failure of the split.
465    * @param ctx
466    * @throws IOException
467    */
468   void postCompleteSplit(final ObserverContext<RegionCoprocessorEnvironment> ctx)
469     throws IOException;
470   /**
471    * Called before the region is reported as closed to the master.
472    * @param c the environment provided by the region server
473    * @param abortRequested true if the region server is aborting
474    * @throws IOException 
475    */
476   void preClose(final ObserverContext<RegionCoprocessorEnvironment> c,
477       boolean abortRequested) throws IOException;
478 
479   /**
480    * Called after the region is reported as closed to the master.
481    * @param c the environment provided by the region server
482    * @param abortRequested true if the region server is aborting
483    */
484   void postClose(final ObserverContext<RegionCoprocessorEnvironment> c,
485       boolean abortRequested);
486 
487   /**
488    * Called before a client makes a GetClosestRowBefore request.
489    * <p>
490    * Call CoprocessorEnvironment#bypass to skip default actions
491    * <p>
492    * Call CoprocessorEnvironment#complete to skip any subsequent chained
493    * coprocessors
494    * @param c the environment provided by the region server
495    * @param row the row
496    * @param family the family
497    * @param result The result to return to the client if default processing
498    * is bypassed. Can be modified. Will not be used if default processing
499    * is not bypassed.
500    * @throws IOException if an error occurred on the coprocessor
501    */
502   void preGetClosestRowBefore(final ObserverContext<RegionCoprocessorEnvironment> c,
503       final byte [] row, final byte [] family, final Result result)
504     throws IOException;
505 
506   /**
507    * Called after a client makes a GetClosestRowBefore request.
508    * <p>
509    * Call CoprocessorEnvironment#complete to skip any subsequent chained
510    * coprocessors
511    * @param c the environment provided by the region server
512    * @param row the row
513    * @param family the desired family
514    * @param result the result to return to the client, modify as necessary
515    * @throws IOException if an error occurred on the coprocessor
516    */
517   void postGetClosestRowBefore(final ObserverContext<RegionCoprocessorEnvironment> c,
518       final byte [] row, final byte [] family, final Result result)
519     throws IOException;
520 
521   /**
522    * Called before the client performs a Get
523    * <p>
524    * Call CoprocessorEnvironment#bypass to skip default actions
525    * <p>
526    * Call CoprocessorEnvironment#complete to skip any subsequent chained
527    * coprocessors
528    * @param c the environment provided by the region server
529    * @param get the Get request
530    * @param result The result to return to the client if default processing
531    * is bypassed. Can be modified. Will not be used if default processing
532    * is not bypassed.
533    * @throws IOException if an error occurred on the coprocessor
534    */
535   void preGetOp(final ObserverContext<RegionCoprocessorEnvironment> c, final Get get,
536       final List<Cell> result)
537     throws IOException;
538 
539   /**
540    * Called after the client performs a Get
541    * <p>
542    * Call CoprocessorEnvironment#complete to skip any subsequent chained
543    * coprocessors
544    * @param c the environment provided by the region server
545    * @param get the Get request
546    * @param result the result to return to the client, modify as necessary
547    * @throws IOException if an error occurred on the coprocessor
548    */
549   void postGetOp(final ObserverContext<RegionCoprocessorEnvironment> c, final Get get,
550       final List<Cell> result)
551     throws IOException;
552 
553   /**
554    * Called before the client tests for existence using a Get.
555    * <p>
556    * Call CoprocessorEnvironment#bypass to skip default actions
557    * <p>
558    * Call CoprocessorEnvironment#complete to skip any subsequent chained
559    * coprocessors
560    * @param c the environment provided by the region server
561    * @param get the Get request
562    * @param exists
563    * @return the value to return to the client if bypassing default processing
564    * @throws IOException if an error occurred on the coprocessor
565    */
566   boolean preExists(final ObserverContext<RegionCoprocessorEnvironment> c, final Get get,
567       final boolean exists)
568     throws IOException;
569 
570   /**
571    * Called after the client tests for existence using a Get.
572    * <p>
573    * Call CoprocessorEnvironment#complete to skip any subsequent chained
574    * coprocessors
575    * @param c the environment provided by the region server
576    * @param get the Get request
577    * @param exists the result returned by the region server
578    * @return the result to return to the client
579    * @throws IOException if an error occurred on the coprocessor
580    */
581   boolean postExists(final ObserverContext<RegionCoprocessorEnvironment> c, final Get get,
582       final boolean exists)
583     throws IOException;
584 
585   /**
586    * Called before the client stores a value.
587    * <p>
588    * Call CoprocessorEnvironment#bypass to skip default actions
589    * <p>
590    * Call CoprocessorEnvironment#complete to skip any subsequent chained
591    * coprocessors
592    * @param c the environment provided by the region server
593    * @param put The Put object
594    * @param edit The WALEdit object that will be written to the wal
595    * @param durability Persistence guarantee for this Put
596    * @throws IOException if an error occurred on the coprocessor
597    */
598   void prePut(final ObserverContext<RegionCoprocessorEnvironment> c, 
599       final Put put, final WALEdit edit, final Durability durability)
600     throws IOException;
601 
602   /**
603    * Called after the client stores a value.
604    * <p>
605    * Call CoprocessorEnvironment#complete to skip any subsequent chained
606    * coprocessors
607    * @param c the environment provided by the region server
608    * @param put The Put object
609    * @param edit The WALEdit object for the wal
610    * @param durability Persistence guarantee for this Put
611    * @throws IOException if an error occurred on the coprocessor
612    */
613   void postPut(final ObserverContext<RegionCoprocessorEnvironment> c, 
614       final Put put, final WALEdit edit, final Durability durability)
615     throws IOException;
616 
617   /**
618    * Called before the client deletes a value.
619    * <p>
620    * Call CoprocessorEnvironment#bypass to skip default actions
621    * <p>
622    * Call CoprocessorEnvironment#complete to skip any subsequent chained
623    * coprocessors
624    * @param c the environment provided by the region server
625    * @param delete The Delete object
626    * @param edit The WALEdit object for the wal
627    * @param durability Persistence guarantee for this Delete
628    * @throws IOException if an error occurred on the coprocessor
629    */
630   void preDelete(final ObserverContext<RegionCoprocessorEnvironment> c, 
631       final Delete delete, final WALEdit edit, final Durability durability)
632     throws IOException;
633 /**
634  * Called before the server updates the timestamp for version delete with latest timestamp.
635  * <p>
636  * Call CoprocessorEnvironment#bypass to skip default actions
637  * <p>
638  * Call CoprocessorEnvironment#complete to skip any subsequent chained
639  * coprocessors
640  * @param c the environment provided by the region server
641  * @param mutation - the parent mutation associated with this delete cell
642  * @param cell - The deleteColumn with latest version cell
643  * @param byteNow - timestamp bytes
644  * @param get - the get formed using the current cell's row.
645  * Note that the get does not specify the family and qualifier
646  * @throws IOException
647  */
648   void prePrepareTimeStampForDeleteVersion(final ObserverContext<RegionCoprocessorEnvironment> c,
649       final Mutation mutation, final Cell cell, final byte[] byteNow,
650       final Get get) throws IOException;
651 
652   /**
653    * Called after the client deletes a value.
654    * <p>
655    * Call CoprocessorEnvironment#complete to skip any subsequent chained
656    * coprocessors
657    * @param c the environment provided by the region server
658    * @param delete The Delete object
659    * @param edit The WALEdit object for the wal
660    * @param durability Persistence guarantee for this Delete
661    * @throws IOException if an error occurred on the coprocessor
662    */
663   void postDelete(final ObserverContext<RegionCoprocessorEnvironment> c,
664       final Delete delete, final WALEdit edit, final Durability durability)
665     throws IOException;
666   
667   /**
668    * This will be called for every batch mutation operation happening at the server. This will be
669    * called after acquiring the locks on the mutating rows and after applying the proper timestamp
670    * for each Mutation at the server. The batch may contain Put/Delete. By setting OperationStatus
671    * of Mutations ({@link MiniBatchOperationInProgress#setOperationStatus(int, OperationStatus)}),
672    * {@link RegionObserver} can make Region to skip these Mutations.
673    * @param c the environment provided by the region server
674    * @param miniBatchOp batch of Mutations getting applied to region.
675    * @throws IOException if an error occurred on the coprocessor
676    */
677   void preBatchMutate(final ObserverContext<RegionCoprocessorEnvironment> c,
678       final MiniBatchOperationInProgress<Mutation> miniBatchOp) throws IOException;
679 
680   /**
681    * This will be called after applying a batch of Mutations on a region. The Mutations are added to
682    * memstore and WAL.
683    * @param c the environment provided by the region server
684    * @param miniBatchOp batch of Mutations applied to region.
685    * @throws IOException if an error occurred on the coprocessor
686    */
687   void postBatchMutate(final ObserverContext<RegionCoprocessorEnvironment> c,
688       final MiniBatchOperationInProgress<Mutation> miniBatchOp) throws IOException;
689 
690   /**
691    * This will be called for region operations where read lock is acquired in
692    * {@link Region#startRegionOperation()}.
693    * @param ctx
694    * @param operation The operation is about to be taken on the region
695    * @throws IOException
696    */
697   void postStartRegionOperation(final ObserverContext<RegionCoprocessorEnvironment> ctx,
698       Operation operation) throws IOException;
699 
700   /**
701    * Called after releasing read lock in {@link Region#closeRegionOperation()}.
702    * @param ctx
703    * @param operation
704    * @throws IOException
705    */
706   void postCloseRegionOperation(final ObserverContext<RegionCoprocessorEnvironment> ctx,
707       Operation operation) throws IOException;
708 
709   /**
710    * Called after the completion of batch put/delete and will be called even if the batch operation
711    * fails
712    * @param ctx
713    * @param miniBatchOp 
714    * @param success true if batch operation is successful otherwise false.
715    * @throws IOException
716    */
717   void postBatchMutateIndispensably(final ObserverContext<RegionCoprocessorEnvironment> ctx,
718       MiniBatchOperationInProgress<Mutation> miniBatchOp, final boolean success) throws IOException;
719 
720   /**
721    * Called before checkAndPut.
722    * <p>
723    * Call CoprocessorEnvironment#bypass to skip default actions
724    * <p>
725    * Call CoprocessorEnvironment#complete to skip any subsequent chained
726    * coprocessors
727    * @param c the environment provided by the region server
728    * @param row row to check
729    * @param family column family
730    * @param qualifier column qualifier
731    * @param compareOp the comparison operation
732    * @param comparator the comparator
733    * @param put data to put if check succeeds
734    * @param result 
735    * @return the return value to return to client if bypassing default
736    * processing
737    * @throws IOException if an error occurred on the coprocessor
738    */
739   boolean preCheckAndPut(final ObserverContext<RegionCoprocessorEnvironment> c,
740       final byte [] row, final byte [] family, final byte [] qualifier,
741       final CompareOp compareOp, final ByteArrayComparable comparator,
742       final Put put, final boolean result)
743     throws IOException;
744 
745   /**
746    * Called before checkAndPut but after acquiring rowlock.
747    * <p>
748    * <b>Note:</b> Caution to be taken for not doing any long time operation in this hook. 
749    * Row will be locked for longer time. Trying to acquire lock on another row, within this, 
750    * can lead to potential deadlock.
751    * <p>
752    * Call CoprocessorEnvironment#bypass to skip default actions
753    * <p>
754    * Call CoprocessorEnvironment#complete to skip any subsequent chained
755    * coprocessors
756    * @param c the environment provided by the region server
757    * @param row row to check
758    * @param family column family
759    * @param qualifier column qualifier
760    * @param compareOp the comparison operation
761    * @param comparator the comparator
762    * @param put data to put if check succeeds
763    * @param result 
764    * @return the return value to return to client if bypassing default
765    * processing
766    * @throws IOException if an error occurred on the coprocessor
767    */
768   boolean preCheckAndPutAfterRowLock(final ObserverContext<RegionCoprocessorEnvironment> c,
769       final byte[] row, final byte[] family, final byte[] qualifier, final CompareOp compareOp,
770       final ByteArrayComparable comparator, final Put put, 
771       final boolean result) throws IOException;
772 
773   /**
774    * Called after checkAndPut
775    * <p>
776    * Call CoprocessorEnvironment#complete to skip any subsequent chained
777    * coprocessors
778    * @param c the environment provided by the region server
779    * @param row row to check
780    * @param family column family
781    * @param qualifier column qualifier
782    * @param compareOp the comparison operation
783    * @param comparator the comparator
784    * @param put data to put if check succeeds
785    * @param result from the checkAndPut
786    * @return the possibly transformed return value to return to client
787    * @throws IOException if an error occurred on the coprocessor
788    */
789   boolean postCheckAndPut(final ObserverContext<RegionCoprocessorEnvironment> c,
790       final byte [] row, final byte [] family, final byte [] qualifier,
791       final CompareOp compareOp, final ByteArrayComparable comparator,
792       final Put put, final boolean result)
793     throws IOException;
794 
795   /**
796    * Called before checkAndDelete.
797    * <p>
798    * Call CoprocessorEnvironment#bypass to skip default actions
799    * <p>
800    * Call CoprocessorEnvironment#complete to skip any subsequent chained
801    * coprocessors
802    * @param c the environment provided by the region server
803    * @param row row to check
804    * @param family column family
805    * @param qualifier column qualifier
806    * @param compareOp the comparison operation
807    * @param comparator the comparator
808    * @param delete delete to commit if check succeeds
809    * @param result 
810    * @return the value to return to client if bypassing default processing
811    * @throws IOException if an error occurred on the coprocessor
812    */
813   boolean preCheckAndDelete(final ObserverContext<RegionCoprocessorEnvironment> c,
814       final byte [] row, final byte [] family, final byte [] qualifier,
815       final CompareOp compareOp, final ByteArrayComparable comparator,
816       final Delete delete, final boolean result)
817     throws IOException;
818 
819   /**
820    * Called before checkAndDelete but after acquiring rowock.
821    * <p>
822    * <b>Note:</b> Caution to be taken for not doing any long time operation in this hook. 
823    * Row will be locked for longer time. Trying to acquire lock on another row, within this, 
824    * can lead to potential deadlock.
825    * <p>
826    * Call CoprocessorEnvironment#bypass to skip default actions
827    * <p>
828    * Call CoprocessorEnvironment#complete to skip any subsequent chained
829    * coprocessors
830    * @param c the environment provided by the region server
831    * @param row row to check
832    * @param family column family
833    * @param qualifier column qualifier
834    * @param compareOp the comparison operation
835    * @param comparator the comparator
836    * @param delete delete to commit if check succeeds
837    * @param result 
838    * @return the value to return to client if bypassing default processing
839    * @throws IOException if an error occurred on the coprocessor
840    */
841   boolean preCheckAndDeleteAfterRowLock(final ObserverContext<RegionCoprocessorEnvironment> c,
842       final byte[] row, final byte[] family, final byte[] qualifier, final CompareOp compareOp,
843       final ByteArrayComparable comparator, final Delete delete,
844       final boolean result) throws IOException;
845 
846   /**
847    * Called after checkAndDelete
848    * <p>
849    * Call CoprocessorEnvironment#complete to skip any subsequent chained
850    * coprocessors
851    * @param c the environment provided by the region server
852    * @param row row to check
853    * @param family column family
854    * @param qualifier column qualifier
855    * @param compareOp the comparison operation
856    * @param comparator the comparator
857    * @param delete delete to commit if check succeeds
858    * @param result from the CheckAndDelete
859    * @return the possibly transformed returned value to return to client
860    * @throws IOException if an error occurred on the coprocessor
861    */
862   boolean postCheckAndDelete(final ObserverContext<RegionCoprocessorEnvironment> c,
863       final byte [] row, final byte [] family, final byte [] qualifier,
864       final CompareOp compareOp, final ByteArrayComparable comparator,
865       final Delete delete, final boolean result)
866     throws IOException;
867 
868   /**
869    * Called before incrementColumnValue
870    * <p>
871    * Call CoprocessorEnvironment#bypass to skip default actions
872    * <p>
873    * Call CoprocessorEnvironment#complete to skip any subsequent chained
874    * coprocessors
875    * @param c the environment provided by the region server
876    * @param row row to check
877    * @param family column family
878    * @param qualifier column qualifier
879    * @param amount long amount to increment
880    * @param writeToWAL true if the change should be written to the WAL
881    * @return value to return to the client if bypassing default processing
882    * @throws IOException if an error occurred on the coprocessor
883    * @deprecated This hook is no longer called by the RegionServer
884    */
885   @Deprecated
886   long preIncrementColumnValue(final ObserverContext<RegionCoprocessorEnvironment> c,
887       final byte [] row, final byte [] family, final byte [] qualifier,
888       final long amount, final boolean writeToWAL)
889     throws IOException;
890 
891   /**
892    * Called after incrementColumnValue
893    * <p>
894    * Call CoprocessorEnvironment#complete to skip any subsequent chained
895    * coprocessors
896    * @param c the environment provided by the region server
897    * @param row row to check
898    * @param family column family
899    * @param qualifier column qualifier
900    * @param amount long amount to increment
901    * @param writeToWAL true if the change should be written to the WAL
902    * @param result the result returned by incrementColumnValue
903    * @return the result to return to the client
904    * @throws IOException if an error occurred on the coprocessor
905    * @deprecated This hook is no longer called by the RegionServer
906    */
907   @Deprecated
908   long postIncrementColumnValue(final ObserverContext<RegionCoprocessorEnvironment> c,
909       final byte [] row, final byte [] family, final byte [] qualifier,
910       final long amount, final boolean writeToWAL, final long result)
911     throws IOException;
912 
913   /**
914    * Called before Append.
915    * <p>
916    * Call CoprocessorEnvironment#bypass to skip default actions
917    * <p>
918    * Call CoprocessorEnvironment#complete to skip any subsequent chained
919    * coprocessors
920    * @param c the environment provided by the region server
921    * @param append Append object
922    * @return result to return to the client if bypassing default processing
923    * @throws IOException if an error occurred on the coprocessor
924    */
925   Result preAppend(final ObserverContext<RegionCoprocessorEnvironment> c,
926       final Append append)
927     throws IOException;
928 
929   /**
930    * Called before Append but after acquiring rowlock.
931    * <p>
932    * <b>Note:</b> Caution to be taken for not doing any long time operation in this hook. 
933    * Row will be locked for longer time. Trying to acquire lock on another row, within this, 
934    * can lead to potential deadlock.
935    * <p>
936    * Call CoprocessorEnvironment#bypass to skip default actions
937    * <p>
938    * Call CoprocessorEnvironment#complete to skip any subsequent chained
939    * coprocessors
940    * @param c the environment provided by the region server
941    * @param append Append object
942    * @return result to return to the client if bypassing default processing
943    * @throws IOException if an error occurred on the coprocessor
944    */
945   Result preAppendAfterRowLock(final ObserverContext<RegionCoprocessorEnvironment> c,
946       final Append append) throws IOException;
947 
948   /**
949    * Called after Append
950    * <p>
951    * Call CoprocessorEnvironment#complete to skip any subsequent chained
952    * coprocessors
953    * @param c the environment provided by the region server
954    * @param append Append object
955    * @param result the result returned by increment
956    * @return the result to return to the client
957    * @throws IOException if an error occurred on the coprocessor
958    */
959   Result postAppend(final ObserverContext<RegionCoprocessorEnvironment> c,
960       final Append append, final Result result)
961     throws IOException;
962 
963   /**
964    * Called before Increment.
965    * <p>
966    * Call CoprocessorEnvironment#bypass to skip default actions
967    * <p>
968    * Call CoprocessorEnvironment#complete to skip any subsequent chained
969    * coprocessors
970    * @param c the environment provided by the region server
971    * @param increment increment object
972    * @return result to return to the client if bypassing default processing
973    * @throws IOException if an error occurred on the coprocessor
974    */
975   Result preIncrement(final ObserverContext<RegionCoprocessorEnvironment> c,
976       final Increment increment)
977     throws IOException;
978 
979   /**
980    * Called before Increment but after acquiring rowlock.
981    * <p>
982    * <b>Note:</b> Caution to be taken for not doing any long time operation in this hook. 
983    * Row will be locked for longer time. Trying to acquire lock on another row, within this, 
984    * can lead to potential deadlock.
985    * <p>
986    * Call CoprocessorEnvironment#bypass to skip default actions
987    * <p>
988    * Call CoprocessorEnvironment#complete to skip any subsequent chained coprocessors
989    * 
990    * @param c
991    *          the environment provided by the region server
992    * @param increment
993    *          increment object
994    * @return result to return to the client if bypassing default processing
995    * @throws IOException
996    *           if an error occurred on the coprocessor
997    */
998   Result preIncrementAfterRowLock(final ObserverContext<RegionCoprocessorEnvironment> c,
999       final Increment increment) throws IOException;
1000 
1001   /**
1002    * Called after increment
1003    * <p>
1004    * Call CoprocessorEnvironment#complete to skip any subsequent chained
1005    * coprocessors
1006    * @param c the environment provided by the region server
1007    * @param increment increment object
1008    * @param result the result returned by increment
1009    * @return the result to return to the client
1010    * @throws IOException if an error occurred on the coprocessor
1011    */
1012   Result postIncrement(final ObserverContext<RegionCoprocessorEnvironment> c,
1013       final Increment increment, final Result result)
1014     throws IOException;
1015 
1016   /**
1017    * Called before the client opens a new scanner.
1018    * <p>
1019    * Call CoprocessorEnvironment#bypass to skip default actions
1020    * <p>
1021    * Call CoprocessorEnvironment#complete to skip any subsequent chained
1022    * coprocessors
1023    * @param c the environment provided by the region server
1024    * @param scan the Scan specification
1025    * @param s if not null, the base scanner
1026    * @return an RegionScanner instance to use instead of the base scanner if
1027    * overriding default behavior, null otherwise
1028    * @throws IOException if an error occurred on the coprocessor
1029    */
1030   RegionScanner preScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c,
1031       final Scan scan, final RegionScanner s)
1032     throws IOException;
1033 
1034   /**
1035    * Called before a store opens a new scanner.
1036    * This hook is called when a "user" scanner is opened.
1037    * <p>
1038    * See {@link #preFlushScannerOpen(ObserverContext, Store, KeyValueScanner, InternalScanner,
1039    * long)} and {@link #preCompactScannerOpen(ObserverContext,
1040    *  Store, List, ScanType, long, InternalScanner, CompactionRequest, long)}
1041    * to override scanners created for flushes or compactions, resp.
1042    * <p>
1043    * Call CoprocessorEnvironment#complete to skip any subsequent chained
1044    * coprocessors.
1045    * Calling {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} has no
1046    * effect in this hook.
1047    * @param c the environment provided by the region server
1048    * @param store the store being scanned
1049    * @param scan the Scan specification
1050    * @param targetCols columns to be used in the scanner
1051    * @param s the base scanner, if not {@code null}, from previous RegionObserver in the chain
1052    * @return a KeyValueScanner instance to use or {@code null} to use the default implementation
1053    * @throws IOException if an error occurred on the coprocessor
1054    */
1055   KeyValueScanner preStoreScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c,
1056       final Store store, final Scan scan, final NavigableSet<byte[]> targetCols,
1057       final KeyValueScanner s) throws IOException;
1058 
1059   /**
1060    * Called after the client opens a new scanner.
1061    * <p>
1062    * Call CoprocessorEnvironment#complete to skip any subsequent chained
1063    * coprocessors
1064    * @param c the environment provided by the region server
1065    * @param scan the Scan specification
1066    * @param s if not null, the base scanner
1067    * @return the scanner instance to use
1068    * @throws IOException if an error occurred on the coprocessor
1069    */
1070   RegionScanner postScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c,
1071       final Scan scan, final RegionScanner s)
1072     throws IOException;
1073 
1074   /**
1075    * Called before the client asks for the next row on a scanner.
1076    * <p>
1077    * Call CoprocessorEnvironment#bypass to skip default actions
1078    * <p>
1079    * Call CoprocessorEnvironment#complete to skip any subsequent chained
1080    * coprocessors
1081    * @param c the environment provided by the region server
1082    * @param s the scanner
1083    * @param result The result to return to the client if default processing
1084    * is bypassed. Can be modified. Will not be returned if default processing
1085    * is not bypassed.
1086    * @param limit the maximum number of results to return
1087    * @param hasNext the 'has more' indication
1088    * @return 'has more' indication that should be sent to client
1089    * @throws IOException if an error occurred on the coprocessor
1090    */
1091   boolean preScannerNext(final ObserverContext<RegionCoprocessorEnvironment> c,
1092       final InternalScanner s, final List<Result> result,
1093       final int limit, final boolean hasNext)
1094     throws IOException;
1095 
1096   /**
1097    * Called after the client asks for the next row on a scanner.
1098    * <p>
1099    * Call CoprocessorEnvironment#complete to skip any subsequent chained
1100    * coprocessors
1101    * @param c the environment provided by the region server
1102    * @param s the scanner
1103    * @param result the result to return to the client, can be modified
1104    * @param limit the maximum number of results to return
1105    * @param hasNext the 'has more' indication
1106    * @return 'has more' indication that should be sent to client
1107    * @throws IOException if an error occurred on the coprocessor
1108    */
1109   boolean postScannerNext(final ObserverContext<RegionCoprocessorEnvironment> c,
1110       final InternalScanner s, final List<Result> result, final int limit,
1111       final boolean hasNext)
1112     throws IOException;
1113 
1114   /**
1115    * This will be called by the scan flow when the current scanned row is being filtered out by the
1116    * filter. The filter may be filtering out the row via any of the below scenarios
1117    * <ol>
1118    * <li>
1119    * <code>boolean filterRowKey(byte [] buffer, int offset, int length)</code> returning true</li>
1120    * <li>
1121    * <code>boolean filterRow()</code> returning true</li>
1122    * <li>
1123    * <code>void filterRow(List&lt;KeyValue&gt; kvs)</code> removing all the kvs
1124    * from the passed List</li>
1125    * </ol>
1126    * @param c the environment provided by the region server
1127    * @param s the scanner
1128    * @param currentRow The current rowkey which got filtered out
1129    * @param offset offset to rowkey
1130    * @param length length of rowkey
1131    * @param hasMore the 'has more' indication
1132    * @return whether more rows are available for the scanner or not
1133    * @throws IOException
1134    */
1135   boolean postScannerFilterRow(final ObserverContext<RegionCoprocessorEnvironment> c,
1136       final InternalScanner s, final byte[] currentRow, final int offset, final short length,
1137       final boolean hasMore) throws IOException;
1138 
1139   /**
1140    * Called before the client closes a scanner.
1141    * <p>
1142    * Call CoprocessorEnvironment#bypass to skip default actions
1143    * <p>
1144    * Call CoprocessorEnvironment#complete to skip any subsequent chained
1145    * coprocessors
1146    * @param c the environment provided by the region server
1147    * @param s the scanner
1148    * @throws IOException if an error occurred on the coprocessor
1149    */
1150   void preScannerClose(final ObserverContext<RegionCoprocessorEnvironment> c,
1151       final InternalScanner s)
1152     throws IOException;
1153 
1154   /**
1155    * Called after the client closes a scanner.
1156    * <p>
1157    * Call CoprocessorEnvironment#complete to skip any subsequent chained
1158    * coprocessors
1159    * @param c the environment provided by the region server
1160    * @param s the scanner
1161    * @throws IOException if an error occurred on the coprocessor
1162    */
1163   void postScannerClose(final ObserverContext<RegionCoprocessorEnvironment> c,
1164       final InternalScanner s)
1165     throws IOException;
1166 
1167   /**
1168    * Called before a {@link org.apache.hadoop.hbase.regionserver.wal.WALEdit}
1169    * replayed for this region.
1170    */
1171   void preWALRestore(final ObserverContext<? extends RegionCoprocessorEnvironment> ctx,
1172       HRegionInfo info, WALKey logKey, WALEdit logEdit) throws IOException;
1173 
1174   /**
1175    * Called before a {@link org.apache.hadoop.hbase.regionserver.wal.WALEdit}
1176    * replayed for this region.
1177    *
1178    * This method is left in place to maintain binary compatibility with older
1179    * {@link RegionObserver}s. If an implementation directly overrides
1180    * {@link #preWALRestore(ObserverContext, HRegionInfo, WALKey, WALEdit)} then this version
1181    * won't be called at all, barring problems with the Security Manager. To work correctly
1182    * in the presence of a strict Security Manager, or in the case of an implementation that
1183    * relies on a parent class to implement preWALRestore, you should implement this method
1184    * as a call to the non-deprecated version.
1185    *
1186    * Users of this method will see all edits that can be treated as HLogKey. If there are
1187    * edits that can't be treated as HLogKey they won't be offered to coprocessors that rely
1188    * on this method. If a coprocessor gets skipped because of this mechanism, a log message
1189    * at ERROR will be generated per coprocessor on the logger for {@link CoprocessorHost} once per
1190    * classloader.
1191    *
1192    * @deprecated use {@link #preWALRestore(ObserverContext, HRegionInfo, WALKey, WALEdit)}
1193    */
1194   @Deprecated
1195   void preWALRestore(final ObserverContext<RegionCoprocessorEnvironment> ctx,
1196       HRegionInfo info, HLogKey logKey, WALEdit logEdit) throws IOException;
1197 
1198   /**
1199    * Called after a {@link org.apache.hadoop.hbase.regionserver.wal.WALEdit}
1200    * replayed for this region.
1201    */
1202   void postWALRestore(final ObserverContext<? extends RegionCoprocessorEnvironment> ctx,
1203       HRegionInfo info, WALKey logKey, WALEdit logEdit) throws IOException;
1204 
1205   /**
1206    * Called after a {@link org.apache.hadoop.hbase.regionserver.wal.WALEdit}
1207    * replayed for this region.
1208    *
1209    * This method is left in place to maintain binary compatibility with older
1210    * {@link RegionObserver}s. If an implementation directly overrides
1211    * {@link #postWALRestore(ObserverContext, HRegionInfo, WALKey, WALEdit)} then this version
1212    * won't be called at all, barring problems with the Security Manager. To work correctly
1213    * in the presence of a strict Security Manager, or in the case of an implementation that
1214    * relies on a parent class to implement preWALRestore, you should implement this method
1215    * as a call to the non-deprecated version.
1216    *
1217    * Users of this method will see all edits that can be treated as HLogKey. If there are
1218    * edits that can't be treated as HLogKey they won't be offered to coprocessors that rely
1219    * on this method. If a coprocessor gets skipped because of this mechanism, a log message
1220    * at ERROR will be generated per coprocessor on the logger for {@link CoprocessorHost} once per
1221    * classloader.
1222    *
1223    * @deprecated use {@link #postWALRestore(ObserverContext, HRegionInfo, WALKey, WALEdit)}
1224    */
1225   @Deprecated
1226   void postWALRestore(final ObserverContext<RegionCoprocessorEnvironment> ctx,
1227       HRegionInfo info, HLogKey logKey, WALEdit logEdit) throws IOException;
1228 
1229   /**
1230    * Called before bulkLoadHFile. Users can create a StoreFile instance to
1231    * access the contents of a HFile.
1232    *
1233    * @param ctx
1234    * @param familyPaths pairs of { CF, HFile path } submitted for bulk load. Adding
1235    * or removing from this list will add or remove HFiles to be bulk loaded.
1236    * @throws IOException
1237    */
1238   void preBulkLoadHFile(final ObserverContext<RegionCoprocessorEnvironment> ctx,
1239     List<Pair<byte[], String>> familyPaths) throws IOException;
1240 
1241   /**
1242    * Called before moving bulk loaded hfile to region directory.
1243    *
1244    * @param ctx
1245    * @param family column family
1246    * @param pairs List of pairs of { HFile location in staging dir, HFile path in region dir }
1247    * Each pair are for the same hfile.
1248    * @throws IOException
1249    */
1250   void preCommitStoreFile(final ObserverContext<RegionCoprocessorEnvironment> ctx,
1251       final byte[] family, final List<Pair<Path, Path>> pairs) throws IOException;
1252 
1253   /**
1254    * Called after moving bulk loaded hfile to region directory.
1255    *
1256    * @param ctx
1257    * @param family column family
1258    * @param srcPath Path to file before the move
1259    * @param dstPath Path to file after the move
1260    */
1261   void postCommitStoreFile(final ObserverContext<RegionCoprocessorEnvironment> ctx,
1262       final byte[] family, Path srcPath, Path dstPath) throws IOException;
1263 
1264   /**
1265    * Called after bulkLoadHFile.
1266    *
1267    * @param ctx
1268    * @param familyPaths pairs of { CF, HFile path } submitted for bulk load
1269    * @param hasLoaded whether the bulkLoad was successful
1270    * @return the new value of hasLoaded
1271    * @throws IOException
1272    */
1273   boolean postBulkLoadHFile(final ObserverContext<RegionCoprocessorEnvironment> ctx,
1274     List<Pair<byte[], String>> familyPaths, boolean hasLoaded) throws IOException;
1275 
1276   /**
1277    * Called before creation of Reader for a store file.
1278    * Calling {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} has no
1279    * effect in this hook.
1280    * 
1281    * @param ctx the environment provided by the region server
1282    * @param fs fileystem to read from
1283    * @param p path to the file
1284    * @param in {@link FSDataInputStreamWrapper}
1285    * @param size Full size of the file
1286    * @param cacheConf
1287    * @param r original reference file. This will be not null only when reading a split file.
1288    * @param reader the base reader, if not {@code null}, from previous RegionObserver in the chain
1289    * @return a Reader instance to use instead of the base reader if overriding
1290    * default behavior, null otherwise
1291    * @throws IOException
1292    */
1293   StoreFile.Reader preStoreFileReaderOpen(final ObserverContext<RegionCoprocessorEnvironment> ctx,
1294       final FileSystem fs, final Path p, final FSDataInputStreamWrapper in, long size,
1295       final CacheConfig cacheConf, final Reference r, StoreFile.Reader reader) throws IOException;
1296 
1297   /**
1298    * Called after the creation of Reader for a store file.
1299    * 
1300    * @param ctx the environment provided by the region server
1301    * @param fs fileystem to read from
1302    * @param p path to the file
1303    * @param in {@link FSDataInputStreamWrapper}
1304    * @param size Full size of the file
1305    * @param cacheConf
1306    * @param r original reference file. This will be not null only when reading a split file.
1307    * @param reader the base reader instance
1308    * @return The reader to use
1309    * @throws IOException
1310    */
1311   StoreFile.Reader postStoreFileReaderOpen(final ObserverContext<RegionCoprocessorEnvironment> ctx,
1312       final FileSystem fs, final Path p, final FSDataInputStreamWrapper in, long size,
1313       final CacheConfig cacheConf, final Reference r, StoreFile.Reader reader) throws IOException;
1314 
1315   /**
1316    * Called after a new cell has been created during an increment operation, but before
1317    * it is committed to the WAL or memstore.
1318    * Calling {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} has no
1319    * effect in this hook.
1320    * @param ctx the environment provided by the region server
1321    * @param opType the operation type
1322    * @param mutation the current mutation
1323    * @param oldCell old cell containing previous value
1324    * @param newCell the new cell containing the computed value
1325    * @return the new cell, possibly changed
1326    * @throws IOException
1327    */
1328   Cell postMutationBeforeWAL(ObserverContext<RegionCoprocessorEnvironment> ctx,
1329       MutationType opType, Mutation mutation, Cell oldCell, Cell newCell) throws IOException;
1330 
1331   /**
1332    * Called after the ScanQueryMatcher creates ScanDeleteTracker. Implementing
1333    * this hook would help in creating customised DeleteTracker and returning
1334    * the newly created DeleteTracker
1335    *
1336    * @param ctx the environment provided by the region server
1337    * @param delTracker the deleteTracker that is created by the QueryMatcher
1338    * @return the Delete Tracker
1339    * @throws IOException
1340    */
1341   DeleteTracker postInstantiateDeleteTracker(
1342       final ObserverContext<RegionCoprocessorEnvironment> ctx, DeleteTracker delTracker)
1343       throws IOException;
1344 
1345   /**
1346    * Called just before the WAL Entry is appended to the WAL. Implementing this hook allows
1347    * coprocessors to add extended attributes to the WALKey that then get persisted to the
1348    * WAL, and are available to replication endpoints to use in processing WAL Entries.
1349    * @param ctx the environment provided by the region server
1350    * @param key the WALKey associated with a particular append to a WAL
1351    * @param edit the WALEdit associated with a particular append to a WAL
1352    */
1353   void preWALAppend(ObserverContext<RegionCoprocessorEnvironment> ctx, WALKey key,
1354                             WALEdit edit)
1355       throws IOException;
1356 }