View Javadoc

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