001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.coprocessor;
019
020import java.io.IOException;
021import java.util.ArrayList;
022import java.util.List;
023import java.util.Map;
024import org.apache.hadoop.fs.FileSystem;
025import org.apache.hadoop.fs.Path;
026import org.apache.hadoop.hbase.Cell;
027import org.apache.hadoop.hbase.CompareOperator;
028import org.apache.hadoop.hbase.HBaseInterfaceAudience;
029import org.apache.hadoop.hbase.client.Append;
030import org.apache.hadoop.hbase.client.CheckAndMutate;
031import org.apache.hadoop.hbase.client.CheckAndMutateResult;
032import org.apache.hadoop.hbase.client.Delete;
033import org.apache.hadoop.hbase.client.Durability;
034import org.apache.hadoop.hbase.client.Get;
035import org.apache.hadoop.hbase.client.Increment;
036import org.apache.hadoop.hbase.client.Mutation;
037import org.apache.hadoop.hbase.client.Put;
038import org.apache.hadoop.hbase.client.RegionInfo;
039import org.apache.hadoop.hbase.client.Result;
040import org.apache.hadoop.hbase.client.Scan;
041import org.apache.hadoop.hbase.filter.BinaryComparator;
042import org.apache.hadoop.hbase.filter.ByteArrayComparable;
043import org.apache.hadoop.hbase.filter.Filter;
044import org.apache.hadoop.hbase.io.FSDataInputStreamWrapper;
045import org.apache.hadoop.hbase.io.Reference;
046import org.apache.hadoop.hbase.io.hfile.CacheConfig;
047import org.apache.hadoop.hbase.regionserver.FlushLifeCycleTracker;
048import org.apache.hadoop.hbase.regionserver.InternalScanner;
049import org.apache.hadoop.hbase.regionserver.MiniBatchOperationInProgress;
050import org.apache.hadoop.hbase.regionserver.OperationStatus;
051import org.apache.hadoop.hbase.regionserver.Region;
052import org.apache.hadoop.hbase.regionserver.Region.Operation;
053import org.apache.hadoop.hbase.regionserver.RegionScanner;
054import org.apache.hadoop.hbase.regionserver.ScanOptions;
055import org.apache.hadoop.hbase.regionserver.ScanType;
056import org.apache.hadoop.hbase.regionserver.Shipper;
057import org.apache.hadoop.hbase.regionserver.Store;
058import org.apache.hadoop.hbase.regionserver.StoreFile;
059import org.apache.hadoop.hbase.regionserver.StoreFileReader;
060import org.apache.hadoop.hbase.regionserver.compactions.CompactionLifeCycleTracker;
061import org.apache.hadoop.hbase.regionserver.compactions.CompactionRequest;
062import org.apache.hadoop.hbase.regionserver.querymatcher.DeleteTracker;
063import org.apache.hadoop.hbase.util.Pair;
064import org.apache.hadoop.hbase.wal.WALEdit;
065import org.apache.hadoop.hbase.wal.WALKey;
066import org.apache.yetus.audience.InterfaceAudience;
067import org.apache.yetus.audience.InterfaceStability;
068
069/**
070 * Coprocessors implement this interface to observe and mediate client actions on the region.
071 * <p>
072 * Since most implementations will be interested in only a subset of hooks, this class uses
073 * 'default' functions to avoid having to add unnecessary overrides. When the functions are
074 * non-empty, it's simply to satisfy the compiler by returning value of expected (non-void) type. It
075 * is done in a way that these default definitions act as no-op. So our suggestion to implementation
076 * would be to not call these 'default' methods from overrides.
077 * <p>
078 * <h3>Exception Handling</h3><br>
079 * For all functions, exception handling is done as follows:
080 * <ul>
081 * <li>Exceptions of type {@link IOException} are reported back to client.</li>
082 * <li>For any other kind of exception:
083 * <ul>
084 * <li>If the configuration {@link CoprocessorHost#ABORT_ON_ERROR_KEY} is set to true, then the
085 * server aborts.</li>
086 * <li>Otherwise, coprocessor is removed from the server and
087 * {@link org.apache.hadoop.hbase.DoNotRetryIOException} is returned to the client.</li>
088 * </ul>
089 * </li>
090 * </ul>
091 * <p>
092 * <h3>For Split Related Hooks</h3> <br>
093 * In hbase2/AMv2, master runs splits, so the split related hooks are moved to
094 * {@link MasterObserver}.
095 * <p>
096 * <h3>Increment Column Value</h3><br>
097 * We do not call this hook anymore.
098 */
099@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.COPROC)
100@InterfaceStability.Evolving
101// TODO as method signatures need to break, update to
102// ObserverContext<? extends RegionCoprocessorEnvironment>
103// so we can use additional environment state that isn't exposed to coprocessors.
104public interface RegionObserver {
105  /** Mutation type for postMutationBeforeWAL hook */
106  enum MutationType {
107    APPEND,
108    INCREMENT
109  }
110
111  /**
112   * Called before the region is reported as open to the master.
113   * @param c the environment provided by the region server
114   */
115  default void preOpen(ObserverContext<RegionCoprocessorEnvironment> c) throws IOException {
116  }
117
118  /**
119   * Called after the region is reported as open to the master.
120   * @param c the environment provided by the region server
121   */
122  default void postOpen(ObserverContext<RegionCoprocessorEnvironment> c) {
123  }
124
125  /**
126   * Called before the memstore is flushed to disk.
127   * @param c       the environment provided by the region server
128   * @param tracker tracker used to track the life cycle of a flush
129   */
130  default void preFlush(final ObserverContext<RegionCoprocessorEnvironment> c,
131    FlushLifeCycleTracker tracker) throws IOException {
132  }
133
134  /**
135   * Called before we open store scanner for flush. You can use the {@code options} to change max
136   * versions and TTL for the scanner being opened.
137   * @param c       the environment provided by the region server
138   * @param store   the store where flush is being requested
139   * @param options used to change max versions and TTL for the scanner being opened
140   */
141  default void preFlushScannerOpen(ObserverContext<RegionCoprocessorEnvironment> c, Store store,
142    ScanOptions options, FlushLifeCycleTracker tracker) throws IOException {
143  }
144
145  /**
146   * Called before a Store's memstore is flushed to disk.
147   * @param c       the environment provided by the region server
148   * @param store   the store where flush is being requested
149   * @param scanner the scanner over existing data used in the memstore
150   * @param tracker tracker used to track the life cycle of a flush
151   * @return the scanner to use during flush. Should not be {@code null} unless the implementation
152   *         is writing new store files on its own.
153   */
154  default InternalScanner preFlush(ObserverContext<RegionCoprocessorEnvironment> c, Store store,
155    InternalScanner scanner, FlushLifeCycleTracker tracker) throws IOException {
156    return scanner;
157  }
158
159  /**
160   * Called after the memstore is flushed to disk.
161   * @param c       the environment provided by the region server
162   * @param tracker tracker used to track the life cycle of a flush
163   * @throws IOException if an error occurred on the coprocessor
164   */
165  default void postFlush(ObserverContext<RegionCoprocessorEnvironment> c,
166    FlushLifeCycleTracker tracker) throws IOException {
167  }
168
169  /**
170   * Called after a Store's memstore is flushed to disk.
171   * @param c          the environment provided by the region server
172   * @param store      the store being flushed
173   * @param resultFile the new store file written out during compaction
174   * @param tracker    tracker used to track the life cycle of a flush
175   */
176  default void postFlush(ObserverContext<RegionCoprocessorEnvironment> c, Store store,
177    StoreFile resultFile, FlushLifeCycleTracker tracker) throws IOException {
178  }
179
180  /**
181   * Called before in memory compaction started.
182   * @param c     the environment provided by the region server
183   * @param store the store where in memory compaction is being requested
184   */
185  default void preMemStoreCompaction(ObserverContext<RegionCoprocessorEnvironment> c, Store store)
186    throws IOException {
187  }
188
189  /**
190   * Called before we open store scanner for in memory compaction. You can use the {@code options}
191   * to change max versions and TTL for the scanner being opened. Notice that this method will only
192   * be called when you use {@code eager} mode. For {@code basic} mode we will not drop any cells
193   * thus we do not open a store scanner.
194   * @param c       the environment provided by the region server
195   * @param store   the store where in memory compaction is being requested
196   * @param options used to change max versions and TTL for the scanner being opened
197   */
198  default void preMemStoreCompactionCompactScannerOpen(
199    ObserverContext<RegionCoprocessorEnvironment> c, Store store, ScanOptions options)
200    throws IOException {
201  }
202
203  /**
204   * Called before we do in memory compaction. Notice that this method will only be called when you
205   * use {@code eager} mode. For {@code basic} mode we will not drop any cells thus there is no
206   * {@link InternalScanner}.
207   * @param c       the environment provided by the region server
208   * @param store   the store where in memory compaction is being executed
209   * @param scanner the scanner over existing data used in the memstore segments being compact
210   * @return the scanner to use during in memory compaction. Must be non-null.
211   */
212  default InternalScanner preMemStoreCompactionCompact(
213    ObserverContext<RegionCoprocessorEnvironment> c, Store store, InternalScanner scanner)
214    throws IOException {
215    return scanner;
216  }
217
218  /**
219   * Called after the in memory compaction is finished.
220   * @param c     the environment provided by the region server
221   * @param store the store where in memory compaction is being executed
222   */
223  default void postMemStoreCompaction(ObserverContext<RegionCoprocessorEnvironment> c, Store store)
224    throws IOException {
225  }
226
227  /**
228   * Called prior to selecting the {@link StoreFile StoreFiles} to compact from the list of
229   * available candidates. To alter the files used for compaction, you may mutate the passed in list
230   * of candidates. If you remove all the candidates then the compaction will be canceled.
231   * <p>
232   * Supports Coprocessor 'bypass' -- 'bypass' is how this method indicates that it changed the
233   * passed in <code>candidates</code>. If 'bypass' is set, we skip out on calling any subsequent
234   * chained coprocessors.
235   * @param c          the environment provided by the region server
236   * @param store      the store where compaction is being requested
237   * @param candidates the store files currently available for compaction
238   * @param tracker    tracker used to track the life cycle of a compaction
239   */
240  default void preCompactSelection(ObserverContext<RegionCoprocessorEnvironment> c, Store store,
241    List<? extends StoreFile> candidates, CompactionLifeCycleTracker tracker) throws IOException {
242  }
243
244  /**
245   * Called after the {@link StoreFile}s to compact have been selected from the available
246   * candidates.
247   * @param c        the environment provided by the region server
248   * @param store    the store being compacted
249   * @param selected the store files selected to compact
250   * @param tracker  tracker used to track the life cycle of a compaction
251   * @param request  the requested compaction
252   */
253  default void postCompactSelection(ObserverContext<RegionCoprocessorEnvironment> c, Store store,
254    List<? extends StoreFile> selected, CompactionLifeCycleTracker tracker,
255    CompactionRequest request) {
256  }
257
258  /**
259   * Called before we open store scanner for compaction. You can use the {@code options} to change
260   * max versions and TTL for the scanner being opened.
261   * @param c        the environment provided by the region server
262   * @param store    the store being compacted
263   * @param scanType type of Scan
264   * @param options  used to change max versions and TTL for the scanner being opened
265   * @param tracker  tracker used to track the life cycle of a compaction
266   * @param request  the requested compaction
267   */
268  default void preCompactScannerOpen(ObserverContext<RegionCoprocessorEnvironment> c, Store store,
269    ScanType scanType, ScanOptions options, CompactionLifeCycleTracker tracker,
270    CompactionRequest request) throws IOException {
271  }
272
273  /**
274   * Called prior to writing the {@link StoreFile}s selected for compaction into a new
275   * {@code StoreFile}.
276   * <p>
277   * To override or modify the compaction process, implementing classes can wrap the provided
278   * {@link InternalScanner} with a custom implementation that is returned from this method. The
279   * custom scanner can then inspect {@link org.apache.hadoop.hbase.Cell}s from the wrapped scanner,
280   * applying its own policy to what gets written.
281   * <p>
282   * If implementations are wrapping the passed in {@link InternalScanner}, they can also have their
283   * implementation implement {@link Shipper} and delegate to the original scanner. This will cause
284   * compactions to free up memory as they progress, which is especially important for people using
285   * off-heap memory pools.
286   * <p>
287   * Keep in mind that when {@link Shipper#shipped()} is called, any cell references you maintain in
288   * your implementation may get corrupted. As such you should make sure to deep clone any cells
289   * that you need to keep reference to across invocations of shipped.
290   * @param c        the environment provided by the region server
291   * @param store    the store being compacted
292   * @param scanner  the scanner over existing data used in the store file rewriting
293   * @param scanType type of Scan
294   * @param tracker  tracker used to track the life cycle of a compaction
295   * @param request  the requested compaction
296   * @return the scanner to use during compaction. Should not be {@code null} unless the
297   *         implementation is writing new store files on its own.
298   */
299  default InternalScanner preCompact(ObserverContext<RegionCoprocessorEnvironment> c, Store store,
300    InternalScanner scanner, ScanType scanType, CompactionLifeCycleTracker tracker,
301    CompactionRequest request) throws IOException {
302    return scanner;
303  }
304
305  /**
306   * Called after compaction has completed and the new store file has been moved in to place.
307   * @param c          the environment provided by the region server
308   * @param store      the store being compacted
309   * @param resultFile the new store file written out during compaction
310   * @param tracker    used to track the life cycle of a compaction
311   * @param request    the requested compaction
312   */
313  default void postCompact(ObserverContext<RegionCoprocessorEnvironment> c, Store store,
314    StoreFile resultFile, CompactionLifeCycleTracker tracker, CompactionRequest request)
315    throws IOException {
316  }
317
318  /**
319   * Called before the region is reported as closed to the master.
320   * @param c              the environment provided by the region server
321   * @param abortRequested true if the region server is aborting
322   */
323  default void preClose(ObserverContext<RegionCoprocessorEnvironment> c, boolean abortRequested)
324    throws IOException {
325  }
326
327  /**
328   * Called after the region is reported as closed to the master.
329   * @param c              the environment provided by the region server
330   * @param abortRequested true if the region server is aborting
331   */
332  default void postClose(ObserverContext<RegionCoprocessorEnvironment> c, boolean abortRequested) {
333  }
334
335  /**
336   * Called before the client performs a Get
337   * <p>
338   * Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on
339   * calling any subsequent chained coprocessors.
340   * @param c      the environment provided by the region server
341   * @param get    the Get request
342   * @param result The result to return to the client if default processing is bypassed. Can be
343   *               modified. Will not be used if default processing is not bypassed.
344   */
345  default void preGetOp(ObserverContext<RegionCoprocessorEnvironment> c, Get get, List<Cell> result)
346    throws IOException {
347  }
348
349  /**
350   * Called after the client performs a Get
351   * <p>
352   * Note: Do not retain references to any Cells in 'result' beyond the life of this invocation. If
353   * need a Cell reference for later use, copy the cell and use that.
354   * @param c      the environment provided by the region server
355   * @param get    the Get request
356   * @param result the result to return to the client, modify as necessary
357   */
358  default void postGetOp(ObserverContext<RegionCoprocessorEnvironment> c, Get get,
359    List<Cell> result) throws IOException {
360  }
361
362  /**
363   * Called before the client tests for existence using a Get.
364   * <p>
365   * Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on
366   * calling any subsequent chained coprocessors.
367   * @param c      the environment provided by the region server
368   * @param get    the Get request
369   * @param exists the result returned by the region server
370   * @return the value to return to the client if bypassing default processing
371   */
372  default boolean preExists(ObserverContext<RegionCoprocessorEnvironment> c, Get get,
373    boolean exists) throws IOException {
374    return exists;
375  }
376
377  /**
378   * Called after the client tests for existence using a Get.
379   * @param c      the environment provided by the region server
380   * @param get    the Get request
381   * @param exists the result returned by the region server
382   * @return the result to return to the client
383   */
384  default boolean postExists(ObserverContext<RegionCoprocessorEnvironment> c, Get get,
385    boolean exists) throws IOException {
386    return exists;
387  }
388
389  /**
390   * Called before the client stores a value.
391   * <p>
392   * Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on
393   * calling any subsequent chained coprocessors.
394   * <p>
395   * Note: Do not retain references to any Cells in 'put' beyond the life of this invocation. If
396   * need a Cell reference for later use, copy the cell and use that.
397   * @param c          the environment provided by the region server
398   * @param put        The Put object
399   * @param edit       The WALEdit object that will be written to the wal
400   * @param durability Persistence guarantee for this Put
401   * @deprecated since 2.5.0 and will be removed in 4.0.0. Use
402   *             {@link #prePut(ObserverContext, Put, WALEdit)} instead.
403   */
404  @Deprecated
405  default void prePut(ObserverContext<RegionCoprocessorEnvironment> c, Put put, WALEdit edit,
406    Durability durability) throws IOException {
407  }
408
409  /**
410   * Called before the client stores a value.
411   * <p>
412   * Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on
413   * calling any subsequent chained coprocessors.
414   * <p>
415   * Note: Do not retain references to any Cells in 'put' beyond the life of this invocation. If
416   * need a Cell reference for later use, copy the cell and use that.
417   * @param c    the environment provided by the region server
418   * @param put  The Put object
419   * @param edit The WALEdit object that will be written to the wal
420   */
421  default void prePut(ObserverContext<RegionCoprocessorEnvironment> c, Put put, WALEdit edit)
422    throws IOException {
423    prePut(c, put, edit, put.getDurability());
424  }
425
426  /**
427   * Called after the client stores a value.
428   * <p>
429   * Note: Do not retain references to any Cells in 'put' beyond the life of this invocation. If
430   * need a Cell reference for later use, copy the cell and use that.
431   * @param c          the environment provided by the region server
432   * @param put        The Put object
433   * @param edit       The WALEdit object for the wal
434   * @param durability Persistence guarantee for this Put
435   * @deprecated since 2.5.0 and will be removed in 4.0.0. Use
436   *             {@link #postPut(ObserverContext, Put, WALEdit)} instead.
437   */
438  @Deprecated
439  default void postPut(ObserverContext<RegionCoprocessorEnvironment> c, Put put, WALEdit edit,
440    Durability durability) throws IOException {
441  }
442
443  /**
444   * Called after the client stores a value.
445   * <p>
446   * Note: Do not retain references to any Cells in 'put' beyond the life of this invocation. If
447   * need a Cell reference for later use, copy the cell and use that.
448   * @param c    the environment provided by the region server
449   * @param put  The Put object
450   * @param edit The WALEdit object for the wal
451   */
452  default void postPut(ObserverContext<RegionCoprocessorEnvironment> c, Put put, WALEdit edit)
453    throws IOException {
454    postPut(c, put, edit, put.getDurability());
455  }
456
457  /**
458   * Called before the client deletes a value.
459   * <p>
460   * Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on
461   * calling any subsequent chained coprocessors.
462   * <p>
463   * Note: Do not retain references to any Cells in 'delete' beyond the life of this invocation. If
464   * need a Cell reference for later use, copy the cell and use that.
465   * @param c          the environment provided by the region server
466   * @param delete     The Delete object
467   * @param edit       The WALEdit object for the wal
468   * @param durability Persistence guarantee for this Delete
469   * @deprecated since 2.5.0 and will be removed in 4.0.0. Use
470   *             {@link #preDelete(ObserverContext, Delete, WALEdit)} instead.
471   */
472  @Deprecated
473  default void preDelete(ObserverContext<RegionCoprocessorEnvironment> c, Delete delete,
474    WALEdit edit, Durability durability) throws IOException {
475  }
476
477  /**
478   * Called before the client deletes a value.
479   * <p>
480   * Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on
481   * calling any subsequent chained coprocessors.
482   * <p>
483   * Note: Do not retain references to any Cells in 'delete' beyond the life of this invocation. If
484   * need a Cell reference for later use, copy the cell and use that.
485   * @param c      the environment provided by the region server
486   * @param delete The Delete object
487   * @param edit   The WALEdit object for the wal
488   */
489  default void preDelete(ObserverContext<RegionCoprocessorEnvironment> c, Delete delete,
490    WALEdit edit) throws IOException {
491    preDelete(c, delete, edit, delete.getDurability());
492  }
493
494  /**
495   * Called before the server updates the timestamp for version delete with latest timestamp.
496   * <p>
497   * Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on
498   * calling any subsequent chained coprocessors.
499   * @param c        the environment provided by the region server
500   * @param mutation - the parent mutation associated with this delete cell
501   * @param cell     - The deleteColumn with latest version cell
502   * @param byteNow  - timestamp bytes
503   * @param get      - the get formed using the current cell's row. Note that the get does not
504   *                 specify the family and qualifier
505   * @deprecated Since hbase-2.0.0. No replacement. To be removed in hbase-3.0.0 and replaced with
506   *             something that doesn't expose IntefaceAudience.Private classes.
507   */
508  @Deprecated
509  default void prePrepareTimeStampForDeleteVersion(ObserverContext<RegionCoprocessorEnvironment> c,
510    Mutation mutation, Cell cell, byte[] byteNow, Get get) throws IOException {
511  }
512
513  /**
514   * Called after the client deletes a value.
515   * <p>
516   * Note: Do not retain references to any Cells in 'delete' beyond the life of this invocation. If
517   * need a Cell reference for later use, copy the cell and use that.
518   * @param c          the environment provided by the region server
519   * @param delete     The Delete object
520   * @param edit       The WALEdit object for the wal
521   * @param durability Persistence guarantee for this Delete
522   * @deprecated since 2.5.0 and will be removed in 4.0.0. Use
523   *             {@link #postDelete(ObserverContext, Delete, WALEdit)} instead.
524   */
525  @Deprecated
526  default void postDelete(ObserverContext<RegionCoprocessorEnvironment> c, Delete delete,
527    WALEdit edit, Durability durability) throws IOException {
528  }
529
530  /**
531   * Called after the client deletes a value.
532   * <p>
533   * Note: Do not retain references to any Cells in 'delete' beyond the life of this invocation. If
534   * need a Cell reference for later use, copy the cell and use that.
535   * @param c      the environment provided by the region server
536   * @param delete The Delete object
537   * @param edit   The WALEdit object for the wal
538   */
539  default void postDelete(ObserverContext<RegionCoprocessorEnvironment> c, Delete delete,
540    WALEdit edit) throws IOException {
541    postDelete(c, delete, edit, delete.getDurability());
542  }
543
544  /**
545   * This will be called for every batch mutation operation happening at the server. This will be
546   * called after acquiring the locks on the mutating rows and after applying the proper timestamp
547   * for each Mutation at the server. The batch may contain Put/Delete/Increment/Append. By setting
548   * OperationStatus of Mutations
549   * ({@link MiniBatchOperationInProgress#setOperationStatus(int, OperationStatus)}),
550   * {@link RegionObserver} can make Region to skip these Mutations.
551   * <p>
552   * Note: Do not retain references to any Cells in Mutations beyond the life of this invocation. If
553   * need a Cell reference for later use, copy the cell and use that.
554   * @param c           the environment provided by the region server
555   * @param miniBatchOp batch of Mutations getting applied to region.
556   */
557  default void preBatchMutate(ObserverContext<RegionCoprocessorEnvironment> c,
558    MiniBatchOperationInProgress<Mutation> miniBatchOp) throws IOException {
559  }
560
561  /**
562   * This will be called after applying a batch of Mutations on a region. The Mutations are added to
563   * memstore and WAL. The difference of this one with
564   * {@link #postPut(ObserverContext, Put, WALEdit)} and
565   * {@link #postDelete(ObserverContext, Delete, WALEdit)} and
566   * {@link #postIncrement(ObserverContext, Increment, Result, WALEdit)} and
567   * {@link #postAppend(ObserverContext, Append, Result, WALEdit)} is this hook will be executed
568   * before the mvcc transaction completion.
569   * <p>
570   * Note: Do not retain references to any Cells in Mutations beyond the life of this invocation. If
571   * need a Cell reference for later use, copy the cell and use that.
572   * @param c           the environment provided by the region server
573   * @param miniBatchOp batch of Mutations applied to region. Coprocessors are discouraged from
574   *                    manipulating its state.
575   */
576  // Coprocessors can do a form of bypass by changing state in miniBatchOp.
577  default void postBatchMutate(ObserverContext<RegionCoprocessorEnvironment> c,
578    MiniBatchOperationInProgress<Mutation> miniBatchOp) throws IOException {
579  }
580
581  /**
582   * This will be called for region operations where read lock is acquired in
583   * {@link Region#startRegionOperation()}.
584   * @param operation The operation is about to be taken on the region
585   */
586  default void postStartRegionOperation(ObserverContext<RegionCoprocessorEnvironment> ctx,
587    Operation operation) throws IOException {
588  }
589
590  /**
591   * Called after releasing read lock in {@link Region#closeRegionOperation()}.
592   */
593  default void postCloseRegionOperation(ObserverContext<RegionCoprocessorEnvironment> ctx,
594    Operation operation) throws IOException {
595  }
596
597  /**
598   * Called after the completion of batch put/delete/increment/append and will be called even if the
599   * batch operation fails.
600   * <p>
601   * Note: Do not retain references to any Cells in Mutations beyond the life of this invocation. If
602   * need a Cell reference for later use, copy the cell and use that.
603   * @param success true if batch operation is successful otherwise false.
604   */
605  default void postBatchMutateIndispensably(ObserverContext<RegionCoprocessorEnvironment> ctx,
606    MiniBatchOperationInProgress<Mutation> miniBatchOp, boolean success) throws IOException {
607  }
608
609  /**
610   * Called before checkAndPut.
611   * <p>
612   * Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on
613   * calling any subsequent chained coprocessors.
614   * <p>
615   * Note: Do not retain references to any Cells in 'put' beyond the life of this invocation. If
616   * need a Cell reference for later use, copy the cell and use that.
617   * @param c          the environment provided by the region server
618   * @param row        row to check
619   * @param family     column family
620   * @param qualifier  column qualifier
621   * @param op         the comparison operation
622   * @param comparator the comparator
623   * @param put        data to put if check succeeds
624   * @param result     the default value of the result
625   * @return the return value to return to client if bypassing default processing
626   * @deprecated since 2.4.0 and will be removed in 4.0.0. Use
627   *             {@link #preCheckAndMutate(ObserverContext, CheckAndMutate, CheckAndMutateResult)}
628   *             instead.
629   */
630  @Deprecated
631  default boolean preCheckAndPut(ObserverContext<RegionCoprocessorEnvironment> c, byte[] row,
632    byte[] family, byte[] qualifier, CompareOperator op, ByteArrayComparable comparator, Put put,
633    boolean result) throws IOException {
634    return result;
635  }
636
637  /**
638   * Called before checkAndPut.
639   * <p>
640   * Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on
641   * calling any subsequent chained coprocessors.
642   * <p>
643   * Note: Do not retain references to any Cells in 'put' beyond the life of this invocation. If
644   * need a Cell reference for later use, copy the cell and use that.
645   * @param c      the environment provided by the region server
646   * @param row    row to check
647   * @param filter filter
648   * @param put    data to put if check succeeds
649   * @param result the default value of the result
650   * @return the return value to return to client if bypassing default processing
651   * @deprecated since 2.4.0 and will be removed in 4.0.0. Use
652   *             {@link #preCheckAndMutate(ObserverContext, CheckAndMutate, CheckAndMutateResult)}
653   *             instead.
654   */
655  @Deprecated
656  default boolean preCheckAndPut(ObserverContext<RegionCoprocessorEnvironment> c, byte[] row,
657    Filter filter, Put put, boolean result) throws IOException {
658    return result;
659  }
660
661  /**
662   * Called before checkAndPut but after acquiring rowlock.
663   * <p>
664   * <b>Note:</b> Caution to be taken for not doing any long time operation in this hook. Row will
665   * be locked for longer time. Trying to acquire lock on another row, within this, can lead to
666   * potential deadlock.
667   * <p>
668   * Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on
669   * calling any subsequent chained coprocessors.
670   * <p>
671   * Note: Do not retain references to any Cells in 'put' beyond the life of this invocation. If
672   * need a Cell reference for later use, copy the cell and use that.
673   * @param c          the environment provided by the region server
674   * @param row        row to check
675   * @param family     column family
676   * @param qualifier  column qualifier
677   * @param op         the comparison operation
678   * @param comparator the comparator
679   * @param put        data to put if check succeeds
680   * @param result     the default value of the result
681   * @return the return value to return to client if bypassing default processing
682   * @deprecated since 2.4.0 and will be removed in 4.0.0. Use
683   *             {@link #preCheckAndMutateAfterRowLock(ObserverContext, CheckAndMutate,CheckAndMutateResult)}
684   *             instead.
685   */
686  @Deprecated
687  default boolean preCheckAndPutAfterRowLock(ObserverContext<RegionCoprocessorEnvironment> c,
688    byte[] row, byte[] family, byte[] qualifier, CompareOperator op, ByteArrayComparable comparator,
689    Put put, boolean result) throws IOException {
690    return result;
691  }
692
693  /**
694   * Called before checkAndPut but after acquiring rowlock.
695   * <p>
696   * <b>Note:</b> Caution to be taken for not doing any long time operation in this hook. Row will
697   * be locked for longer time. Trying to acquire lock on another row, within this, can lead to
698   * potential deadlock.
699   * <p>
700   * Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on
701   * calling any subsequent chained coprocessors.
702   * <p>
703   * Note: Do not retain references to any Cells in 'put' beyond the life of this invocation. If
704   * need a Cell reference for later use, copy the cell and use that.
705   * @param c      the environment provided by the region server
706   * @param row    row to check
707   * @param filter filter
708   * @param put    data to put if check succeeds
709   * @param result the default value of the result
710   * @return the return value to return to client if bypassing default processing
711   * @deprecated since 2.4.0 and will be removed in 4.0.0. Use
712   *             {@link #preCheckAndMutateAfterRowLock(ObserverContext, CheckAndMutate,CheckAndMutateResult)}
713   *             instead.
714   */
715  @Deprecated
716  default boolean preCheckAndPutAfterRowLock(ObserverContext<RegionCoprocessorEnvironment> c,
717    byte[] row, Filter filter, Put put, boolean result) throws IOException {
718    return result;
719  }
720
721  /**
722   * Called after checkAndPut
723   * <p>
724   * Note: Do not retain references to any Cells in 'put' beyond the life of this invocation. If
725   * need a Cell reference for later use, copy the cell and use that.
726   * @param c          the environment provided by the region server
727   * @param row        row to check
728   * @param family     column family
729   * @param qualifier  column qualifier
730   * @param op         the comparison operation
731   * @param comparator the comparator
732   * @param put        data to put if check succeeds
733   * @param result     from the checkAndPut
734   * @return the possibly transformed return value to return to client
735   * @deprecated since 2.4.0 and will be removed in 4.0.0. Use
736   *             {@link #postCheckAndMutate(ObserverContext, CheckAndMutate, CheckAndMutateResult)}
737   *             instead.
738   */
739  @Deprecated
740  default boolean postCheckAndPut(ObserverContext<RegionCoprocessorEnvironment> c, byte[] row,
741    byte[] family, byte[] qualifier, CompareOperator op, ByteArrayComparable comparator, Put put,
742    boolean result) throws IOException {
743    return result;
744  }
745
746  /**
747   * Called after checkAndPut
748   * <p>
749   * Note: Do not retain references to any Cells in 'put' beyond the life of this invocation. If
750   * need a Cell reference for later use, copy the cell and use that.
751   * @param c      the environment provided by the region server
752   * @param row    row to check
753   * @param filter filter
754   * @param put    data to put if check succeeds
755   * @param result from the checkAndPut
756   * @return the possibly transformed return value to return to client
757   * @deprecated since 2.4.0 and will be removed in 4.0.0. Use
758   *             {@link #postCheckAndMutate(ObserverContext, CheckAndMutate, CheckAndMutateResult)}
759   *             instead.
760   */
761  @Deprecated
762  default boolean postCheckAndPut(ObserverContext<RegionCoprocessorEnvironment> c, byte[] row,
763    Filter filter, Put put, boolean result) throws IOException {
764    return result;
765  }
766
767  /**
768   * Called before checkAndDelete.
769   * <p>
770   * Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on
771   * calling any subsequent chained coprocessors.
772   * <p>
773   * Note: Do not retain references to any Cells in 'delete' beyond the life of this invocation. If
774   * need a Cell reference for later use, copy the cell and use that.
775   * @param c          the environment provided by the region server
776   * @param row        row to check
777   * @param family     column family
778   * @param qualifier  column qualifier
779   * @param op         the comparison operation
780   * @param comparator the comparator
781   * @param delete     delete to commit if check succeeds
782   * @param result     the default value of the result
783   * @return the value to return to client if bypassing default processing
784   * @deprecated since 2.4.0 and will be removed in 4.0.0. Use
785   *             {@link #preCheckAndMutate(ObserverContext, CheckAndMutate, CheckAndMutateResult)}
786   *             instead.
787   */
788  @Deprecated
789  default boolean preCheckAndDelete(ObserverContext<RegionCoprocessorEnvironment> c, byte[] row,
790    byte[] family, byte[] qualifier, CompareOperator op, ByteArrayComparable comparator,
791    Delete delete, boolean result) throws IOException {
792    return result;
793  }
794
795  /**
796   * Called before checkAndDelete.
797   * <p>
798   * Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on
799   * calling any subsequent chained coprocessors.
800   * <p>
801   * Note: Do not retain references to any Cells in 'delete' beyond the life of this invocation. If
802   * need a Cell reference for later use, copy the cell and use that.
803   * @param c      the environment provided by the region server
804   * @param row    row to check
805   * @param filter column family
806   * @param delete delete to commit if check succeeds
807   * @param result the default value of the result
808   * @return the value to return to client if bypassing default processing
809   * @deprecated since 2.4.0 and will be removed in 4.0.0. Use
810   *             {@link #preCheckAndMutate(ObserverContext, CheckAndMutate, CheckAndMutateResult)}
811   *             instead.
812   */
813  @Deprecated
814  default boolean preCheckAndDelete(ObserverContext<RegionCoprocessorEnvironment> c, byte[] row,
815    Filter filter, Delete delete, boolean result) throws IOException {
816    return result;
817  }
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. Row will
823   * be locked for longer time. Trying to acquire lock on another row, within this, can lead to
824   * potential deadlock.
825   * <p>
826   * Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on
827   * calling any subsequent chained coprocessors.
828   * <p>
829   * Note: Do not retain references to any Cells in 'delete' beyond the life of this invocation. If
830   * need a Cell reference for later use, copy the cell and use that.
831   * @param c          the environment provided by the region server
832   * @param row        row to check
833   * @param family     column family
834   * @param qualifier  column qualifier
835   * @param op         the comparison operation
836   * @param comparator the comparator
837   * @param delete     delete to commit if check succeeds
838   * @param result     the default value of the result
839   * @return the value to return to client if bypassing default processing
840   * @deprecated since 2.4.0 and will be removed in 4.0.0. Use
841   *             {@link #preCheckAndMutateAfterRowLock(ObserverContext, CheckAndMutate,CheckAndMutateResult)}
842   *             instead.
843   */
844  @Deprecated
845  default boolean preCheckAndDeleteAfterRowLock(ObserverContext<RegionCoprocessorEnvironment> c,
846    byte[] row, byte[] family, byte[] qualifier, CompareOperator op, ByteArrayComparable comparator,
847    Delete delete, boolean result) throws IOException {
848    return result;
849  }
850
851  /**
852   * Called before checkAndDelete but after acquiring rowock.
853   * <p>
854   * <b>Note:</b> Caution to be taken for not doing any long time operation in this hook. Row will
855   * be locked for longer time. Trying to acquire lock on another row, within this, can lead to
856   * potential deadlock.
857   * <p>
858   * Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on
859   * calling any subsequent chained coprocessors.
860   * <p>
861   * Note: Do not retain references to any Cells in 'delete' beyond the life of this invocation. If
862   * need a Cell reference for later use, copy the cell and use that.
863   * @param c      the environment provided by the region server
864   * @param row    row to check
865   * @param filter filter
866   * @param delete delete to commit if check succeeds
867   * @param result the default value of the result
868   * @return the value to return to client if bypassing default processing
869   * @deprecated since 2.4.0 and will be removed in 4.0.0. Use
870   *             {@link #preCheckAndMutateAfterRowLock(ObserverContext, CheckAndMutate,CheckAndMutateResult)}
871   *             instead.
872   */
873  @Deprecated
874  default boolean preCheckAndDeleteAfterRowLock(ObserverContext<RegionCoprocessorEnvironment> c,
875    byte[] row, Filter filter, Delete delete, boolean result) throws IOException {
876    return result;
877  }
878
879  /**
880   * Called after checkAndDelete
881   * <p>
882   * Note: Do not retain references to any Cells in 'delete' beyond the life of this invocation. If
883   * need a Cell reference for later use, copy the cell and use that.
884   * @param c          the environment provided by the region server
885   * @param row        row to check
886   * @param family     column family
887   * @param qualifier  column qualifier
888   * @param op         the comparison operation
889   * @param comparator the comparator
890   * @param delete     delete to commit if check succeeds
891   * @param result     from the CheckAndDelete
892   * @return the possibly transformed returned value to return to client
893   * @deprecated since 2.4.0 and will be removed in 4.0.0. Use
894   *             {@link #postCheckAndMutate(ObserverContext, CheckAndMutate, CheckAndMutateResult)}
895   *             instead.
896   */
897  @Deprecated
898  default boolean postCheckAndDelete(ObserverContext<RegionCoprocessorEnvironment> c, byte[] row,
899    byte[] family, byte[] qualifier, CompareOperator op, ByteArrayComparable comparator,
900    Delete delete, boolean result) throws IOException {
901    return result;
902  }
903
904  /**
905   * Called after checkAndDelete
906   * <p>
907   * Note: Do not retain references to any Cells in 'delete' beyond the life of this invocation. If
908   * need a Cell reference for later use, copy the cell and use that.
909   * @param c      the environment provided by the region server
910   * @param row    row to check
911   * @param filter filter
912   * @param delete delete to commit if check succeeds
913   * @param result from the CheckAndDelete
914   * @return the possibly transformed returned value to return to client
915   * @deprecated since 2.4.0 and will be removed in 4.0.0. Use
916   *             {@link #postCheckAndMutate(ObserverContext, CheckAndMutate, CheckAndMutateResult)}
917   *             instead.
918   */
919  @Deprecated
920  default boolean postCheckAndDelete(ObserverContext<RegionCoprocessorEnvironment> c, byte[] row,
921    Filter filter, Delete delete, boolean result) throws IOException {
922    return result;
923  }
924
925  /**
926   * Called before checkAndMutate
927   * <p>
928   * Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on
929   * calling any subsequent chained coprocessors.
930   * <p>
931   * Note: Do not retain references to any Cells in actions beyond the life of this invocation. If
932   * need a Cell reference for later use, copy the cell and use that.
933   * @param c              the environment provided by the region server
934   * @param checkAndMutate the CheckAndMutate object
935   * @param result         the default value of the result
936   * @return the return value to return to client if bypassing default processing
937   * @throws IOException if an error occurred on the coprocessor
938   */
939  default CheckAndMutateResult preCheckAndMutate(ObserverContext<RegionCoprocessorEnvironment> c,
940    CheckAndMutate checkAndMutate, CheckAndMutateResult result) throws IOException {
941    if (checkAndMutate.getAction() instanceof Put) {
942      boolean success;
943      if (checkAndMutate.hasFilter()) {
944        success = preCheckAndPut(c, checkAndMutate.getRow(), checkAndMutate.getFilter(),
945          (Put) checkAndMutate.getAction(), result.isSuccess());
946      } else {
947        success = preCheckAndPut(c, checkAndMutate.getRow(), checkAndMutate.getFamily(),
948          checkAndMutate.getQualifier(), checkAndMutate.getCompareOp(),
949          new BinaryComparator(checkAndMutate.getValue()), (Put) checkAndMutate.getAction(),
950          result.isSuccess());
951      }
952      return new CheckAndMutateResult(success, null);
953    } else if (checkAndMutate.getAction() instanceof Delete) {
954      boolean success;
955      if (checkAndMutate.hasFilter()) {
956        success = preCheckAndDelete(c, checkAndMutate.getRow(), checkAndMutate.getFilter(),
957          (Delete) checkAndMutate.getAction(), result.isSuccess());
958      } else {
959        success = preCheckAndDelete(c, checkAndMutate.getRow(), checkAndMutate.getFamily(),
960          checkAndMutate.getQualifier(), checkAndMutate.getCompareOp(),
961          new BinaryComparator(checkAndMutate.getValue()), (Delete) checkAndMutate.getAction(),
962          result.isSuccess());
963      }
964      return new CheckAndMutateResult(success, null);
965    }
966    return result;
967  }
968
969  /**
970   * Called before checkAndDelete but after acquiring rowlock.
971   * <p>
972   * <b>Note:</b> Caution to be taken for not doing any long time operation in this hook. Row will
973   * be locked for longer time. Trying to acquire lock on another row, within this, can lead to
974   * potential deadlock.
975   * <p>
976   * Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on
977   * calling any subsequent chained coprocessors.
978   * <p>
979   * Note: Do not retain references to any Cells in actions beyond the life of this invocation. If
980   * need a Cell reference for later use, copy the cell and use that.
981   * @param c              the environment provided by the region server
982   * @param checkAndMutate the CheckAndMutate object
983   * @param result         the default value of the result
984   * @return the value to return to client if bypassing default processing
985   * @throws IOException if an error occurred on the coprocessor
986   */
987  default CheckAndMutateResult preCheckAndMutateAfterRowLock(
988    ObserverContext<RegionCoprocessorEnvironment> c, CheckAndMutate checkAndMutate,
989    CheckAndMutateResult result) throws IOException {
990    if (checkAndMutate.getAction() instanceof Put) {
991      boolean success;
992      if (checkAndMutate.hasFilter()) {
993        success = preCheckAndPutAfterRowLock(c, checkAndMutate.getRow(), checkAndMutate.getFilter(),
994          (Put) checkAndMutate.getAction(), result.isSuccess());
995      } else {
996        success = preCheckAndPutAfterRowLock(c, checkAndMutate.getRow(), checkAndMutate.getFamily(),
997          checkAndMutate.getQualifier(), checkAndMutate.getCompareOp(),
998          new BinaryComparator(checkAndMutate.getValue()), (Put) checkAndMutate.getAction(),
999          result.isSuccess());
1000      }
1001      return new CheckAndMutateResult(success, null);
1002    } else if (checkAndMutate.getAction() instanceof Delete) {
1003      boolean success;
1004      if (checkAndMutate.hasFilter()) {
1005        success = preCheckAndDeleteAfterRowLock(c, checkAndMutate.getRow(),
1006          checkAndMutate.getFilter(), (Delete) checkAndMutate.getAction(), result.isSuccess());
1007      } else {
1008        success = preCheckAndDeleteAfterRowLock(c, checkAndMutate.getRow(),
1009          checkAndMutate.getFamily(), checkAndMutate.getQualifier(), checkAndMutate.getCompareOp(),
1010          new BinaryComparator(checkAndMutate.getValue()), (Delete) checkAndMutate.getAction(),
1011          result.isSuccess());
1012      }
1013      return new CheckAndMutateResult(success, null);
1014    }
1015    return result;
1016  }
1017
1018  /**
1019   * Called after checkAndMutate
1020   * <p>
1021   * Note: Do not retain references to any Cells in actions beyond the life of this invocation. If
1022   * need a Cell reference for later use, copy the cell and use that.
1023   * @param c              the environment provided by the region server
1024   * @param checkAndMutate the CheckAndMutate object
1025   * @param result         from the checkAndMutate
1026   * @return the possibly transformed returned value to return to client
1027   * @throws IOException if an error occurred on the coprocessor
1028   */
1029  default CheckAndMutateResult postCheckAndMutate(ObserverContext<RegionCoprocessorEnvironment> c,
1030    CheckAndMutate checkAndMutate, CheckAndMutateResult result) throws IOException {
1031    if (checkAndMutate.getAction() instanceof Put) {
1032      boolean success;
1033      if (checkAndMutate.hasFilter()) {
1034        success = postCheckAndPut(c, checkAndMutate.getRow(), checkAndMutate.getFilter(),
1035          (Put) checkAndMutate.getAction(), result.isSuccess());
1036      } else {
1037        success = postCheckAndPut(c, checkAndMutate.getRow(), checkAndMutate.getFamily(),
1038          checkAndMutate.getQualifier(), checkAndMutate.getCompareOp(),
1039          new BinaryComparator(checkAndMutate.getValue()), (Put) checkAndMutate.getAction(),
1040          result.isSuccess());
1041      }
1042      return new CheckAndMutateResult(success, null);
1043    } else if (checkAndMutate.getAction() instanceof Delete) {
1044      boolean success;
1045      if (checkAndMutate.hasFilter()) {
1046        success = postCheckAndDelete(c, checkAndMutate.getRow(), checkAndMutate.getFilter(),
1047          (Delete) checkAndMutate.getAction(), result.isSuccess());
1048      } else {
1049        success = postCheckAndDelete(c, checkAndMutate.getRow(), checkAndMutate.getFamily(),
1050          checkAndMutate.getQualifier(), checkAndMutate.getCompareOp(),
1051          new BinaryComparator(checkAndMutate.getValue()), (Delete) checkAndMutate.getAction(),
1052          result.isSuccess());
1053      }
1054      return new CheckAndMutateResult(success, null);
1055    }
1056    return result;
1057  }
1058
1059  /**
1060   * Called before Append.
1061   * <p>
1062   * Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on
1063   * calling any subsequent chained coprocessors.
1064   * <p>
1065   * Note: Do not retain references to any Cells in 'append' beyond the life of this invocation. If
1066   * need a Cell reference for later use, copy the cell and use that.
1067   * @param c      the environment provided by the region server
1068   * @param append Append object
1069   * @return result to return to the client if bypassing default processing
1070   * @deprecated since 2.5.0 and will be removed in 4.0.0. Use
1071   *             {@link #preAppend(ObserverContext, Append, WALEdit)} instead.
1072   */
1073  @Deprecated
1074  default Result preAppend(ObserverContext<RegionCoprocessorEnvironment> c, Append append)
1075    throws IOException {
1076    return null;
1077  }
1078
1079  /**
1080   * Called before Append.
1081   * <p>
1082   * Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on
1083   * calling any subsequent chained coprocessors.
1084   * <p>
1085   * Note: Do not retain references to any Cells in 'append' beyond the life of this invocation. If
1086   * need a Cell reference for later use, copy the cell and use that.
1087   * @param c      the environment provided by the region server
1088   * @param append Append object
1089   * @param edit   The WALEdit object that will be written to the wal
1090   * @return result to return to the client if bypassing default processing
1091   */
1092  default Result preAppend(ObserverContext<RegionCoprocessorEnvironment> c, Append append,
1093    WALEdit edit) throws IOException {
1094    return preAppend(c, append);
1095  }
1096
1097  /**
1098   * Called before Append but after acquiring rowlock.
1099   * <p>
1100   * <b>Note:</b> Caution to be taken for not doing any long time operation in this hook. Row will
1101   * be locked for longer time. Trying to acquire lock on another row, within this, can lead to
1102   * potential deadlock.
1103   * <p>
1104   * Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on
1105   * calling any subsequent chained coprocessors.
1106   * <p>
1107   * Note: Do not retain references to any Cells in 'append' beyond the life of this invocation. If
1108   * need a Cell reference for later use, copy the cell and use that.
1109   * @param c      the environment provided by the region server
1110   * @param append Append object
1111   * @return result to return to the client if bypassing default processing
1112   * @deprecated since 2.5.0 and will be removed in 4.0.0. Use
1113   *             {@link #preBatchMutate(ObserverContext, MiniBatchOperationInProgress)} instead.
1114   */
1115  @Deprecated
1116  default Result preAppendAfterRowLock(ObserverContext<RegionCoprocessorEnvironment> c,
1117    Append append) throws IOException {
1118    return null;
1119  }
1120
1121  /**
1122   * Called after Append
1123   * <p>
1124   * Note: Do not retain references to any Cells in 'append' beyond the life of this invocation. If
1125   * need a Cell reference for later use, copy the cell and use that.
1126   * @param c      the environment provided by the region server
1127   * @param append Append object
1128   * @param result the result returned by increment
1129   * @return the result to return to the client
1130   * @deprecated since 2.5.0 and will be removed in 4.0.0. Use
1131   *             {@link #postAppend(ObserverContext, Append, Result, WALEdit)} instead.
1132   */
1133  @Deprecated
1134  default Result postAppend(ObserverContext<RegionCoprocessorEnvironment> c, Append append,
1135    Result result) throws IOException {
1136    return result;
1137  }
1138
1139  /**
1140   * Called after Append
1141   * <p>
1142   * Note: Do not retain references to any Cells in 'append' beyond the life of this invocation. If
1143   * need a Cell reference for later use, copy the cell and use that.
1144   * @param c      the environment provided by the region server
1145   * @param append Append object
1146   * @param result the result returned by increment
1147   * @param edit   The WALEdit object for the wal
1148   * @return the result to return to the client
1149   */
1150  default Result postAppend(ObserverContext<RegionCoprocessorEnvironment> c, Append append,
1151    Result result, WALEdit edit) throws IOException {
1152    return postAppend(c, append, result);
1153  }
1154
1155  /**
1156   * Called before Increment.
1157   * <p>
1158   * Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on
1159   * calling any subsequent chained coprocessors.
1160   * <p>
1161   * Note: Do not retain references to any Cells in 'increment' beyond the life of this invocation.
1162   * If need a Cell reference for later use, copy the cell and use that.
1163   * @param c         the environment provided by the region server
1164   * @param increment increment object
1165   * @return result to return to the client if bypassing default processing
1166   * @deprecated since 2.5.0 and will be removed in 4.0.0. Use
1167   *             {@link #preIncrement(ObserverContext, Increment, WALEdit)} instead.
1168   */
1169  @Deprecated
1170  default Result preIncrement(ObserverContext<RegionCoprocessorEnvironment> c, Increment increment)
1171    throws IOException {
1172    return null;
1173  }
1174
1175  /**
1176   * Called before Increment.
1177   * <p>
1178   * Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on
1179   * calling any subsequent chained coprocessors.
1180   * <p>
1181   * Note: Do not retain references to any Cells in 'increment' beyond the life of this invocation.
1182   * If need a Cell reference for later use, copy the cell and use that.
1183   * @param c         the environment provided by the region server
1184   * @param increment increment object
1185   * @param edit      The WALEdit object that will be written to the wal
1186   * @return result to return to the client if bypassing default processing
1187   */
1188  default Result preIncrement(ObserverContext<RegionCoprocessorEnvironment> c, Increment increment,
1189    WALEdit edit) throws IOException {
1190    return preIncrement(c, increment);
1191  }
1192
1193  /**
1194   * Called before Increment but after acquiring rowlock.
1195   * <p>
1196   * <b>Note:</b> Caution to be taken for not doing any long time operation in this hook. Row will
1197   * be locked for longer time. Trying to acquire lock on another row, within this, can lead to
1198   * potential deadlock.
1199   * <p>
1200   * Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on
1201   * calling any subsequent chained coprocessors.
1202   * <p>
1203   * Note: Do not retain references to any Cells in 'increment' beyond the life of this invocation.
1204   * If need a Cell reference for later use, copy the cell and use that.
1205   * @param c         the environment provided by the region server
1206   * @param increment increment object
1207   * @return result to return to the client if bypassing default processing
1208   * @deprecated since 2.5.0 and will be removed in 4.0.0. Use
1209   *             {@link #preBatchMutate(ObserverContext, MiniBatchOperationInProgress)} instead.
1210   */
1211  @Deprecated
1212  default Result preIncrementAfterRowLock(ObserverContext<RegionCoprocessorEnvironment> c,
1213    Increment increment) throws IOException {
1214    return null;
1215  }
1216
1217  /**
1218   * Called after increment
1219   * <p>
1220   * Note: Do not retain references to any Cells in 'increment' beyond the life of this invocation.
1221   * If need a Cell reference for later use, copy the cell and use that.
1222   * @param c         the environment provided by the region server
1223   * @param increment increment object
1224   * @param result    the result returned by increment
1225   * @return the result to return to the client
1226   * @deprecated since 2.5.0 and will be removed in 4.0.0. Use
1227   *             {@link #postIncrement(ObserverContext, Increment, Result, WALEdit)} instead.
1228   */
1229  @Deprecated
1230  default Result postIncrement(ObserverContext<RegionCoprocessorEnvironment> c, Increment increment,
1231    Result result) throws IOException {
1232    return result;
1233  }
1234
1235  /**
1236   * Called after increment
1237   * <p>
1238   * Note: Do not retain references to any Cells in 'increment' beyond the life of this invocation.
1239   * If need a Cell reference for later use, copy the cell and use that.
1240   * @param c         the environment provided by the region server
1241   * @param increment increment object
1242   * @param result    the result returned by increment
1243   * @param edit      The WALEdit object for the wal
1244   * @return the result to return to the client
1245   */
1246  default Result postIncrement(ObserverContext<RegionCoprocessorEnvironment> c, Increment increment,
1247    Result result, WALEdit edit) throws IOException {
1248    return postIncrement(c, increment, result);
1249  }
1250
1251  /**
1252   * Called before the client opens a new scanner.
1253   * <p>
1254   * Note: Do not retain references to any Cells returned by scanner, beyond the life of this
1255   * invocation. If need a Cell reference for later use, copy the cell and use that.
1256   * @param c    the environment provided by the region server
1257   * @param scan the Scan specification
1258   */
1259  default void preScannerOpen(ObserverContext<RegionCoprocessorEnvironment> c, Scan scan)
1260    throws IOException {
1261  }
1262
1263  /**
1264   * Called after the client opens a new scanner.
1265   * <p>
1266   * Note: Do not retain references to any Cells returned by scanner, beyond the life of this
1267   * invocation. If need a Cell reference for later use, copy the cell and use that.
1268   * @param c    the environment provided by the region server
1269   * @param scan the Scan specification
1270   * @param s    if not null, the base scanner
1271   * @return the scanner instance to use
1272   */
1273  default RegionScanner postScannerOpen(ObserverContext<RegionCoprocessorEnvironment> c, Scan scan,
1274    RegionScanner s) throws IOException {
1275    return s;
1276  }
1277
1278  /**
1279   * Called before the client asks for the next row on a scanner.
1280   * <p>
1281   * Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on
1282   * calling any subsequent chained coprocessors.
1283   * <p>
1284   * Note: Do not retain references to any Cells returned by scanner, beyond the life of this
1285   * invocation. If need a Cell reference for later use, copy the cell and use that.
1286   * @param c       the environment provided by the region server
1287   * @param s       the scanner
1288   * @param result  The result to return to the client if default processing is bypassed. Can be
1289   *                modified. Will not be returned if default processing is not bypassed.
1290   * @param limit   the maximum number of results to return
1291   * @param hasNext the 'has more' indication
1292   * @return 'has more' indication that should be sent to client
1293   */
1294  default boolean preScannerNext(ObserverContext<RegionCoprocessorEnvironment> c, InternalScanner s,
1295    List<Result> result, int limit, boolean hasNext) throws IOException {
1296    return hasNext;
1297  }
1298
1299  /**
1300   * Called after the client asks for the next row on a scanner.
1301   * <p>
1302   * Note: Do not retain references to any Cells returned by scanner, beyond the life of this
1303   * invocation. If need a Cell reference for later use, copy the cell and use that.
1304   * @param c       the environment provided by the region server
1305   * @param s       the scanner
1306   * @param result  the result to return to the client, can be modified
1307   * @param limit   the maximum number of results to return
1308   * @param hasNext the 'has more' indication
1309   * @return 'has more' indication that should be sent to client
1310   */
1311  default boolean postScannerNext(ObserverContext<RegionCoprocessorEnvironment> c,
1312    InternalScanner s, List<Result> result, int limit, boolean hasNext) throws IOException {
1313    return hasNext;
1314  }
1315
1316  /**
1317   * This will be called by the scan flow when the current scanned row is being filtered out by the
1318   * filter. The filter may be filtering out the row via any of the below scenarios
1319   * <ol>
1320   * <li><code>boolean filterRowKey(byte [] buffer, int offset, int length)</code> returning
1321   * true</li>
1322   * <li><code>boolean filterRow()</code> returning true</li>
1323   * <li><code>default void filterRow(List&lt;KeyValue&gt; kvs)</code> removing all the kvs from the
1324   * passed List</li>
1325   * </ol>
1326   * <p>
1327   * Note: Do not retain references to any Cells returned by scanner, beyond the life of this
1328   * invocation. If need a Cell reference for later use, copy the cell and use that.
1329   * @param c          the environment provided by the region server
1330   * @param s          the scanner
1331   * @param curRowCell The cell in the current row which got filtered out
1332   * @param hasMore    the 'has more' indication
1333   * @return whether more rows are available for the scanner or not
1334   */
1335  default boolean postScannerFilterRow(ObserverContext<RegionCoprocessorEnvironment> c,
1336    InternalScanner s, Cell curRowCell, boolean hasMore) throws IOException {
1337    return hasMore;
1338  }
1339
1340  /**
1341   * Called before the client closes a scanner.
1342   * <p>
1343   * Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on
1344   * calling any subsequent chained coprocessors.
1345   * @param c the environment provided by the region server
1346   * @param s the scanner
1347   */
1348  default void preScannerClose(ObserverContext<RegionCoprocessorEnvironment> c, InternalScanner s)
1349    throws IOException {
1350  }
1351
1352  /**
1353   * Called after the client closes a scanner.
1354   * @param ctx the environment provided by the region server
1355   * @param s   the scanner
1356   */
1357  default void postScannerClose(ObserverContext<RegionCoprocessorEnvironment> ctx,
1358    InternalScanner s) throws IOException {
1359  }
1360
1361  /**
1362   * Called before a store opens a new scanner.
1363   * <p>
1364   * This hook is called when a "user" scanner is opened. Use {@code preFlushScannerOpen} and
1365   * {@code preCompactScannerOpen} to inject flush/compaction.
1366   * <p>
1367   * Notice that, this method is used to change the inherent max versions and TTL for a Store. For
1368   * example, you can change the max versions option for a {@link Scan} object to 10 in
1369   * {@code preScannerOpen}, but if the max versions config on the Store is 1, then you still can
1370   * only read 1 version. You need also to inject here to change the max versions to 10 if you want
1371   * to get more versions.
1372   * @param ctx     the environment provided by the region server
1373   * @param store   the store which we want to get scanner from
1374   * @param options used to change max versions and TTL for the scanner being opened
1375   * @see #preFlushScannerOpen(ObserverContext, Store, ScanOptions, FlushLifeCycleTracker)
1376   * @see #preCompactScannerOpen(ObserverContext, Store, ScanType, ScanOptions,
1377   *      CompactionLifeCycleTracker, CompactionRequest)
1378   */
1379  default void preStoreScannerOpen(ObserverContext<RegionCoprocessorEnvironment> ctx, Store store,
1380    ScanOptions options) throws IOException {
1381  }
1382
1383  /**
1384   * Called before replaying WALs for this region. Calling
1385   * {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} has no effect in this
1386   * hook.
1387   * @param ctx   the environment provided by the region server
1388   * @param info  the RegionInfo for this region
1389   * @param edits the file of recovered edits
1390   */
1391  // todo: what about these?
1392  default void preReplayWALs(ObserverContext<? extends RegionCoprocessorEnvironment> ctx,
1393    RegionInfo info, Path edits) throws IOException {
1394  }
1395
1396  /**
1397   * Called after replaying WALs for this region.
1398   * @param ctx   the environment provided by the region server
1399   * @param info  the RegionInfo for this region
1400   * @param edits the file of recovered edits
1401   */
1402  default void postReplayWALs(ObserverContext<? extends RegionCoprocessorEnvironment> ctx,
1403    RegionInfo info, Path edits) throws IOException {
1404  }
1405
1406  /**
1407   * Called before a {@link WALEdit} replayed for this region.
1408   * @param ctx the environment provided by the region server
1409   */
1410  default void preWALRestore(ObserverContext<? extends RegionCoprocessorEnvironment> ctx,
1411    RegionInfo info, WALKey logKey, WALEdit logEdit) throws IOException {
1412  }
1413
1414  /**
1415   * Called after a {@link WALEdit} replayed for this region.
1416   * @param ctx the environment provided by the region server
1417   */
1418  default void postWALRestore(ObserverContext<? extends RegionCoprocessorEnvironment> ctx,
1419    RegionInfo info, WALKey logKey, WALEdit logEdit) throws IOException {
1420  }
1421
1422  /**
1423   * Called before bulkLoadHFile. Users can create a StoreFile instance to access the contents of a
1424   * HFile.
1425   * @param ctx         the environment provided by the region server
1426   * @param familyPaths pairs of { CF, HFile path } submitted for bulk load. Adding or removing from
1427   *                    this list will add or remove HFiles to be bulk loaded.
1428   */
1429  default void preBulkLoadHFile(ObserverContext<RegionCoprocessorEnvironment> ctx,
1430    List<Pair<byte[], String>> familyPaths) throws IOException {
1431  }
1432
1433  /**
1434   * Called before moving bulk loaded hfile to region directory.
1435   * @param ctx    the environment provided by the region server
1436   * @param family column family
1437   * @param pairs  List of pairs of { HFile location in staging dir, HFile path in region dir } Each
1438   *               pair are for the same hfile.
1439   */
1440  default void preCommitStoreFile(ObserverContext<RegionCoprocessorEnvironment> ctx, byte[] family,
1441    List<Pair<Path, Path>> pairs) throws IOException {
1442  }
1443
1444  /**
1445   * Called after moving bulk loaded hfile to region directory.
1446   * @param ctx     the environment provided by the region server
1447   * @param family  column family
1448   * @param srcPath Path to file before the move
1449   * @param dstPath Path to file after the move
1450   */
1451  default void postCommitStoreFile(ObserverContext<RegionCoprocessorEnvironment> ctx, byte[] family,
1452    Path srcPath, Path dstPath) throws IOException {
1453  }
1454
1455  /**
1456   * Called after bulkLoadHFile.
1457   * @param ctx                the environment provided by the region server
1458   * @param stagingFamilyPaths pairs of { CF, HFile path } submitted for bulk load
1459   * @param finalPaths         Map of CF to List of file paths for the loaded files if the Map is
1460   *                           not null, the bulkLoad was successful. Otherwise the bulk load
1461   *                           failed. bulkload is done by the time this hook is called.
1462   */
1463  default void postBulkLoadHFile(ObserverContext<RegionCoprocessorEnvironment> ctx,
1464    List<Pair<byte[], String>> stagingFamilyPaths, Map<byte[], List<Path>> finalPaths)
1465    throws IOException {
1466  }
1467
1468  /**
1469   * Called before creation of Reader for a store file. Calling
1470   * {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} has no effect in this
1471   * hook.
1472   * @param ctx    the environment provided by the region server
1473   * @param fs     fileystem to read from
1474   * @param p      path to the file
1475   * @param in     {@link FSDataInputStreamWrapper}
1476   * @param size   Full size of the file
1477   * @param r      original reference file. This will be not null only when reading a split file.
1478   * @param reader the base reader, if not {@code null}, from previous RegionObserver in the chain
1479   * @return a Reader instance to use instead of the base reader if overriding default behavior,
1480   *         null otherwise
1481   * @deprecated For Phoenix only, StoreFileReader is not a stable interface.
1482   */
1483  @Deprecated
1484  // Passing InterfaceAudience.Private args FSDataInputStreamWrapper, CacheConfig and Reference.
1485  // This is fine as the hook is deprecated any way.
1486  default StoreFileReader preStoreFileReaderOpen(ObserverContext<RegionCoprocessorEnvironment> ctx,
1487    FileSystem fs, Path p, FSDataInputStreamWrapper in, long size, CacheConfig cacheConf,
1488    Reference r, StoreFileReader reader) throws IOException {
1489    return reader;
1490  }
1491
1492  /**
1493   * Called after the creation of Reader for a store file.
1494   * @param ctx    the environment provided by the region server
1495   * @param fs     fileystem to read from
1496   * @param p      path to the file
1497   * @param in     {@link FSDataInputStreamWrapper}
1498   * @param size   Full size of the file
1499   * @param r      original reference file. This will be not null only when reading a split file.
1500   * @param reader the base reader instance
1501   * @return The reader to use
1502   * @deprecated For Phoenix only, StoreFileReader is not a stable interface.
1503   */
1504  @Deprecated
1505  // Passing InterfaceAudience.Private args FSDataInputStreamWrapper, CacheConfig and Reference.
1506  // This is fine as the hook is deprecated any way.
1507  default StoreFileReader postStoreFileReaderOpen(ObserverContext<RegionCoprocessorEnvironment> ctx,
1508    FileSystem fs, Path p, FSDataInputStreamWrapper in, long size, CacheConfig cacheConf,
1509    Reference r, StoreFileReader reader) throws IOException {
1510    return reader;
1511  }
1512
1513  /**
1514   * Called after a new cell has been created during an increment operation, but before it is
1515   * committed to the WAL or memstore. Calling
1516   * {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} has no effect in this
1517   * hook.
1518   * @param ctx      the environment provided by the region server
1519   * @param opType   the operation type
1520   * @param mutation the current mutation
1521   * @param oldCell  old cell containing previous value
1522   * @param newCell  the new cell containing the computed value
1523   * @return the new cell, possibly changed
1524   * @deprecated since 2.2.0 and will be removedin 4.0.0. Use
1525   *             {@link #postIncrementBeforeWAL(ObserverContext, Mutation, List)} or
1526   *             {@link #postAppendBeforeWAL(ObserverContext, Mutation, List)} instead.
1527   * @see #postIncrementBeforeWAL(ObserverContext, Mutation, List)
1528   * @see #postAppendBeforeWAL(ObserverContext, Mutation, List)
1529   * @see <a href="https://issues.apache.org/jira/browse/HBASE-21643">HBASE-21643</a>
1530   */
1531  @Deprecated
1532  default Cell postMutationBeforeWAL(ObserverContext<RegionCoprocessorEnvironment> ctx,
1533    MutationType opType, Mutation mutation, Cell oldCell, Cell newCell) throws IOException {
1534    return newCell;
1535  }
1536
1537  /**
1538   * Called after a list of new cells has been created during an increment operation, but before
1539   * they are committed to the WAL or memstore.
1540   * @param ctx       the environment provided by the region server
1541   * @param mutation  the current mutation
1542   * @param cellPairs a list of cell pair. The first cell is old cell which may be null. And the
1543   *                  second cell is the new cell.
1544   * @return a list of cell pair, possibly changed.
1545   */
1546  default List<Pair<Cell, Cell>> postIncrementBeforeWAL(
1547    ObserverContext<RegionCoprocessorEnvironment> ctx, Mutation mutation,
1548    List<Pair<Cell, Cell>> cellPairs) throws IOException {
1549    List<Pair<Cell, Cell>> resultPairs = new ArrayList<>(cellPairs.size());
1550    for (Pair<Cell, Cell> pair : cellPairs) {
1551      resultPairs.add(new Pair<>(pair.getFirst(), postMutationBeforeWAL(ctx, MutationType.INCREMENT,
1552        mutation, pair.getFirst(), pair.getSecond())));
1553    }
1554    return resultPairs;
1555  }
1556
1557  /**
1558   * Called after a list of new cells has been created during an append operation, but before they
1559   * are committed to the WAL or memstore.
1560   * @param ctx       the environment provided by the region server
1561   * @param mutation  the current mutation
1562   * @param cellPairs a list of cell pair. The first cell is old cell which may be null. And the
1563   *                  second cell is the new cell.
1564   * @return a list of cell pair, possibly changed.
1565   */
1566  default List<Pair<Cell, Cell>> postAppendBeforeWAL(
1567    ObserverContext<RegionCoprocessorEnvironment> ctx, Mutation mutation,
1568    List<Pair<Cell, Cell>> cellPairs) throws IOException {
1569    List<Pair<Cell, Cell>> resultPairs = new ArrayList<>(cellPairs.size());
1570    for (Pair<Cell, Cell> pair : cellPairs) {
1571      resultPairs.add(new Pair<>(pair.getFirst(), postMutationBeforeWAL(ctx, MutationType.APPEND,
1572        mutation, pair.getFirst(), pair.getSecond())));
1573    }
1574    return resultPairs;
1575  }
1576
1577  /**
1578   * Called after the ScanQueryMatcher creates ScanDeleteTracker. Implementing this hook would help
1579   * in creating customised DeleteTracker and returning the newly created DeleteTracker
1580   * <p>
1581   * Warn: This is used by internal coprocessors. Should not be implemented by user coprocessors
1582   * @param ctx        the environment provided by the region server
1583   * @param delTracker the deleteTracker that is created by the QueryMatcher
1584   * @return the Delete Tracker
1585   * @deprecated Since 2.0 with out any replacement and will be removed in 3.0
1586   */
1587  @Deprecated
1588  default DeleteTracker postInstantiateDeleteTracker(
1589    ObserverContext<RegionCoprocessorEnvironment> ctx, DeleteTracker delTracker)
1590    throws IOException {
1591    return delTracker;
1592  }
1593
1594  /**
1595   * Called just before the WAL Entry is appended to the WAL. Implementing this hook allows
1596   * coprocessors to add extended attributes to the WALKey that then get persisted to the WAL, and
1597   * are available to replication endpoints to use in processing WAL Entries.
1598   * @param ctx the environment provided by the region server
1599   * @param key the WALKey associated with a particular append to a WAL
1600   */
1601  default void preWALAppend(ObserverContext<RegionCoprocessorEnvironment> ctx, WALKey key,
1602    WALEdit edit) throws IOException {
1603  }
1604}