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