hbase-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From a...@apache.org
Subject [2/7] hbase git commit: HBASE-17732 Coprocessor Design Improvements
Date Wed, 27 Sep 2017 19:50:21 GMT
http://git-wip-us.apache.org/repos/asf/hbase/blob/0c883a23/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestReplicaWithCluster.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestReplicaWithCluster.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestReplicaWithCluster.java
index 264c646..d580b42 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestReplicaWithCluster.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestReplicaWithCluster.java
@@ -24,6 +24,7 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Optional;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicLong;
@@ -46,6 +47,7 @@ import org.apache.hadoop.hbase.Waiter;
 
 import org.apache.hadoop.hbase.client.replication.ReplicationAdmin;
 import org.apache.hadoop.hbase.coprocessor.ObserverContext;
+import org.apache.hadoop.hbase.coprocessor.RegionCoprocessor;
 import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
 import org.apache.hadoop.hbase.coprocessor.RegionObserver;
 import org.apache.hadoop.hbase.ipc.RpcControllerFactory;
@@ -83,7 +85,7 @@ public class TestReplicaWithCluster {
   /**
    * This copro is used to synchronize the tests.
    */
-  public static class SlowMeCopro implements RegionObserver {
+  public static class SlowMeCopro implements RegionCoprocessor, RegionObserver {
     static final AtomicLong sleepTime = new AtomicLong(0);
     static final AtomicReference<CountDownLatch> cdl = new AtomicReference<>(new CountDownLatch(0));
 
@@ -91,6 +93,11 @@ public class TestReplicaWithCluster {
     }
 
     @Override
+    public Optional<RegionObserver> getRegionObserver() {
+      return Optional.of(this);
+    }
+
+    @Override
     public void preGetOp(final ObserverContext<RegionCoprocessorEnvironment> e,
                          final Get get, final List<Cell> results) throws IOException {
 
@@ -119,12 +126,17 @@ public class TestReplicaWithCluster {
   /**
    * This copro is used to simulate region server down exception for Get and Scan
    */
-  public static class RegionServerStoppedCopro implements RegionObserver {
+  public static class RegionServerStoppedCopro implements RegionCoprocessor, RegionObserver {
 
     public RegionServerStoppedCopro() {
     }
 
     @Override
+    public Optional<RegionObserver> getRegionObserver() {
+      return Optional.of(this);
+    }
+
+    @Override
     public void preGetOp(final ObserverContext<RegionCoprocessorEnvironment> e,
         final Get get, final List<Cell> results) throws IOException {
 
@@ -164,11 +176,17 @@ public class TestReplicaWithCluster {
   /**
    * This copro is used to slow down the primary meta region scan a bit
    */
-  public static class RegionServerHostingPrimayMetaRegionSlowOrStopCopro implements RegionObserver {
+  public static class RegionServerHostingPrimayMetaRegionSlowOrStopCopro
+      implements RegionCoprocessor, RegionObserver {
     static boolean slowDownPrimaryMetaScan = false;
     static boolean throwException = false;
 
     @Override
+    public Optional<RegionObserver> getRegionObserver() {
+      return Optional.of(this);
+    }
+
+    @Override
     public void preGetOp(final ObserverContext<RegionCoprocessorEnvironment> e,
         final Get get, final List<Cell> results) throws IOException {
 

http://git-wip-us.apache.org/repos/asf/hbase/blob/0c883a23/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestReplicasClient.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestReplicasClient.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestReplicasClient.java
index 46c3f0d..1a3cfbf 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestReplicasClient.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestReplicasClient.java
@@ -24,6 +24,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Optional;
 import java.util.Random;
 import java.util.Set;
 import java.util.concurrent.CountDownLatch;
@@ -47,6 +48,7 @@ import org.apache.hadoop.hbase.NotServingRegionException;
 import org.apache.hadoop.hbase.RegionLocations;
 import org.apache.hadoop.hbase.TableNotFoundException;
 import org.apache.hadoop.hbase.coprocessor.ObserverContext;
+import org.apache.hadoop.hbase.coprocessor.RegionCoprocessor;
 import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
 import org.apache.hadoop.hbase.coprocessor.RegionObserver;
 import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
@@ -98,7 +100,7 @@ public class TestReplicasClient {
   /**
    * This copro is used to synchronize the tests.
    */
-  public static class SlowMeCopro implements RegionObserver {
+  public static class SlowMeCopro implements RegionCoprocessor, RegionObserver {
     static final AtomicLong sleepTime = new AtomicLong(0);
     static final AtomicBoolean slowDownNext = new AtomicBoolean(false);
     static final AtomicInteger countOfNext = new AtomicInteger(0);
@@ -109,6 +111,11 @@ public class TestReplicasClient {
     }
 
     @Override
+    public Optional<RegionObserver> getRegionObserver() {
+      return Optional.of(this);
+    }
+
+    @Override
     public void preGetOp(final ObserverContext<RegionCoprocessorEnvironment> e,
                          final Get get, final List<Cell> results) throws IOException {
       slowdownCode(e);

http://git-wip-us.apache.org/repos/asf/hbase/blob/0c883a23/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestResultFromCoprocessor.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestResultFromCoprocessor.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestResultFromCoprocessor.java
index 4425fb2..1fb0f64 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestResultFromCoprocessor.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestResultFromCoprocessor.java
@@ -21,6 +21,8 @@ package org.apache.hadoop.hbase.client;
 
 import java.io.IOException;
 import java.util.Arrays;
+import java.util.Optional;
+
 import static junit.framework.TestCase.assertTrue;
 import org.apache.hadoop.hbase.Cell;
 import org.apache.hadoop.hbase.CellUtil;
@@ -29,6 +31,7 @@ import org.apache.hadoop.hbase.HBaseTestingUtility;
 import org.apache.hadoop.hbase.KeyValue;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.coprocessor.ObserverContext;
+import org.apache.hadoop.hbase.coprocessor.RegionCoprocessor;
 import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
 import org.apache.hadoop.hbase.coprocessor.RegionObserver;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
@@ -101,7 +104,11 @@ public class TestResultFromCoprocessor {
     }
   }
 
-  public static class MyObserver implements RegionObserver {
+  public static class MyObserver implements RegionCoprocessor, RegionObserver {
+    @Override
+    public Optional<RegionObserver> getRegionObserver() {
+      return Optional.of(this);
+    }
 
     @Override
     public Result postAppend(final ObserverContext<RegionCoprocessorEnvironment> c,

http://git-wip-us.apache.org/repos/asf/hbase/blob/0c883a23/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestServerBusyException.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestServerBusyException.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestServerBusyException.java
index aba5b07..b1126e5 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestServerBusyException.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestServerBusyException.java
@@ -22,6 +22,7 @@ import static org.junit.Assert.assertEquals;
 
 import java.io.IOException;
 import java.util.List;
+import java.util.Optional;
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.hadoop.conf.Configuration;
@@ -32,6 +33,7 @@ import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.HTableDescriptor;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.coprocessor.ObserverContext;
+import org.apache.hadoop.hbase.coprocessor.RegionCoprocessor;
 import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
 import org.apache.hadoop.hbase.coprocessor.RegionObserver;
 import org.apache.hadoop.hbase.ipc.ServerTooBusyException;
@@ -66,9 +68,14 @@ public class TestServerBusyException {
   @Rule
   public TestName name = new TestName();
 
-  public static class SleepCoprocessor implements RegionObserver {
+  public static class SleepCoprocessor implements RegionCoprocessor, RegionObserver {
     public static final int SLEEP_TIME = 5000;
     @Override
+    public Optional<RegionObserver> getRegionObserver() {
+      return Optional.of(this);
+    }
+
+    @Override
     public void preGetOp(final ObserverContext<RegionCoprocessorEnvironment> e,
         final Get get, final List<Cell> results) throws IOException {
       Threads.sleep(SLEEP_TIME);
@@ -95,9 +102,15 @@ public class TestServerBusyException {
 
   }
 
-  public static class SleepLongerAtFirstCoprocessor implements RegionObserver {
+  public static class SleepLongerAtFirstCoprocessor implements RegionCoprocessor, RegionObserver {
     public static final int SLEEP_TIME = 2000;
     static final AtomicLong ct = new AtomicLong(0);
+
+    @Override
+    public Optional<RegionObserver> getRegionObserver() {
+      return Optional.of(this);
+    }
+
     @Override
     public void preGetOp(final ObserverContext<RegionCoprocessorEnvironment> e,
         final Get get, final List<Cell> results) throws IOException {

http://git-wip-us.apache.org/repos/asf/hbase/blob/0c883a23/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/SampleRegionWALCoprocessor.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/SampleRegionWALCoprocessor.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/SampleRegionWALCoprocessor.java
new file mode 100644
index 0000000..6dbd04f
--- /dev/null
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/SampleRegionWALCoprocessor.java
@@ -0,0 +1,199 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hbase.coprocessor;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hbase.Cell;
+import org.apache.hadoop.hbase.CellUtil;
+import org.apache.hadoop.hbase.KeyValue;
+import org.apache.hadoop.hbase.client.RegionInfo;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.wal.WALEdit;
+import org.apache.hadoop.hbase.wal.WALKey;
+
+/**
+ * Class for testing WALObserver coprocessor. It will monitor WAL writing and restoring, and modify
+ * passed-in WALEdit, i.e, ignore specified columns when writing, or add a KeyValue. On the other
+ * side, it checks whether the ignored column is still in WAL when Restoreed at region reconstruct.
+ */
+public class SampleRegionWALCoprocessor implements WALCoprocessor, RegionCoprocessor,
+    WALObserver, RegionObserver {
+
+  private static final Log LOG = LogFactory.getLog(SampleRegionWALCoprocessor.class);
+
+  private byte[] tableName;
+  private byte[] row;
+  private byte[] ignoredFamily;
+  private byte[] ignoredQualifier;
+  private byte[] addedFamily;
+  private byte[] addedQualifier;
+  private byte[] changedFamily;
+  private byte[] changedQualifier;
+
+  private boolean preWALWriteCalled = false;
+  private boolean postWALWriteCalled = false;
+  private boolean preWALRestoreCalled = false;
+  private boolean postWALRestoreCalled = false;
+  private boolean preWALRollCalled = false;
+  private boolean postWALRollCalled = false;
+
+  /**
+   * Set values: with a table name, a column name which will be ignored, and
+   * a column name which will be added to WAL.
+   */
+  public void setTestValues(byte[] tableName, byte[] row, byte[] igf, byte[] igq,
+      byte[] chf, byte[] chq, byte[] addf, byte[] addq) {
+    this.row = row;
+    this.tableName = tableName;
+    this.ignoredFamily = igf;
+    this.ignoredQualifier = igq;
+    this.addedFamily = addf;
+    this.addedQualifier = addq;
+    this.changedFamily = chf;
+    this.changedQualifier = chq;
+    preWALWriteCalled = false;
+    postWALWriteCalled = false;
+    preWALRestoreCalled = false;
+    postWALRestoreCalled = false;
+    preWALRollCalled = false;
+    postWALRollCalled = false;
+  }
+
+  @Override public Optional<WALObserver> getWALObserver() {
+    return Optional.of(this);
+  }
+
+  @Override
+  public Optional<RegionObserver> getRegionObserver() {
+    return Optional.of(this);
+  }
+
+  @Override
+  public void postWALWrite(ObserverContext<? extends WALCoprocessorEnvironment> env,
+      RegionInfo info, WALKey logKey, WALEdit logEdit) throws IOException {
+    postWALWriteCalled = true;
+  }
+
+  @Override
+  public boolean preWALWrite(ObserverContext<? extends WALCoprocessorEnvironment> env,
+      RegionInfo info, WALKey logKey, WALEdit logEdit) throws IOException {
+    boolean bypass = false;
+    // check table name matches or not.
+    if (!Bytes.equals(info.getTable().toBytes(), this.tableName)) {
+      return bypass;
+    }
+    preWALWriteCalled = true;
+    // here we're going to remove one keyvalue from the WALEdit, and add
+    // another one to it.
+    List<Cell> cells = logEdit.getCells();
+    Cell deletedCell = null;
+    for (Cell cell : cells) {
+      // assume only one kv from the WALEdit matches.
+      byte[] family = CellUtil.cloneFamily(cell);
+      byte[] qulifier = CellUtil.cloneQualifier(cell);
+
+      if (Arrays.equals(family, ignoredFamily) &&
+          Arrays.equals(qulifier, ignoredQualifier)) {
+        LOG.debug("Found the KeyValue from WALEdit which should be ignored.");
+        deletedCell = cell;
+      }
+      if (Arrays.equals(family, changedFamily) &&
+          Arrays.equals(qulifier, changedQualifier)) {
+        LOG.debug("Found the KeyValue from WALEdit which should be changed.");
+        cell.getValueArray()[cell.getValueOffset()] += 1;
+      }
+    }
+    if (null != row) {
+      cells.add(new KeyValue(row, addedFamily, addedQualifier));
+    }
+    if (deletedCell != null) {
+      LOG.debug("About to delete a KeyValue from WALEdit.");
+      cells.remove(deletedCell);
+    }
+    return bypass;
+  }
+
+  /**
+   * Triggered before  {@link org.apache.hadoop.hbase.regionserver.HRegion} when WAL is
+   * Restoreed.
+   */
+  @Override
+  public void preWALRestore(ObserverContext<? extends RegionCoprocessorEnvironment> env,
+    RegionInfo info, WALKey logKey, WALEdit logEdit) throws IOException {
+    preWALRestoreCalled = true;
+  }
+
+  @Override
+  public void preWALRoll(ObserverContext<? extends WALCoprocessorEnvironment> ctx,
+      Path oldPath, Path newPath) throws IOException {
+    preWALRollCalled = true;
+  }
+
+  @Override
+  public void postWALRoll(ObserverContext<? extends WALCoprocessorEnvironment> ctx,
+      Path oldPath, Path newPath) throws IOException {
+    postWALRollCalled = true;
+  }
+
+  /**
+   * Triggered after {@link org.apache.hadoop.hbase.regionserver.HRegion} when WAL is
+   * Restoreed.
+   */
+  @Override
+  public void postWALRestore(ObserverContext<? extends RegionCoprocessorEnvironment> env,
+      RegionInfo info, WALKey logKey, WALEdit logEdit) throws IOException {
+    postWALRestoreCalled = true;
+  }
+
+  public boolean isPreWALWriteCalled() {
+    return preWALWriteCalled;
+  }
+
+  public boolean isPostWALWriteCalled() {
+    return postWALWriteCalled;
+  }
+
+  public boolean isPreWALRestoreCalled() {
+    LOG.debug(SampleRegionWALCoprocessor.class.getName() +
+      ".isPreWALRestoreCalled is called.");
+    return preWALRestoreCalled;
+  }
+
+  public boolean isPostWALRestoreCalled() {
+    LOG.debug(SampleRegionWALCoprocessor.class.getName() +
+      ".isPostWALRestoreCalled is called.");
+    return postWALRestoreCalled;
+  }
+
+  public boolean isPreWALRollCalled() {
+    return preWALRollCalled;
+  }
+
+  public boolean isPostWALRollCalled() {
+    return postWALRollCalled;
+  }
+}

http://git-wip-us.apache.org/repos/asf/hbase/blob/0c883a23/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/SampleRegionWALObserver.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/SampleRegionWALObserver.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/SampleRegionWALObserver.java
deleted file mode 100644
index e338941..0000000
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/SampleRegionWALObserver.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/**
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.hadoop.hbase.coprocessor;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.fs.Path;
-import org.apache.hadoop.hbase.Cell;
-import org.apache.hadoop.hbase.CellUtil;
-import org.apache.hadoop.hbase.KeyValue;
-import org.apache.hadoop.hbase.client.RegionInfo;
-import org.apache.hadoop.hbase.util.Bytes;
-import org.apache.hadoop.hbase.wal.WALEdit;
-import org.apache.hadoop.hbase.wal.WALKey;
-
-/**
- * Class for testing WALObserver coprocessor. It will monitor WAL writing and restoring, and modify
- * passed-in WALEdit, i.e, ignore specified columns when writing, or add a KeyValue. On the other
- * side, it checks whether the ignored column is still in WAL when Restoreed at region reconstruct.
- */
-public class SampleRegionWALObserver implements WALObserver, RegionObserver {
-
-  private static final Log LOG = LogFactory.getLog(SampleRegionWALObserver.class);
-
-  private byte[] tableName;
-  private byte[] row;
-  private byte[] ignoredFamily;
-  private byte[] ignoredQualifier;
-  private byte[] addedFamily;
-  private byte[] addedQualifier;
-  private byte[] changedFamily;
-  private byte[] changedQualifier;
-
-  private boolean preWALWriteCalled = false;
-  private boolean postWALWriteCalled = false;
-  private boolean preWALRestoreCalled = false;
-  private boolean postWALRestoreCalled = false;
-  private boolean preWALRollCalled = false;
-  private boolean postWALRollCalled = false;
-
-  /**
-   * Set values: with a table name, a column name which will be ignored, and
-   * a column name which will be added to WAL.
-   */
-  public void setTestValues(byte[] tableName, byte[] row, byte[] igf, byte[] igq,
-      byte[] chf, byte[] chq, byte[] addf, byte[] addq) {
-    this.row = row;
-    this.tableName = tableName;
-    this.ignoredFamily = igf;
-    this.ignoredQualifier = igq;
-    this.addedFamily = addf;
-    this.addedQualifier = addq;
-    this.changedFamily = chf;
-    this.changedQualifier = chq;
-    preWALWriteCalled = false;
-    postWALWriteCalled = false;
-    preWALRestoreCalled = false;
-    postWALRestoreCalled = false;
-    preWALRollCalled = false;
-    postWALRollCalled = false;
-  }
-
-  @Override
-  public void postWALWrite(ObserverContext<? extends WALCoprocessorEnvironment> env,
-      RegionInfo info, WALKey logKey, WALEdit logEdit) throws IOException {
-    postWALWriteCalled = true;
-  }
-
-  @Override
-  public boolean preWALWrite(ObserverContext<? extends WALCoprocessorEnvironment> env,
-      RegionInfo info, WALKey logKey, WALEdit logEdit) throws IOException {
-    boolean bypass = false;
-    // check table name matches or not.
-    if (!Bytes.equals(info.getTable().toBytes(), this.tableName)) {
-      return bypass;
-    }
-    preWALWriteCalled = true;
-    // here we're going to remove one keyvalue from the WALEdit, and add
-    // another one to it.
-    List<Cell> cells = logEdit.getCells();
-    Cell deletedCell = null;
-    for (Cell cell : cells) {
-      // assume only one kv from the WALEdit matches.
-      byte[] family = CellUtil.cloneFamily(cell);
-      byte[] qulifier = CellUtil.cloneQualifier(cell);
-
-      if (Arrays.equals(family, ignoredFamily) &&
-          Arrays.equals(qulifier, ignoredQualifier)) {
-        LOG.debug("Found the KeyValue from WALEdit which should be ignored.");
-        deletedCell = cell;
-      }
-      if (Arrays.equals(family, changedFamily) &&
-          Arrays.equals(qulifier, changedQualifier)) {
-        LOG.debug("Found the KeyValue from WALEdit which should be changed.");
-        cell.getValueArray()[cell.getValueOffset()] += 1;
-      }
-    }
-    if (null != row) {
-      cells.add(new KeyValue(row, addedFamily, addedQualifier));
-    }
-    if (deletedCell != null) {
-      LOG.debug("About to delete a KeyValue from WALEdit.");
-      cells.remove(deletedCell);
-    }
-    return bypass;
-  }
-
-  /**
-   * Triggered before  {@link org.apache.hadoop.hbase.regionserver.HRegion} when WAL is
-   * Restoreed.
-   */
-  @Override
-  public void preWALRestore(ObserverContext<? extends RegionCoprocessorEnvironment> env,
-    RegionInfo info, WALKey logKey, WALEdit logEdit) throws IOException {
-    preWALRestoreCalled = true;
-  }
-
-  @Override
-  public void preWALRoll(ObserverContext<? extends WALCoprocessorEnvironment> ctx,
-      Path oldPath, Path newPath) throws IOException {
-    preWALRollCalled = true;
-  }
-
-  @Override
-  public void postWALRoll(ObserverContext<? extends WALCoprocessorEnvironment> ctx,
-      Path oldPath, Path newPath) throws IOException {
-    postWALRollCalled = true;
-  }
-
-  /**
-   * Triggered after {@link org.apache.hadoop.hbase.regionserver.HRegion} when WAL is
-   * Restoreed.
-   */
-  @Override
-  public void postWALRestore(ObserverContext<? extends RegionCoprocessorEnvironment> env,
-      RegionInfo info, WALKey logKey, WALEdit logEdit) throws IOException {
-    postWALRestoreCalled = true;
-  }
-
-  public boolean isPreWALWriteCalled() {
-    return preWALWriteCalled;
-  }
-
-  public boolean isPostWALWriteCalled() {
-    return postWALWriteCalled;
-  }
-
-  public boolean isPreWALRestoreCalled() {
-    LOG.debug(SampleRegionWALObserver.class.getName() +
-      ".isPreWALRestoreCalled is called.");
-    return preWALRestoreCalled;
-  }
-
-  public boolean isPostWALRestoreCalled() {
-    LOG.debug(SampleRegionWALObserver.class.getName() +
-      ".isPostWALRestoreCalled is called.");
-    return postWALRestoreCalled;
-  }
-
-  public boolean isPreWALRollCalled() {
-    return preWALRollCalled;
-  }
-
-  public boolean isPostWALRollCalled() {
-    return postWALRollCalled;
-  }
-}

http://git-wip-us.apache.org/repos/asf/hbase/blob/0c883a23/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/SimpleRegionObserver.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/SimpleRegionObserver.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/SimpleRegionObserver.java
index 5868bf9..727fa39 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/SimpleRegionObserver.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/SimpleRegionObserver.java
@@ -28,6 +28,7 @@ import java.io.IOException;
 import java.util.List;
 import java.util.Map;
 import java.util.NavigableSet;
+import java.util.Optional;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -72,7 +73,7 @@ import org.apache.hadoop.hbase.shaded.com.google.common.collect.ImmutableList;
  * A sample region observer that tests the RegionObserver interface.
  * It works with TestRegionObserverInterface to provide the test case.
  */
-public class SimpleRegionObserver implements RegionObserver {
+public class SimpleRegionObserver implements RegionCoprocessor, RegionObserver {
 
   final AtomicInteger ctBeforeDelete = new AtomicInteger(1);
   final AtomicInteger ctPreOpen = new AtomicInteger(0);
@@ -135,6 +136,11 @@ public class SimpleRegionObserver implements RegionObserver {
   }
 
   @Override
+  public Optional<RegionObserver> getRegionObserver() {
+    return Optional.of(this);
+  }
+
+  @Override
   public void start(CoprocessorEnvironment e) throws IOException {
   }
 

http://git-wip-us.apache.org/repos/asf/hbase/blob/0c883a23/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorConfiguration.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorConfiguration.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorConfiguration.java
index 1102cf8..6213e86 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorConfiguration.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorConfiguration.java
@@ -20,13 +20,13 @@
 package org.apache.hadoop.hbase.coprocessor;
 
 import java.io.IOException;
+import java.util.Optional;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import static org.mockito.Mockito.*;
 import static org.junit.Assert.*;
 
 import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.hbase.Coprocessor;
 import org.apache.hadoop.hbase.CoprocessorEnvironment;
 import org.apache.hadoop.hbase.HBaseConfiguration;
 import org.apache.hadoop.hbase.HRegionInfo;
@@ -74,7 +74,8 @@ public class TestCoprocessorConfiguration {
   private static final AtomicBoolean systemCoprocessorLoaded = new AtomicBoolean();
   private static final AtomicBoolean tableCoprocessorLoaded = new AtomicBoolean();
 
-  public static class SystemCoprocessor implements Coprocessor {
+  public static class SystemCoprocessor implements MasterCoprocessor, RegionCoprocessor,
+      RegionServerCoprocessor {
     @Override
     public void start(CoprocessorEnvironment env) throws IOException {
       systemCoprocessorLoaded.set(true);
@@ -84,7 +85,7 @@ public class TestCoprocessorConfiguration {
     public void stop(CoprocessorEnvironment env) throws IOException { }
   }
 
-  public static class TableCoprocessor implements Coprocessor {
+  public static class TableCoprocessor implements RegionCoprocessor {
     @Override
     public void start(CoprocessorEnvironment env) throws IOException {
       tableCoprocessorLoaded.set(true);
@@ -108,7 +109,7 @@ public class TestCoprocessorConfiguration {
       systemCoprocessorLoaded.get(),
       CoprocessorHost.DEFAULT_COPROCESSORS_ENABLED);
     assertEquals("Table coprocessors loading default was not honored",
-      tableCoprocessorLoaded.get(), 
+      tableCoprocessorLoaded.get(),
       CoprocessorHost.DEFAULT_COPROCESSORS_ENABLED &&
       CoprocessorHost.DEFAULT_USER_COPROCESSORS_ENABLED);
   }

http://git-wip-us.apache.org/repos/asf/hbase/blob/0c883a23/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorHost.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorHost.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorHost.java
index f0915e0..03cae78 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorHost.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorHost.java
@@ -39,7 +39,7 @@ public class TestCoprocessorHost {
   /**
    * An {@link Abortable} implementation for tests.
    */
-  class TestAbortable implements Abortable {
+  private class TestAbortable implements Abortable {
     private volatile boolean aborted = false;
 
     @Override
@@ -56,13 +56,23 @@ public class TestCoprocessorHost {
   @Test
   public void testDoubleLoadingAndPriorityValue() {
     final Configuration conf = HBaseConfiguration.create();
-    CoprocessorHost<CoprocessorEnvironment> host =
-        new CoprocessorHost<CoprocessorEnvironment>(new TestAbortable()) {
-      final Configuration cpHostConf = conf;
+    CoprocessorHost<RegionCoprocessor, CoprocessorEnvironment<RegionCoprocessor>> host =
+        new CoprocessorHost<RegionCoprocessor, CoprocessorEnvironment<RegionCoprocessor>>(
+            new TestAbortable()) {
+          @Override
+          public RegionCoprocessor checkAndGetInstance(Class<?> implClass)
+              throws InstantiationException, IllegalAccessException {
+            if(RegionCoprocessor.class.isAssignableFrom(implClass)) {
+              return (RegionCoprocessor)implClass.newInstance();
+            }
+            return null;
+          }
+
+          final Configuration cpHostConf = conf;
 
       @Override
-      public CoprocessorEnvironment createEnvironment(Class<?> implClass,
-          final Coprocessor instance, final int priority, int sequence, Configuration conf) {
+      public CoprocessorEnvironment createEnvironment(final RegionCoprocessor instance,
+          final int priority, int sequence, Configuration conf) {
         return new CoprocessorEnvironment() {
           final Coprocessor envInstance = instance;
 
@@ -107,6 +117,12 @@ public class TestCoprocessorHost {
           }
 
           @Override
+          public void startup() throws IOException {}
+
+          @Override
+          public void shutdown() {}
+
+          @Override
           public ClassLoader getClassLoader() {
             return null;
           }
@@ -116,13 +132,16 @@ public class TestCoprocessorHost {
     final String key = "KEY";
     final String coprocessor = "org.apache.hadoop.hbase.coprocessor.SimpleRegionObserver";
     // Try and load a coprocessor three times
-    conf.setStrings(key, coprocessor, coprocessor, coprocessor, SimpleRegionObserverV2.class.getName());
+    conf.setStrings(key, coprocessor, coprocessor, coprocessor,
+        SimpleRegionObserverV2.class.getName());
     host.loadSystemCoprocessors(conf, key);
     // Two coprocessors(SimpleRegionObserver and SimpleRegionObserverV2) loaded
-    Assert.assertEquals(2, host.coprocessors.size());
+    Assert.assertEquals(2, host.coprocEnvironments.size());
     // Check the priority value
-    CoprocessorEnvironment simpleEnv = host.findCoprocessorEnvironment(SimpleRegionObserver.class.getName());
-    CoprocessorEnvironment simpleEnv_v2 = host.findCoprocessorEnvironment(SimpleRegionObserverV2.class.getName());
+    CoprocessorEnvironment simpleEnv = host.findCoprocessorEnvironment(
+        SimpleRegionObserver.class.getName());
+    CoprocessorEnvironment simpleEnv_v2 = host.findCoprocessorEnvironment(
+        SimpleRegionObserverV2.class.getName());
     assertNotNull(simpleEnv);
     assertNotNull(simpleEnv_v2);
     assertEquals(Coprocessor.PRIORITY_SYSTEM, simpleEnv.getPriority());

http://git-wip-us.apache.org/repos/asf/hbase/blob/0c883a23/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorInterface.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorInterface.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorInterface.java
index 5cf0bb3..3ff0f1f 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorInterface.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorInterface.java
@@ -32,6 +32,7 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.concurrent.ConcurrentMap;
 
 import org.apache.commons.logging.Log;
@@ -62,7 +63,6 @@ import org.apache.hadoop.hbase.regionserver.ScannerContext;
 import org.apache.hadoop.hbase.regionserver.Store;
 import org.apache.hadoop.hbase.regionserver.StoreFile;
 import org.apache.hadoop.hbase.regionserver.compactions.CompactionLifeCycleTracker;
-import org.apache.hadoop.hbase.regionserver.compactions.CompactionRequest;
 import org.apache.hadoop.hbase.testclassification.CoprocessorTests;
 import org.apache.hadoop.hbase.testclassification.SmallTests;
 import org.junit.Rule;
@@ -149,7 +149,7 @@ public class TestCoprocessorInterface {
     }
   }
 
-  public static class CoprocessorImpl implements RegionObserver {
+  public static class CoprocessorImpl implements RegionCoprocessor, RegionObserver {
 
     private boolean startCalled;
     private boolean stopCalled;
@@ -178,6 +178,11 @@ public class TestCoprocessorInterface {
     }
 
     @Override
+    public Optional<RegionObserver> getRegionObserver() {
+      return Optional.of(this);
+    }
+
+    @Override
     public void preOpen(ObserverContext<RegionCoprocessorEnvironment> e) {
       preOpenCalled = true;
     }
@@ -242,23 +247,31 @@ public class TestCoprocessorInterface {
     }
   }
 
-  public static class CoprocessorII implements RegionObserver {
+  public static class CoprocessorII implements RegionCoprocessor {
     private ConcurrentMap<String, Object> sharedData;
+
     @Override
     public void start(CoprocessorEnvironment e) {
       sharedData = ((RegionCoprocessorEnvironment)e).getSharedData();
       sharedData.putIfAbsent("test2", new Object());
     }
+
     @Override
     public void stop(CoprocessorEnvironment e) {
       sharedData = null;
     }
+
     @Override
-    public void preGetOp(final ObserverContext<RegionCoprocessorEnvironment> e,
-        final Get get, final List<Cell> results) throws IOException {
-      if (1/0 == 1) {
-        e.complete();
-      }
+    public Optional<RegionObserver> getRegionObserver() {
+      return Optional.of(new RegionObserver() {
+        @Override
+        public void preGetOp(final ObserverContext<RegionCoprocessorEnvironment> e,
+            final Get get, final List<Cell> results) throws IOException {
+          if (1/0 == 1) {
+            e.complete();
+          }
+        }
+      });
     }
 
     Map<String, Object> getSharedData() {
@@ -272,8 +285,7 @@ public class TestCoprocessorInterface {
     byte [][] families = { fam1, fam2, fam3 };
 
     Configuration hc = initConfig();
-    Region region = initHRegion(tableName, name.getMethodName(), hc,
-      new Class<?>[]{}, families);
+    Region region = initHRegion(tableName, name.getMethodName(), hc, new Class<?>[]{}, families);
 
     for (int i = 0; i < 3; i++) {
       HBaseTestCase.addContent(region, fam3);
@@ -284,18 +296,16 @@ public class TestCoprocessorInterface {
 
     region = reopenRegion(region, CoprocessorImpl.class, CoprocessorII.class);
 
-    Coprocessor c = region.getCoprocessorHost().
-        findCoprocessor(CoprocessorImpl.class.getName());
-    Coprocessor c2 = region.getCoprocessorHost().
-        findCoprocessor(CoprocessorII.class.getName());
+    Coprocessor c = region.getCoprocessorHost().findCoprocessor(CoprocessorImpl.class);
+    Coprocessor c2 = region.getCoprocessorHost().findCoprocessor(CoprocessorII.class);
     Object o = ((CoprocessorImpl)c).getSharedData().get("test1");
     Object o2 = ((CoprocessorII)c2).getSharedData().get("test2");
     assertNotNull(o);
     assertNotNull(o2);
     // to coprocessors get different sharedDatas
     assertFalse(((CoprocessorImpl)c).getSharedData() == ((CoprocessorII)c2).getSharedData());
-    c = region.getCoprocessorHost().findCoprocessor(CoprocessorImpl.class.getName());
-    c2 = region.getCoprocessorHost().findCoprocessor(CoprocessorII.class.getName());
+    c = region.getCoprocessorHost().findCoprocessor(CoprocessorImpl.class);
+    c2 = region.getCoprocessorHost().findCoprocessor(CoprocessorII.class);
     // make sure that all coprocessor of a class have identical sharedDatas
     assertTrue(((CoprocessorImpl)c).getSharedData().get("test1") == o);
     assertTrue(((CoprocessorII)c2).getSharedData().get("test2") == o2);
@@ -312,21 +322,18 @@ public class TestCoprocessorInterface {
       fail();
     } catch (org.apache.hadoop.hbase.DoNotRetryIOException xc) {
     }
-    assertNull(region.getCoprocessorHost().findCoprocessor(CoprocessorII.class.getName()));
-    c = region.getCoprocessorHost().
-        findCoprocessor(CoprocessorImpl.class.getName());
+    assertNull(region.getCoprocessorHost().findCoprocessor(CoprocessorII.class));
+    c = region.getCoprocessorHost().findCoprocessor(CoprocessorImpl.class);
     assertTrue(((CoprocessorImpl)c).getSharedData().get("test1") == o);
     c = c2 = null;
     // perform a GC
     System.gc();
     // reopen the region
     region = reopenRegion(region, CoprocessorImpl.class, CoprocessorII.class);
-    c = region.getCoprocessorHost().
-        findCoprocessor(CoprocessorImpl.class.getName());
+    c = region.getCoprocessorHost().findCoprocessor(CoprocessorImpl.class);
     // CPimpl is unaffected, still the same reference
     assertTrue(((CoprocessorImpl)c).getSharedData().get("test1") == o);
-    c2 = region.getCoprocessorHost().
-        findCoprocessor(CoprocessorII.class.getName());
+    c2 = region.getCoprocessorHost().findCoprocessor(CoprocessorII.class);
     // new map and object created, hence the reference is different
     // hence the old entry was indeed removed by the GC and new one has been created
     Object o3 = ((CoprocessorII)c2).getSharedData().get("test2");
@@ -357,8 +364,7 @@ public class TestCoprocessorInterface {
     scanner.next(new ArrayList<>());
 
     HBaseTestingUtility.closeRegionAndWAL(region);
-    Coprocessor c = region.getCoprocessorHost().
-      findCoprocessor(CoprocessorImpl.class.getName());
+    Coprocessor c = region.getCoprocessorHost().findCoprocessor(CoprocessorImpl.class);
 
     assertTrue("Coprocessor not started", ((CoprocessorImpl)c).wasStarted());
     assertTrue("Coprocessor not stopped", ((CoprocessorImpl)c).wasStopped());
@@ -382,7 +388,7 @@ public class TestCoprocessorInterface {
     ((HRegion)r).setCoprocessorHost(host);
 
     for (Class<?> implClass : implClasses) {
-      host.load(implClass, Coprocessor.PRIORITY_USER, conf);
+      host.load((Class<? extends RegionCoprocessor>) implClass, Coprocessor.PRIORITY_USER, conf);
     }
     // we need to manually call pre- and postOpen here since the
     // above load() is not the real case for CP loading. A CP is
@@ -412,7 +418,7 @@ public class TestCoprocessorInterface {
     ((HRegion)r).setCoprocessorHost(host);
 
     for (Class<?> implClass : implClasses) {
-      host.load(implClass, Coprocessor.PRIORITY_USER, conf);
+      host.load((Class<? extends RegionCoprocessor>) implClass, Coprocessor.PRIORITY_USER, conf);
       Coprocessor c = host.findCoprocessor(implClass.getName());
       assertNotNull(c);
     }

http://git-wip-us.apache.org/repos/asf/hbase/blob/0c883a23/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorMetrics.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorMetrics.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorMetrics.java
index b4e10d9..fbcd1d5 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorMetrics.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorMetrics.java
@@ -95,7 +95,7 @@ public class TestCoprocessorMetrics {
   /**
    * MasterObserver that has a Timer metric for create table operation.
    */
-  public static class CustomMasterObserver implements MasterObserver {
+  public static class CustomMasterObserver implements MasterCoprocessor, MasterObserver {
     private Timer createTableTimer;
     private long start = Long.MIN_VALUE;
 
@@ -125,14 +125,25 @@ public class TestCoprocessorMetrics {
         createTableTimer  = registry.timer("CreateTable");
       }
     }
+
+    @Override
+    public Optional<MasterObserver> getMasterObserver() {
+      return Optional.of(this);
+    }
   }
 
   /**
    * RegionServerObserver that has a Counter for rollWAL requests.
    */
-  public static class CustomRegionServerObserver implements RegionServerObserver {
+  public static class CustomRegionServerObserver implements RegionServerCoprocessor,
+      RegionServerObserver {
     /** This is the Counter metric object to keep track of the current count across invocations */
     private Counter rollWALCounter;
+
+    @Override public Optional<RegionServerObserver> getRegionServerObserver() {
+      return Optional.of(this);
+    }
+
     @Override
     public void postRollWALWriterRequest(ObserverContext<RegionServerCoprocessorEnvironment> ctx)
         throws IOException {
@@ -156,7 +167,7 @@ public class TestCoprocessorMetrics {
   /**
    * WALObserver that has a Counter for walEdits written.
    */
-  public static class CustomWALObserver implements WALObserver {
+  public static class CustomWALObserver implements WALCoprocessor, WALObserver {
     private Counter walEditsCount;
 
     @Override
@@ -177,12 +188,16 @@ public class TestCoprocessorMetrics {
         }
       }
     }
+
+    @Override public Optional<WALObserver> getWALObserver() {
+      return Optional.of(this);
+    }
   }
 
   /**
    * RegionObserver that has a Counter for preGet()
    */
-  public static class CustomRegionObserver implements RegionObserver {
+  public static class CustomRegionObserver implements RegionCoprocessor, RegionObserver {
     private Counter preGetCounter;
 
     @Override
@@ -192,6 +207,11 @@ public class TestCoprocessorMetrics {
     }
 
     @Override
+    public Optional<RegionObserver> getRegionObserver() {
+      return Optional.of(this);
+    }
+
+    @Override
     public void start(CoprocessorEnvironment env) throws IOException {
       if (env instanceof RegionCoprocessorEnvironment) {
         MetricRegistry registry =

http://git-wip-us.apache.org/repos/asf/hbase/blob/0c883a23/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorStop.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorStop.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorStop.java
index 2ef13f7..1d8acdf 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorStop.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorStop.java
@@ -49,7 +49,7 @@ public class TestCoprocessorStop {
   private static final String REGIONSERVER_FILE =
                               "regionserver" + System.currentTimeMillis();
 
-  public static class FooCoprocessor implements Coprocessor {
+  public static class FooCoprocessor implements MasterCoprocessor, RegionServerCoprocessor {
     @Override
     public void start(CoprocessorEnvironment env) throws IOException {
       String where = null;

http://git-wip-us.apache.org/repos/asf/hbase/blob/0c883a23/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestHTableWrapper.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestHTableWrapper.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestHTableWrapper.java
index 326b3c0..b3fdb3e 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestHTableWrapper.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestHTableWrapper.java
@@ -29,6 +29,7 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Optional;
 
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.Coprocessor;
@@ -87,7 +88,11 @@ public class TestHTableWrapper {
   private static final byte[] bytes4 = Bytes.toBytes(4);
   private static final byte[] bytes5 = Bytes.toBytes(5);
 
-  static class DummyRegionObserver implements RegionObserver {
+  public static class DummyRegionObserver implements MasterCoprocessor, MasterObserver {
+    @Override
+    public Optional<MasterObserver> getMasterObserver() {
+      return Optional.of(this);
+    }
   }
 
   private Table hTableInterface;
@@ -135,14 +140,14 @@ public class TestHTableWrapper {
   public void testHTableInterfaceMethods() throws Exception {
     Configuration conf = util.getConfiguration();
     MasterCoprocessorHost cpHost = util.getMiniHBaseCluster().getMaster().getMasterCoprocessorHost();
-    Class<?> implClazz = DummyRegionObserver.class;
+    Class<? extends MasterCoprocessor> implClazz = DummyRegionObserver.class;
     cpHost.load(implClazz, Coprocessor.PRIORITY_HIGHEST, conf);
     CoprocessorEnvironment env = cpHost.findCoprocessorEnvironment(implClazz.getName());
     assertEquals(Coprocessor.VERSION, env.getVersion());
     assertEquals(VersionInfo.getVersion(), env.getHBaseVersion());
     hTableInterface = env.getTable(TEST_TABLE);
     checkHTableInterfaceMethods();
-    cpHost.shutdown(env);
+    cpHost.shutdown((MasterCoprocessorEnvironment) env);
   }
 
   private void checkHTableInterfaceMethods() throws Exception {

http://git-wip-us.apache.org/repos/asf/hbase/blob/0c883a23/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestMasterCoprocessorExceptionWithAbort.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestMasterCoprocessorExceptionWithAbort.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestMasterCoprocessorExceptionWithAbort.java
index ab3dec7..0595a67 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestMasterCoprocessorExceptionWithAbort.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestMasterCoprocessorExceptionWithAbort.java
@@ -20,6 +20,7 @@
 package org.apache.hadoop.hbase.coprocessor;
 
 import java.io.IOException;
+import java.util.Optional;
 
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.Abortable;
@@ -97,13 +98,18 @@ public class TestMasterCoprocessorExceptionWithAbort {
    }
   }
 
-  public static class BuggyMasterObserver implements MasterObserver {
+  public static class BuggyMasterObserver implements MasterCoprocessor, MasterObserver {
     private boolean preCreateTableCalled;
     private boolean postCreateTableCalled;
     private boolean startCalled;
     private boolean postStartMasterCalled;
 
     @Override
+    public Optional<MasterObserver> getMasterObserver() {
+      return Optional.of(this);
+    }
+
+    @Override
     public void postCreateTable(ObserverContext<MasterCoprocessorEnvironment> env,
         TableDescriptor desc, RegionInfo[] regions) throws IOException {
       // cause a NullPointerException and don't catch it: this will cause the
@@ -163,8 +169,7 @@ public class TestMasterCoprocessorExceptionWithAbort {
 
     HMaster master = cluster.getMaster();
     MasterCoprocessorHost host = master.getMasterCoprocessorHost();
-    BuggyMasterObserver cp = (BuggyMasterObserver)host.findCoprocessor(
-        BuggyMasterObserver.class.getName());
+    BuggyMasterObserver cp = host.findCoprocessor(BuggyMasterObserver.class);
     assertFalse("No table created yet", cp.wasCreateTableCalled());
 
     // set a watch on the zookeeper /hbase/master node. If the master dies,

http://git-wip-us.apache.org/repos/asf/hbase/blob/0c883a23/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestMasterCoprocessorExceptionWithRemove.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestMasterCoprocessorExceptionWithRemove.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestMasterCoprocessorExceptionWithRemove.java
index ccd777f..d4c6e4f 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestMasterCoprocessorExceptionWithRemove.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestMasterCoprocessorExceptionWithRemove.java
@@ -20,6 +20,7 @@
 package org.apache.hadoop.hbase.coprocessor;
 
 import java.io.IOException;
+import java.util.Optional;
 
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.Abortable;
@@ -73,12 +74,17 @@ public class TestMasterCoprocessorExceptionWithRemove {
     }
   }
 
-  public static class BuggyMasterObserver implements MasterObserver {
+  public static class BuggyMasterObserver implements MasterCoprocessor, MasterObserver {
     private boolean preCreateTableCalled;
     private boolean postCreateTableCalled;
     private boolean startCalled;
     private boolean postStartMasterCalled;
 
+    @Override
+    public Optional<MasterObserver> getMasterObserver() {
+      return Optional.of(this);
+    }
+
     @SuppressWarnings("null")
     @Override
     public void postCreateTable(ObserverContext<MasterCoprocessorEnvironment> env,
@@ -144,8 +150,7 @@ public class TestMasterCoprocessorExceptionWithRemove {
 
     HMaster master = cluster.getMaster();
     MasterCoprocessorHost host = master.getMasterCoprocessorHost();
-    BuggyMasterObserver cp = (BuggyMasterObserver)host.findCoprocessor(
-        BuggyMasterObserver.class.getName());
+    BuggyMasterObserver cp = host.findCoprocessor(BuggyMasterObserver.class);
     assertFalse("No table created yet", cp.wasCreateTableCalled());
 
     // Set a watch on the zookeeper /hbase/master node. If the master dies,

http://git-wip-us.apache.org/repos/asf/hbase/blob/0c883a23/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestMasterObserver.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestMasterObserver.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestMasterObserver.java
index 1e36b0b..b038d9d 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestMasterObserver.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestMasterObserver.java
@@ -23,6 +23,7 @@ import java.io.IOException;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
+import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.CountDownLatch;
 
@@ -95,7 +96,7 @@ public class TestMasterObserver {
   public static CountDownLatch tableCreationLatch = new CountDownLatch(1);
   public static CountDownLatch tableDeletionLatch = new CountDownLatch(1);
 
-  public static class CPMasterObserver implements MasterObserver {
+  public static class CPMasterObserver implements MasterCoprocessor, MasterObserver {
 
     private boolean bypass = false;
     private boolean preCreateTableCalled;
@@ -283,6 +284,11 @@ public class TestMasterObserver {
     }
 
     @Override
+    public Optional<MasterObserver> getMasterObserver() {
+      return Optional.of(this);
+    }
+
+    @Override
     public void preMergeRegions(
         final ObserverContext<MasterCoprocessorEnvironment> ctx,
         final RegionInfo[] regionsToMerge) throws IOException {
@@ -1503,8 +1509,7 @@ public class TestMasterObserver {
     assertTrue("Master should be active", master.isActiveMaster());
     MasterCoprocessorHost host = master.getMasterCoprocessorHost();
     assertNotNull("CoprocessorHost should not be null", host);
-    CPMasterObserver cp = (CPMasterObserver)host.findCoprocessor(
-        CPMasterObserver.class.getName());
+    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
     assertNotNull("CPMasterObserver coprocessor not found or not installed!", cp);
 
     // check basic lifecycle
@@ -1521,8 +1526,7 @@ public class TestMasterObserver {
     final TableName tableName = TableName.valueOf(name.getMethodName());
     HMaster master = cluster.getMaster();
     MasterCoprocessorHost host = master.getMasterCoprocessorHost();
-    CPMasterObserver cp = (CPMasterObserver)host.findCoprocessor(
-        CPMasterObserver.class.getName());
+    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
     cp.enableBypass(true);
     cp.resetStates();
     assertFalse("No table created yet", cp.wasCreateTableCalled());
@@ -1698,8 +1702,7 @@ public class TestMasterObserver {
     MiniHBaseCluster cluster = UTIL.getHBaseCluster();
     HMaster master = cluster.getMaster();
     MasterCoprocessorHost host = master.getMasterCoprocessorHost();
-    CPMasterObserver cp = (CPMasterObserver)host.findCoprocessor(
-        CPMasterObserver.class.getName());
+    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
     cp.resetStates();
 
     // create a table
@@ -1760,8 +1763,7 @@ public class TestMasterObserver {
     String testNamespace = "observed_ns";
     HMaster master = cluster.getMaster();
     MasterCoprocessorHost host = master.getMasterCoprocessorHost();
-    CPMasterObserver cp = (CPMasterObserver)host.findCoprocessor(
-        CPMasterObserver.class.getName());
+    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
 
     cp.enableBypass(false);
     cp.resetStates();
@@ -1866,8 +1868,7 @@ public class TestMasterObserver {
 
     HMaster master = cluster.getMaster();
     MasterCoprocessorHost host = master.getMasterCoprocessorHost();
-    CPMasterObserver cp = (CPMasterObserver)host.findCoprocessor(
-        CPMasterObserver.class.getName());
+    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
     cp.enableBypass(false);
     cp.resetStates();
 
@@ -1955,8 +1956,7 @@ public class TestMasterObserver {
 
     HMaster master = cluster.getMaster();
     MasterCoprocessorHost host = master.getMasterCoprocessorHost();
-    CPMasterObserver cp = (CPMasterObserver)host.findCoprocessor(
-        CPMasterObserver.class.getName());
+    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
     cp.resetStates();
 
     GetTableDescriptorsRequest req =
@@ -1973,8 +1973,7 @@ public class TestMasterObserver {
 
     HMaster master = cluster.getMaster();
     MasterCoprocessorHost host = master.getMasterCoprocessorHost();
-    CPMasterObserver cp = (CPMasterObserver)host.findCoprocessor(
-        CPMasterObserver.class.getName());
+    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
     cp.resetStates();
 
     master.getMasterRpcServices().getTableNames(null,
@@ -1989,8 +1988,7 @@ public class TestMasterObserver {
 
     HMaster master = cluster.getMaster();
     MasterCoprocessorHost host = master.getMasterCoprocessorHost();
-    CPMasterObserver cp = (CPMasterObserver)host.findCoprocessor(
-        CPMasterObserver.class.getName());
+    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
     cp.resetStates();
 
     master.abortProcedure(1, true);
@@ -2005,8 +2003,7 @@ public class TestMasterObserver {
 
     HMaster master = cluster.getMaster();
     MasterCoprocessorHost host = master.getMasterCoprocessorHost();
-    CPMasterObserver cp = (CPMasterObserver)host.findCoprocessor(
-        CPMasterObserver.class.getName());
+    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
     cp.resetStates();
 
     master.getProcedures();
@@ -2021,8 +2018,7 @@ public class TestMasterObserver {
 
     HMaster master = cluster.getMaster();
     MasterCoprocessorHost host = master.getMasterCoprocessorHost();
-    CPMasterObserver cp = (CPMasterObserver)host.findCoprocessor(
-        CPMasterObserver.class.getName());
+    CPMasterObserver cp = host.findCoprocessor(CPMasterObserver.class);
     cp.resetStates();
 
     master.getLocks();
@@ -2043,8 +2039,7 @@ public class TestMasterObserver {
   @Test
   public void testQueueLockAndLockHeartbeatOperations() throws Exception {
     HMaster master = UTIL.getMiniHBaseCluster().getMaster();
-    CPMasterObserver cp = (CPMasterObserver)master.getMasterCoprocessorHost().findCoprocessor(
-        CPMasterObserver.class.getName());
+    CPMasterObserver cp = master.getMasterCoprocessorHost().findCoprocessor(CPMasterObserver.class);
     cp.resetStates();
 
     final TableName tableName = TableName.valueOf("testLockedTable");

http://git-wip-us.apache.org/repos/asf/hbase/blob/0c883a23/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestOpenTableInCoprocessor.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestOpenTableInCoprocessor.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestOpenTableInCoprocessor.java
index 5cd1fca..dabf20b 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestOpenTableInCoprocessor.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestOpenTableInCoprocessor.java
@@ -41,6 +41,7 @@ import org.junit.experimental.categories.Category;
 
 import java.io.IOException;
 import java.util.Collections;
+import java.util.Optional;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.SynchronousQueue;
 import java.util.concurrent.ThreadPoolExecutor;
@@ -63,7 +64,12 @@ public class TestOpenTableInCoprocessor {
   /**
    * Custom coprocessor that just copies the write to another table.
    */
-  public static class SendToOtherTableCoprocessor implements RegionObserver {
+  public static class SendToOtherTableCoprocessor implements RegionCoprocessor, RegionObserver {
+
+    @Override
+    public Optional<RegionObserver> getRegionObserver() {
+      return Optional.of(this);
+    }
 
     @Override
     public void prePut(final ObserverContext<RegionCoprocessorEnvironment> e, final Put put,
@@ -80,7 +86,7 @@ public class TestOpenTableInCoprocessor {
   /**
    * Coprocessor that creates an HTable with a pool to write to another table
    */
-  public static class CustomThreadPoolCoprocessor implements RegionObserver {
+  public static class CustomThreadPoolCoprocessor implements RegionCoprocessor, RegionObserver {
 
     /**
      * Get a pool that has only ever one thread. A second action added to the pool (running
@@ -98,6 +104,11 @@ public class TestOpenTableInCoprocessor {
     }
 
     @Override
+    public Optional<RegionObserver> getRegionObserver() {
+      return Optional.of(this);
+    }
+
+    @Override
     public void prePut(final ObserverContext<RegionCoprocessorEnvironment> e, final Put put,
         final WALEdit edit, final Durability durability) throws IOException {
       Table table = e.getEnvironment().getTable(otherTable, getPool());

http://git-wip-us.apache.org/repos/asf/hbase/blob/0c883a23/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverBypass.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverBypass.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverBypass.java
index 8d55430..050ea36 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverBypass.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverBypass.java
@@ -24,6 +24,7 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.Cell;
@@ -204,7 +205,12 @@ public class TestRegionObserverBypass {
     t.delete(d);
   }
 
-  public static class TestCoprocessor implements RegionObserver {
+  public static class TestCoprocessor implements RegionCoprocessor, RegionObserver {
+    @Override
+    public Optional<RegionObserver> getRegionObserver() {
+      return Optional.of(this);
+    }
+
     @Override
     public void prePut(final ObserverContext<RegionCoprocessorEnvironment> e,
         final Put put, final WALEdit edit, final Durability durability)

http://git-wip-us.apache.org/repos/asf/hbase/blob/0c883a23/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverForAddingMutationsFromCoprocessors.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverForAddingMutationsFromCoprocessors.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverForAddingMutationsFromCoprocessors.java
index b168be7..8897957 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverForAddingMutationsFromCoprocessors.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverForAddingMutationsFromCoprocessors.java
@@ -21,6 +21,7 @@ package org.apache.hadoop.hbase.coprocessor;
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Optional;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -194,7 +195,12 @@ public class TestRegionObserverForAddingMutationsFromCoprocessors {
     }
   }
 
-  public static class TestMultiMutationCoprocessor implements RegionObserver {
+  public static class TestMultiMutationCoprocessor implements RegionCoprocessor, RegionObserver {
+    @Override
+    public Optional<RegionObserver> getRegionObserver() {
+      return Optional.of(this);
+    }
+
     @Override
     public void preBatchMutate(ObserverContext<RegionCoprocessorEnvironment> c,
         MiniBatchOperationInProgress<Mutation> miniBatchOp) throws IOException {
@@ -211,7 +217,12 @@ public class TestRegionObserverForAddingMutationsFromCoprocessors {
     }
   }
 
-  public static class TestDeleteCellCoprocessor implements RegionObserver {
+  public static class TestDeleteCellCoprocessor implements RegionCoprocessor, RegionObserver {
+    @Override
+    public Optional<RegionObserver> getRegionObserver() {
+      return Optional.of(this);
+    }
+
     @Override
     public void preBatchMutate(ObserverContext<RegionCoprocessorEnvironment> c,
         MiniBatchOperationInProgress<Mutation> miniBatchOp) throws IOException {
@@ -230,7 +241,12 @@ public class TestRegionObserverForAddingMutationsFromCoprocessors {
     }
   }
 
-  public static class TestDeleteFamilyCoprocessor implements RegionObserver {
+  public static class TestDeleteFamilyCoprocessor implements RegionCoprocessor, RegionObserver {
+    @Override
+    public Optional<RegionObserver> getRegionObserver() {
+      return Optional.of(this);
+    }
+
     @Override
     public void preBatchMutate(ObserverContext<RegionCoprocessorEnvironment> c,
         MiniBatchOperationInProgress<Mutation> miniBatchOp) throws IOException {
@@ -249,7 +265,12 @@ public class TestRegionObserverForAddingMutationsFromCoprocessors {
     }
   }
 
-  public static class TestDeleteRowCoprocessor implements RegionObserver {
+  public static class TestDeleteRowCoprocessor implements RegionCoprocessor, RegionObserver {
+    @Override
+    public Optional<RegionObserver> getRegionObserver() {
+      return Optional.of(this);
+    }
+
     @Override
     public void preBatchMutate(ObserverContext<RegionCoprocessorEnvironment> c,
         MiniBatchOperationInProgress<Mutation> miniBatchOp) throws IOException {
@@ -268,8 +289,14 @@ public class TestRegionObserverForAddingMutationsFromCoprocessors {
     }
   }
 
-  public static class TestWALObserver implements WALObserver {
+  public static class TestWALObserver implements WALCoprocessor, WALObserver {
     static WALEdit savedEdit = null;
+
+    @Override
+    public Optional<WALObserver> getWALObserver() {
+      return Optional.of(this);
+    }
+
     @Override
     public void postWALWrite(ObserverContext<? extends WALCoprocessorEnvironment> ctx,
                              RegionInfo info, WALKey logKey, WALEdit logEdit) throws IOException {

http://git-wip-us.apache.org/repos/asf/hbase/blob/0c883a23/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverInterface.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverInterface.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverInterface.java
index 0641b56..2666340 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverInterface.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverInterface.java
@@ -28,6 +28,7 @@ import java.io.IOException;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -411,11 +412,16 @@ public class TestRegionObserverInterface {
   }
 
   /* Overrides compaction to only output rows with keys that are even numbers */
-  public static class EvenOnlyCompactor implements RegionObserver {
+  public static class EvenOnlyCompactor implements RegionCoprocessor, RegionObserver {
     long lastCompaction;
     long lastFlush;
 
     @Override
+    public Optional<RegionObserver> getRegionObserver() {
+      return Optional.of(this);
+    }
+
+    @Override
     public InternalScanner preCompact(ObserverContext<RegionCoprocessorEnvironment> e, Store store,
         InternalScanner scanner, ScanType scanType, CompactionLifeCycleTracker tracker) {
       return new InternalScanner() {
@@ -494,8 +500,7 @@ public class TestRegionObserverInterface {
     }
 
     HRegion firstRegion = cluster.getRegions(compactTable).get(0);
-    Coprocessor cp =
-        firstRegion.getCoprocessorHost().findCoprocessor(EvenOnlyCompactor.class.getName());
+    Coprocessor cp = firstRegion.getCoprocessorHost().findCoprocessor(EvenOnlyCompactor.class);
     assertNotNull("EvenOnlyCompactor coprocessor should be loaded", cp);
     EvenOnlyCompactor compactor = (EvenOnlyCompactor) cp;
 
@@ -656,7 +661,7 @@ public class TestRegionObserverInterface {
   }
 
   // check each region whether the coprocessor upcalls are called or not.
-  private void verifyMethodResult(Class<?> c, String methodName[], TableName tableName,
+  private void verifyMethodResult(Class<?> coprocessor, String methodName[], TableName tableName,
       Object value[]) throws IOException {
     try {
       for (JVMClusterUtil.RegionServerThread t : cluster.getRegionServerThreads()) {
@@ -671,14 +676,14 @@ public class TestRegionObserverInterface {
           RegionCoprocessorHost cph =
               t.getRegionServer().getOnlineRegion(r.getRegionName()).getCoprocessorHost();
 
-          Coprocessor cp = cph.findCoprocessor(c.getName());
+          Coprocessor cp = cph.findCoprocessor(coprocessor.getName());
           assertNotNull(cp);
           for (int i = 0; i < methodName.length; ++i) {
-            Method m = c.getMethod(methodName[i]);
+            Method m = coprocessor.getMethod(methodName[i]);
             Object o = m.invoke(cp);
-            assertTrue("Result of " + c.getName() + "." + methodName[i] + " is expected to be "
-                + value[i].toString() + ", while we get " + o.toString(),
-              o.equals(value[i]));
+            assertTrue("Result of " + coprocessor.getName() + "." + methodName[i]
+                    + " is expected to be " + value[i].toString() + ", while we get "
+                    + o.toString(), o.equals(value[i]));
           }
         }
       }

http://git-wip-us.apache.org/repos/asf/hbase/blob/0c883a23/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverScannerOpenHook.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverScannerOpenHook.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverScannerOpenHook.java
index 7b24c1f..4c8c4ce 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverScannerOpenHook.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverScannerOpenHook.java
@@ -25,6 +25,7 @@ import static org.junit.Assert.assertNull;
 import java.io.IOException;
 import java.util.List;
 import java.util.NavigableSet;
+import java.util.Optional;
 import java.util.concurrent.CountDownLatch;
 
 import org.apache.hadoop.conf.Configuration;
@@ -103,13 +104,22 @@ public class TestRegionObserverScannerOpenHook {
   /**
    * Do the default logic in {@link RegionObserver} interface.
    */
-  public static class EmptyRegionObsever implements RegionObserver {
+  public static class EmptyRegionObsever implements RegionCoprocessor, RegionObserver {
+    @Override
+    public Optional<RegionObserver> getRegionObserver() {
+      return Optional.of(this);
+    }
   }
 
   /**
    * Don't return any data from a scan by creating a custom {@link StoreScanner}.
    */
-  public static class NoDataFromScan implements RegionObserver {
+  public static class NoDataFromScan implements RegionCoprocessor, RegionObserver {
+    @Override
+    public Optional<RegionObserver> getRegionObserver() {
+      return Optional.of(this);
+    }
+
     @Override
     public KeyValueScanner preStoreScannerOpen(ObserverContext<RegionCoprocessorEnvironment> c,
         Store store, Scan scan, NavigableSet<byte[]> targetCols, KeyValueScanner s, long readPt)
@@ -137,7 +147,11 @@ public class TestRegionObserverScannerOpenHook {
   /**
    * Don't allow any data in a flush by creating a custom {@link StoreScanner}.
    */
-  public static class NoDataFromFlush implements RegionObserver {
+  public static class NoDataFromFlush implements RegionCoprocessor, RegionObserver {
+    @Override
+    public Optional<RegionObserver> getRegionObserver() {
+      return Optional.of(this);
+    }
 
     @Override
     public InternalScanner preFlushScannerOpen(ObserverContext<RegionCoprocessorEnvironment> c,
@@ -152,7 +166,12 @@ public class TestRegionObserverScannerOpenHook {
    * Don't allow any data to be written out in the compaction by creating a custom
    * {@link StoreScanner}.
    */
-  public static class NoDataFromCompaction implements RegionObserver {
+  public static class NoDataFromCompaction implements RegionCoprocessor, RegionObserver {
+    @Override
+    public Optional<RegionObserver> getRegionObserver() {
+      return Optional.of(this);
+    }
+
     @Override
     public InternalScanner preCompactScannerOpen(ObserverContext<RegionCoprocessorEnvironment> c,
         Store store, List<? extends KeyValueScanner> scanners, ScanType scanType,

http://git-wip-us.apache.org/repos/asf/hbase/blob/0c883a23/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverStacking.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverStacking.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverStacking.java
index 702155b..1277ccc 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverStacking.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverStacking.java
@@ -20,6 +20,7 @@
 package org.apache.hadoop.hbase.coprocessor;
 
 import java.io.IOException;
+import java.util.Optional;
 
 import junit.framework.TestCase;
 
@@ -50,8 +51,14 @@ public class TestRegionObserverStacking extends TestCase {
     = new HBaseTestingUtility();
   static final Path DIR = TEST_UTIL.getDataTestDir();
 
-  public static class ObserverA implements RegionObserver {
+  public static class ObserverA implements RegionCoprocessor, RegionObserver {
     long id;
+
+    @Override
+    public Optional<RegionObserver> getRegionObserver() {
+      return Optional.of(this);
+    }
+
     @Override
     public void postPut(final ObserverContext<RegionCoprocessorEnvironment> c,
         final Put put, final WALEdit edit,
@@ -65,8 +72,14 @@ public class TestRegionObserverStacking extends TestCase {
     }
   }
 
-  public static class ObserverB implements RegionObserver {
+  public static class ObserverB implements RegionCoprocessor, RegionObserver {
     long id;
+
+    @Override
+    public Optional<RegionObserver> getRegionObserver() {
+      return Optional.of(this);
+    }
+
     @Override
     public void postPut(final ObserverContext<RegionCoprocessorEnvironment> c,
         final Put put, final WALEdit edit,
@@ -80,10 +93,15 @@ public class TestRegionObserverStacking extends TestCase {
     }
   }
 
-  public static class ObserverC implements RegionObserver {
+  public static class ObserverC implements RegionCoprocessor, RegionObserver {
     long id;
 
     @Override
+    public Optional<RegionObserver> getRegionObserver() {
+      return Optional.of(this);
+    }
+
+    @Override
     public void postPut(final ObserverContext<RegionCoprocessorEnvironment> c,
         final Put put, final WALEdit edit,
         final Durability durability)

http://git-wip-us.apache.org/repos/asf/hbase/blob/0c883a23/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionServerCoprocessorExceptionWithAbort.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionServerCoprocessorExceptionWithAbort.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionServerCoprocessorExceptionWithAbort.java
index ae46003..b4644cb 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionServerCoprocessorExceptionWithAbort.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionServerCoprocessorExceptionWithAbort.java
@@ -119,7 +119,7 @@ public class TestRegionServerCoprocessorExceptionWithAbort {
       // it will abort.
       boolean aborted = false;
       for (int i = 0; i < 10; i++) {
-        aborted = regionServer.isAborted(); 
+        aborted = regionServer.isAborted();
         if (aborted) {
           break;
         }
@@ -137,7 +137,7 @@ public class TestRegionServerCoprocessorExceptionWithAbort {
     }
   }
 
-  public static class FailedInitializationObserver extends SimpleRegionObserver {
+  public static class FailedInitializationObserver implements RegionServerCoprocessor {
     @SuppressWarnings("null")
     @Override
     public void start(CoprocessorEnvironment e) throws IOException {

http://git-wip-us.apache.org/repos/asf/hbase/blob/0c883a23/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestWALObserver.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestWALObserver.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestWALObserver.java
index d701413..9e140f0 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestWALObserver.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestWALObserver.java
@@ -109,9 +109,9 @@ public class TestWALObserver {
   public static void setupBeforeClass() throws Exception {
     Configuration conf = TEST_UTIL.getConfiguration();
     conf.setStrings(CoprocessorHost.WAL_COPROCESSOR_CONF_KEY,
-        SampleRegionWALObserver.class.getName());
+        SampleRegionWALCoprocessor.class.getName());
     conf.set(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY,
-        SampleRegionWALObserver.class.getName());
+        SampleRegionWALCoprocessor.class.getName());
     conf.setInt("dfs.client.block.recovery.retries", 2);
 
     TEST_UTIL.startMiniCluster(1);
@@ -173,10 +173,10 @@ public class TestWALObserver {
   @Test
   public void testWALObserverWriteToWAL() throws Exception {
     final WAL log = wals.getWAL(UNSPECIFIED_REGION, null);
-    verifyWritesSeen(log, getCoprocessor(log, SampleRegionWALObserver.class), false);
+    verifyWritesSeen(log, getCoprocessor(log, SampleRegionWALCoprocessor.class), false);
   }
 
-  private void verifyWritesSeen(final WAL log, final SampleRegionWALObserver cp,
+  private void verifyWritesSeen(final WAL log, final SampleRegionWALCoprocessor cp,
       final boolean seesLegacy) throws Exception {
     HRegionInfo hri = createBasic3FamilyHRegionInfo(Bytes.toString(TEST_TABLE));
     final HTableDescriptor htd = createBasic3FamilyHTD(Bytes
@@ -277,7 +277,7 @@ public class TestWALObserver {
     }
     WAL log = wals.getWAL(UNSPECIFIED_REGION, null);
     try {
-      SampleRegionWALObserver cp = getCoprocessor(log, SampleRegionWALObserver.class);
+      SampleRegionWALCoprocessor cp = getCoprocessor(log, SampleRegionWALCoprocessor.class);
 
       cp.setTestValues(TEST_TABLE, null, null, null, null, null, null, null);
 
@@ -354,9 +354,8 @@ public class TestWALObserver {
             hri, htd, wal2, TEST_UTIL.getHBaseCluster().getRegionServer(0), null);
         long seqid2 = region.getOpenSeqNum();
 
-        SampleRegionWALObserver cp2 =
-          (SampleRegionWALObserver)region.getCoprocessorHost().findCoprocessor(
-              SampleRegionWALObserver.class.getName());
+        SampleRegionWALCoprocessor cp2 =
+          region.getCoprocessorHost().findCoprocessor(SampleRegionWALCoprocessor.class);
         // TODO: asserting here is problematic.
         assertNotNull(cp2);
         assertTrue(cp2.isPreWALRestoreCalled());
@@ -376,13 +375,13 @@ public class TestWALObserver {
   @Test
   public void testWALObserverLoaded() throws Exception {
     WAL log = wals.getWAL(UNSPECIFIED_REGION, null);
-    assertNotNull(getCoprocessor(log, SampleRegionWALObserver.class));
+    assertNotNull(getCoprocessor(log, SampleRegionWALCoprocessor.class));
   }
 
   @Test
   public void testWALObserverRoll() throws Exception {
     final WAL wal = wals.getWAL(UNSPECIFIED_REGION, null);
-    final SampleRegionWALObserver cp = getCoprocessor(wal, SampleRegionWALObserver.class);
+    final SampleRegionWALCoprocessor cp = getCoprocessor(wal, SampleRegionWALCoprocessor.class);
     cp.setTestValues(TEST_TABLE, null, null, null, null, null, null, null);
 
     assertFalse(cp.isPreWALRollCalled());
@@ -393,11 +392,11 @@ public class TestWALObserver {
     assertTrue(cp.isPostWALRollCalled());
   }
 
-  private SampleRegionWALObserver getCoprocessor(WAL wal,
-      Class<? extends SampleRegionWALObserver> clazz) throws Exception {
+  private SampleRegionWALCoprocessor getCoprocessor(WAL wal,
+      Class<? extends SampleRegionWALCoprocessor> clazz) throws Exception {
     WALCoprocessorHost host = wal.getCoprocessorHost();
     Coprocessor c = host.findCoprocessor(clazz.getName());
-    return (SampleRegionWALObserver) c;
+    return (SampleRegionWALCoprocessor) c;
   }
 
   /*

http://git-wip-us.apache.org/repos/asf/hbase/blob/0c883a23/hbase-server/src/test/java/org/apache/hadoop/hbase/mob/compactions/TestMobCompactor.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/mob/compactions/TestMobCompactor.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/mob/compactions/TestMobCompactor.java
index 8f0c5d6..e0d9fa2 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/mob/compactions/TestMobCompactor.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/mob/compactions/TestMobCompactor.java
@@ -29,6 +29,7 @@ import java.util.Arrays;
 import java.util.Calendar;
 import java.util.Collections;
 import java.util.List;
+import java.util.Optional;
 import java.util.Random;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.RejectedExecutionException;
@@ -69,6 +70,7 @@ import org.apache.hadoop.hbase.client.ResultScanner;
 import org.apache.hadoop.hbase.client.Scan;
 import org.apache.hadoop.hbase.client.Table;
 import org.apache.hadoop.hbase.coprocessor.ObserverContext;
+import org.apache.hadoop.hbase.coprocessor.RegionCoprocessor;
 import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
 import org.apache.hadoop.hbase.coprocessor.RegionObserver;
 import org.apache.hadoop.hbase.io.HFileLink;
@@ -719,7 +721,12 @@ public class TestMobCompactor {
    * This copro overwrites the default compaction policy. It always chooses two latest hfiles and
    * compacts them into a new one.
    */
-  public static class CompactTwoLatestHfilesCopro implements RegionObserver {
+  public static class CompactTwoLatestHfilesCopro implements RegionCoprocessor, RegionObserver {
+
+    @Override
+    public Optional<RegionObserver> getRegionObserver() {
+      return Optional.of(this);
+    }
 
     @Override
     public void preCompactSelection(ObserverContext<RegionCoprocessorEnvironment> c, Store store,

http://git-wip-us.apache.org/repos/asf/hbase/blob/0c883a23/hbase-server/src/test/java/org/apache/hadoop/hbase/namespace/TestNamespaceAuditor.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/namespace/TestNamespaceAuditor.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/namespace/TestNamespaceAuditor.java
index c3627f7..47e3783 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/namespace/TestNamespaceAuditor.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/namespace/TestNamespaceAuditor.java
@@ -21,6 +21,7 @@ package org.apache.hadoop.hbase.namespace;
 import java.io.IOException;
 import java.util.Collections;
 import java.util.List;
+import java.util.Optional;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
@@ -52,11 +53,14 @@ import org.apache.hadoop.hbase.client.RegionLocator;
 import org.apache.hadoop.hbase.client.Table;
 import org.apache.hadoop.hbase.client.TableDescriptor;
 import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
+import org.apache.hadoop.hbase.coprocessor.MasterCoprocessor;
 import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
 import org.apache.hadoop.hbase.coprocessor.MasterObserver;
 import org.apache.hadoop.hbase.coprocessor.ObserverContext;
+import org.apache.hadoop.hbase.coprocessor.RegionCoprocessor;
 import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
 import org.apache.hadoop.hbase.coprocessor.RegionObserver;
+import org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessor;
 import org.apache.hadoop.hbase.coprocessor.RegionServerObserver;
 import org.apache.hadoop.hbase.master.HMaster;
 import org.apache.hadoop.hbase.master.MasterCoprocessorHost;
@@ -278,7 +282,8 @@ public class TestNamespaceAuditor {
     assertNull("Namespace state not found to be null.", stateInfo);
   }
 
-  public static class CPRegionServerObserver implements RegionServerObserver {
+  public static class CPRegionServerObserver
+      implements RegionServerCoprocessor, RegionServerObserver {
     private volatile boolean shouldFailMerge = false;
 
     public void failMerge(boolean fail) {
@@ -292,9 +297,14 @@ public class TestNamespaceAuditor {
         wait();
       }
     }
+
+    @Override
+    public Optional<RegionServerObserver> getRegionServerObserver() {
+      return Optional.of(this);
+    }
   }
 
-  public static class CPMasterObserver implements MasterObserver {
+  public static class CPMasterObserver implements MasterCoprocessor, MasterObserver {
     private volatile boolean shouldFailMerge = false;
 
     public void failMerge(boolean fail) {
@@ -302,6 +312,11 @@ public class TestNamespaceAuditor {
     }
 
     @Override
+    public Optional<MasterObserver> getMasterObserver() {
+      return Optional.of(this);
+    }
+
+    @Override
     public synchronized void preMergeRegionsAction(
         final ObserverContext<MasterCoprocessorEnvironment> ctx,
         final RegionInfo[] regionsToMerge) throws IOException {
@@ -353,7 +368,7 @@ public class TestNamespaceAuditor {
     // Fail region merge through Coprocessor hook
     MiniHBaseCluster cluster = UTIL.getHBaseCluster();
     MasterCoprocessorHost cpHost = cluster.getMaster().getMasterCoprocessorHost();
-    Coprocessor coprocessor = cpHost.findCoprocessor(CPMasterObserver.class.getName());
+    Coprocessor coprocessor = cpHost.findCoprocessor(CPMasterObserver.class);
     CPMasterObserver masterObserver = (CPMasterObserver) coprocessor;
     masterObserver.failMerge(true);
 
@@ -445,7 +460,7 @@ public class TestNamespaceAuditor {
     return Bytes.toBytes("" + key);
   }
 
-  public static class CustomObserver implements RegionObserver {
+  public static class CustomObserver implements RegionCoprocessor, RegionObserver {
     volatile CountDownLatch postCompact;
 
     @Override
@@ -458,6 +473,11 @@ public class TestNamespaceAuditor {
     public void start(CoprocessorEnvironment e) throws IOException {
       postCompact = new CountDownLatch(1);
     }
+
+    @Override
+    public Optional<RegionObserver> getRegionObserver() {
+      return Optional.of(this);
+    }
   }
 
   @Test
@@ -522,11 +542,16 @@ public class TestNamespaceAuditor {
         .getMasterQuotaManager().getNamespaceQuotaManager();
   }
 
-  public static class MasterSyncObserver implements MasterObserver {
+  public static class MasterSyncObserver implements MasterCoprocessor, MasterObserver {
     volatile CountDownLatch tableDeletionLatch;
     static boolean throwExceptionInPreCreateTableAction;
 
     @Override
+    public Optional<MasterObserver> getMasterObserver() {
+      return Optional.of(this);
+    }
+
+    @Override
     public void preDeleteTable(ObserverContext<MasterCoprocessorEnvironment> ctx,
         TableName tableName) throws IOException {
       tableDeletionLatch = new CountDownLatch(1);
@@ -551,8 +576,8 @@ public class TestNamespaceAuditor {
   private void deleteTable(final TableName tableName) throws Exception {
     // NOTE: We need a latch because admin is not sync,
     // so the postOp coprocessor method may be called after the admin operation returned.
-    MasterSyncObserver observer = (MasterSyncObserver)UTIL.getHBaseCluster().getMaster()
-      .getMasterCoprocessorHost().findCoprocessor(MasterSyncObserver.class.getName());
+    MasterSyncObserver observer = UTIL.getHBaseCluster().getMaster()
+      .getMasterCoprocessorHost().findCoprocessor(MasterSyncObserver.class);
     ADMIN.deleteTable(tableName);
     observer.tableDeletionLatch.await();
   }


Mime
View raw message