diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.java index 4243d2f2059..7e0f2ae2b86 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.java @@ -143,8 +143,16 @@ public abstract class CoprocessorHost 1){ + overridePriority = Integer.parseInt(classNameAndPriority[1]); + hasPriorityOverride = true; + } className = className.trim(); if (findCoprocessor(className) != null) { // If already loaded will just continue @@ -155,13 +163,16 @@ public abstract class CoprocessorHost> host; host = new CoprocessorHostForTest<>(conf); + int overridePriority = Integer.MAX_VALUE - 1; + + final String coprocessor_v3 = + SimpleRegionObserverV3.class.getName() + "|" + overridePriority; // Try and load a coprocessor three times conf.setStrings(key, coprocessor, coprocessor, coprocessor, - SimpleRegionObserverV2.class.getName()); + SimpleRegionObserverV2.class.getName(), coprocessor_v3); host.loadSystemCoprocessors(conf, key); - // Two coprocessors(SimpleRegionObserver and SimpleRegionObserverV2) loaded - Assert.assertEquals(2, host.coprocEnvironments.size()); + // Three coprocessors(SimpleRegionObserver, SimpleRegionObserverV2, + // SimpleRegionObserverV3) loaded + Assert.assertEquals(3, host.coprocEnvironments.size()); // Check the priority value CoprocessorEnvironment simpleEnv = host.findCoprocessorEnvironment( SimpleRegionObserver.class.getName()); CoprocessorEnvironment simpleEnv_v2 = host.findCoprocessorEnvironment( SimpleRegionObserverV2.class.getName()); + CoprocessorEnvironment simpleEnv_v3 = host.findCoprocessorEnvironment( + SimpleRegionObserverV3.class.getName()); assertNotNull(simpleEnv); assertNotNull(simpleEnv_v2); + assertNotNull(simpleEnv_v3); assertEquals(Coprocessor.PRIORITY_SYSTEM, simpleEnv.getPriority()); assertEquals(Coprocessor.PRIORITY_SYSTEM + 1, simpleEnv_v2.getPriority()); + assertEquals(overridePriority, simpleEnv_v3.getPriority()); } public static class SimpleRegionObserverV2 extends SimpleRegionObserver { } + public static class SimpleRegionObserverV3 extends SimpleRegionObserver { + + } + private static class CoprocessorHostForTest extends CoprocessorHost> { final Configuration cpHostConf; diff --git a/src/main/asciidoc/_chapters/cp.adoc b/src/main/asciidoc/_chapters/cp.adoc index abe334c68af..e769efd2840 100644 --- a/src/main/asciidoc/_chapters/cp.adoc +++ b/src/main/asciidoc/_chapters/cp.adoc @@ -242,12 +242,28 @@ following entry in RegionServer's 'hbase-site.xml' file (generally located under If multiple classes are specified for loading, the class names must be comma-separated. The framework attempts to load all the configured classes using the default class loader. Therefore, the jar file must reside on the server-side HBase classpath. + + Coprocessors which are loaded in this way will be active on all regions of all tables. These are also called system Coprocessor. The first listed Coprocessors will be assigned the priority `Coprocessor.Priority.SYSTEM`. Each subsequent coprocessor in the list will have its priority value incremented by one (which reduces its priority, because priorities have the natural sort order of Integers). + ++ +These priority values can be manually overriden in hbase-site.xml. This can be useful if you +want to guarantee that a coprocessor will execute after another. For example, in the following +configuration `SumEndPoint` would be guaranteed to go last, except in the case of a tie with +another coprocessor: ++ +[source,xml] +---- + + hbase.coprocessor.region.classes + org.myname.hbase.coprocessor.endpoint.SumEndPoint|2147483647 + +---- + + When calling out to registered observers, the framework executes their callbacks methods in the sorted order of their priority. + @@ -786,7 +802,7 @@ Restricting arbitrary user coprocessors can be a big concern in multitenant envi - `hbase.coprocessor.enabled`: Enables or disables all coprocessors. This will limit the functionality of HBase, as disabling all coprocessors will disable some security providers. An example coproccessor so affected is `org.apache.hadoop.hbase.security.access.AccessController`. * `hbase.coprocessor.user.enabled`: Enables or disables loading coprocessors on tables (i.e. user coprocessors). -* One can statically load coprocessors via the following tunables in `hbase-site.xml`: +* One can statically load coprocessors, and optionally tune their priorities, via the following tunables in `hbase-site.xml`: ** `hbase.coprocessor.regionserver.classes`: A comma-separated list of coprocessors that are loaded by region servers ** `hbase.coprocessor.region.classes`: A comma-separated list of RegionObserver and Endpoint coprocessors ** `hbase.coprocessor.user.region.classes`: A comma-separated list of coprocessors that are loaded by all regions