You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by ap...@apache.org on 2015/08/26 22:41:15 UTC
hbase git commit: HBASE-14232 Backwards compatiblity support for new
MasterObserver APIs (Francis Liu)
Repository: hbase
Updated Branches:
refs/heads/hbase-6721-0.98 66e16163f -> 8726a60a5
HBASE-14232 Backwards compatiblity support for new MasterObserver APIs (Francis Liu)
Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/8726a60a
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/8726a60a
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/8726a60a
Branch: refs/heads/hbase-6721-0.98
Commit: 8726a60a52728730e46c46f4a6b9992530de2216
Parents: 66e1616
Author: Andrew Purtell <ap...@apache.org>
Authored: Wed Aug 26 13:28:44 2015 -0700
Committer: Andrew Purtell <ap...@apache.org>
Committed: Wed Aug 26 13:41:06 2015 -0700
----------------------------------------------------------------------
.../hbase/coprocessor/CoprocessorHost.java | 74 ++++++++++++++++++++
.../hbase/master/MasterCoprocessorHost.java | 47 +++++++++----
2 files changed, 109 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hbase/blob/8726a60a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.java
----------------------------------------------------------------------
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 1c55738..16f6a86 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
@@ -30,6 +30,7 @@ import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.UUID;
+import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.atomic.AtomicInteger;
@@ -870,4 +871,77 @@ public abstract class CoprocessorHost<E extends CoprocessorEnvironment> {
"coprocessor set.", e);
}
}
+
+ /**
+ * Used to gracefully handle fallback to deprecated methods when we
+ * evolve coprocessor APIs.
+ *
+ * When a particular Coprocessor API is updated to change methods, hosts can support fallback
+ * to the deprecated API by using this method to determine if an instance implements the new API.
+ * In the event that said support is partial, then in the face of a runtime issue that prevents
+ * proper operation {@link #legacyWarning(Class, String)} should be used to let operators know.
+ *
+ * For examples of this in action, see the implementation of
+ * <ul>
+ * <li>{@link org.apache.hadoop.hbase.regionserver.RegionCoprocessorHost}
+ * <li>{@link org.apache.hadoop.hbase.regionserver.wal.WALCoprocessorHost}
+ * </ul>
+ *
+ * @param clazz Coprocessor you wish to evaluate
+ * @param methodName the name of the non-deprecated method version
+ * @param parameterTypes the Class of the non-deprecated method's arguments in the order they are
+ * declared.
+ */
+ @InterfaceAudience.Private
+ protected static boolean useLegacyMethod(final Class<? extends Coprocessor> clazz,
+ final String methodName, final Class<?>... parameterTypes) {
+ boolean useLegacy;
+ // Use reflection to see if they implement the non-deprecated version
+ try {
+ clazz.getDeclaredMethod(methodName, parameterTypes);
+ LOG.debug("Found an implementation of '" + methodName + "' that uses updated method " +
+ "signature. Skipping legacy support for invocations in '" + clazz +"'.");
+ useLegacy = false;
+ } catch (NoSuchMethodException exception) {
+ useLegacy = true;
+ } catch (SecurityException exception) {
+ LOG.warn("The Security Manager denied our attempt to detect if the coprocessor '" + clazz +
+ "' requires legacy support; assuming it does. If you get later errors about legacy " +
+ "coprocessor use, consider updating your security policy to allow access to the package" +
+ " and declared members of your implementation.");
+ LOG.debug("Details of Security Manager rejection.", exception);
+ useLegacy = true;
+ }
+ return useLegacy;
+ }
+
+ /**
+ * Used to limit legacy handling to once per Coprocessor class per classloader.
+ */
+ private static final Set<Class<? extends Coprocessor>> legacyWarning =
+ new ConcurrentSkipListSet<Class<? extends Coprocessor>>(
+ new Comparator<Class<? extends Coprocessor>>() {
+ @Override
+ public int compare(Class<? extends Coprocessor> c1, Class<? extends Coprocessor> c2) {
+ if (c1.equals(c2)) {
+ return 0;
+ }
+ return c1.getName().compareTo(c2.getName());
+ }
+ });
+
+ /**
+ * limits the amount of logging to once per coprocessor class.
+ * Used in concert with {@link #useLegacyMethod(Class, String, Class[])} when a runtime issue
+ * prevents properly supporting the legacy version of a coprocessor API.
+ * Since coprocessors can be in tight loops this serves to limit the amount of log spam we create.
+ */
+ @InterfaceAudience.Private
+ protected void legacyWarning(final Class<? extends Coprocessor> clazz, final String message) {
+ if(legacyWarning.add(clazz)) {
+ LOG.error("You have a legacy coprocessor loaded and there are events we can't map to the " +
+ " deprecated API. Your coprocessor will not see these events. Please update '" + clazz +
+ "'. Details of the problem: " + message);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/hbase/blob/8726a60a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java
index 73faf3c..15c357c 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java
@@ -60,12 +60,15 @@ public class MasterCoprocessorHost
static class MasterEnvironment extends CoprocessorHost.Environment
implements MasterCoprocessorEnvironment {
private MasterServices masterServices;
+ final boolean supportGroupCPs;
public MasterEnvironment(final Class<?> implClass, final Coprocessor impl,
final int priority, final int seq, final Configuration conf,
final MasterServices services) {
super(impl, priority, seq, conf);
this.masterServices = services;
+ supportGroupCPs = !useLegacyMethod(impl.getClass(),
+ "preBalanceGroup", ObserverContext.class, String.class);
}
public MasterServices getMasterServices() {
@@ -852,14 +855,16 @@ public class MasterCoprocessorHost
}
});
}
-
+
public void preMoveServers(final Set<HostPort> servers, final String targetGroup)
throws IOException {
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
@Override
public void call(MasterObserver oserver,
ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException {
- oserver.preMoveServers(ctx, servers, targetGroup);
+ if(((MasterEnvironment)ctx.getEnvironment()).supportGroupCPs) {
+ oserver.preMoveServers(ctx, servers, targetGroup);
+ }
}
});
}
@@ -870,7 +875,9 @@ public class MasterCoprocessorHost
@Override
public void call(MasterObserver oserver,
ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException {
- oserver.postMoveServers(ctx, servers, targetGroup);
+ if(((MasterEnvironment)ctx.getEnvironment()).supportGroupCPs) {
+ oserver.postMoveServers(ctx, servers, targetGroup);
+ }
}
});
}
@@ -881,7 +888,9 @@ public class MasterCoprocessorHost
@Override
public void call(MasterObserver oserver,
ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException {
- oserver.preMoveTables(ctx, tables, targetGroup);
+ if(((MasterEnvironment)ctx.getEnvironment()).supportGroupCPs) {
+ oserver.preMoveTables(ctx, tables, targetGroup);
+ }
}
});
}
@@ -892,7 +901,9 @@ public class MasterCoprocessorHost
@Override
public void call(MasterObserver oserver,
ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException {
- oserver.postMoveTables(ctx, tables, targetGroup);
+ if(((MasterEnvironment)ctx.getEnvironment()).supportGroupCPs) {
+ oserver.postMoveTables(ctx, tables, targetGroup);
+ }
}
});
}
@@ -903,7 +914,9 @@ public class MasterCoprocessorHost
@Override
public void call(MasterObserver oserver,
ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException {
- oserver.preAddGroup(ctx, name);
+ if(((MasterEnvironment)ctx.getEnvironment()).supportGroupCPs) {
+ oserver.preAddGroup(ctx, name);
+ }
}
});
}
@@ -914,7 +927,9 @@ public class MasterCoprocessorHost
@Override
public void call(MasterObserver oserver,
ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException {
- oserver.postAddGroup(ctx, name);
+ if (((MasterEnvironment) ctx.getEnvironment()).supportGroupCPs) {
+ oserver.postAddGroup(ctx, name);
+ }
}
});
}
@@ -925,7 +940,9 @@ public class MasterCoprocessorHost
@Override
public void call(MasterObserver oserver,
ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException {
- oserver.preRemoveGroup(ctx, name);
+ if(((MasterEnvironment)ctx.getEnvironment()).supportGroupCPs) {
+ oserver.preRemoveGroup(ctx, name);
+ }
}
});
}
@@ -936,7 +953,9 @@ public class MasterCoprocessorHost
@Override
public void call(MasterObserver oserver,
ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException {
- oserver.postRemoveGroup(ctx, name);
+ if(((MasterEnvironment)ctx.getEnvironment()).supportGroupCPs) {
+ oserver.postRemoveGroup(ctx, name);
+ }
}
});
}
@@ -947,7 +966,9 @@ public class MasterCoprocessorHost
@Override
public void call(MasterObserver oserver,
ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException {
- oserver.preBalanceGroup(ctx, name);
+ if(((MasterEnvironment)ctx.getEnvironment()).supportGroupCPs) {
+ oserver.preBalanceGroup(ctx, name);
+ }
}
});
}
@@ -958,10 +979,12 @@ public class MasterCoprocessorHost
@Override
public void call(MasterObserver oserver,
ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException {
- oserver.postBalanceGroup(ctx, name, balanceRan);
+ if(((MasterEnvironment)ctx.getEnvironment()).supportGroupCPs) {
+ oserver.postBalanceGroup(ctx, name, balanceRan);
+ }
}
});
- }
+ }
private static abstract class CoprocessorOperation
extends ObserverContext<MasterCoprocessorEnvironment> {