.../java/org/apache/hadoop/hbase/RegionLoad.java | 1 + .../java/org/apache/hadoop/hbase/ServerLoad.java | 2 + .../hadoop/hbase/client/RegionLoadStats.java | 4 +- .../hbase/TestInterfaceAudienceAnnotations.java | 152 +++++++++++++++++++++ .../java/org/apache/hadoop/hbase/util/Triple.java | 4 + 5 files changed, 161 insertions(+), 2 deletions(-) diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/RegionLoad.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/RegionLoad.java index 5bf2ec7..b5852d4 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/RegionLoad.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/RegionLoad.java @@ -38,6 +38,7 @@ public class RegionLoad { protected ClusterStatusProtos.RegionLoad regionLoadPB; + @InterfaceAudience.Private public RegionLoad(ClusterStatusProtos.RegionLoad regionLoadPB) { this.regionLoadPB = regionLoadPB; } diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/ServerLoad.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/ServerLoad.java index 1ddcc20..3ea59db 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/ServerLoad.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/ServerLoad.java @@ -57,6 +57,7 @@ public class ServerLoad { private long totalCompactingKVs = 0; private long currentCompactedKVs = 0; + @InterfaceAudience.Private public ServerLoad(ClusterStatusProtos.ServerLoad serverLoad) { this.serverLoad = serverLoad; for (ClusterStatusProtos.RegionLoad rl: serverLoad.getRegionLoadsList()) { @@ -81,6 +82,7 @@ public class ServerLoad { // NOTE: Function name cannot start with "get" because then an OpenDataException is thrown because // HBaseProtos.ServerLoad cannot be converted to an open data type(see HBASE-5967). /* @return the underlying ServerLoad protobuf object */ + @InterfaceAudience.Private public ClusterStatusProtos.ServerLoad obtainServerLoadPB() { return serverLoad; } diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RegionLoadStats.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RegionLoadStats.java index 443026f..bfdb216 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RegionLoadStats.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RegionLoadStats.java @@ -20,11 +20,11 @@ package org.apache.hadoop.hbase.client; import org.apache.hadoop.hbase.classification.InterfaceAudience; import org.apache.hadoop.hbase.classification.InterfaceStability; -@InterfaceAudience.Public -@InterfaceStability.Evolving /** * POJO representing region server load */ +@InterfaceAudience.Public +@InterfaceStability.Evolving public class RegionLoadStats { int memstoreLoad; int heapOccupancy; diff --git a/hbase-client/src/test/java/org/apache/hadoop/hbase/TestInterfaceAudienceAnnotations.java b/hbase-client/src/test/java/org/apache/hadoop/hbase/TestInterfaceAudienceAnnotations.java index 0e0fbb0..426b6a7 100644 --- a/hbase-client/src/test/java/org/apache/hadoop/hbase/TestInterfaceAudienceAnnotations.java +++ b/hbase-client/src/test/java/org/apache/hadoop/hbase/TestInterfaceAudienceAnnotations.java @@ -20,7 +20,11 @@ package org.apache.hadoop.hbase; import java.io.IOException; import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.List; import java.util.Set; import org.apache.commons.logging.Log; @@ -28,6 +32,8 @@ import org.apache.commons.logging.LogFactory; import org.apache.hadoop.hbase.classification.InterfaceAudience; import org.apache.hadoop.hbase.classification.InterfaceStability; import org.apache.hadoop.hbase.testclassification.SmallTests; +import org.apache.hadoop.hbase.util.Pair; +import org.apache.hadoop.hbase.util.Triple; import org.apache.hadoop.hbase.ClassFinder.And; import org.apache.hadoop.hbase.ClassFinder.FileNameFilter; import org.apache.hadoop.hbase.ClassFinder.Not; @@ -59,6 +65,7 @@ import org.junit.experimental.categories.Category; @Category(SmallTests.class) public class TestInterfaceAudienceAnnotations { + private static final String HBASE_PROTOBUF = "org.apache.hadoop.hbase.protobuf.generated"; private static final Log LOG = LogFactory.getLog(TestInterfaceAudienceAnnotations.class); /** Selects classes with generated in their package name */ @@ -180,6 +187,28 @@ public class TestInterfaceAudienceAnnotations { c.equals(InterfaceStability.Evolving.class); } + private boolean isInterfacePrivateMethod(Method m) { + if(m.getDeclaredAnnotations().length > 0) { + for(Annotation ann : m.getDeclaredAnnotations()) { + if(ann.annotationType().equals(InterfaceAudience.Private.class)) { + return true; + } + } + } + return false; + } + + private boolean isInterfacePrivateContructor(Constructor c) { + if(c.getDeclaredAnnotations().length > 0) { + for(Annotation ann : c.getDeclaredAnnotations()) { + if(ann.annotationType().equals(InterfaceAudience.Private.class)) { + return true; + } + } + } + return false; + } + /** Selects classes that are declared public */ class PublicClassFilter implements ClassFinder.ClassFilter { @Override @@ -299,4 +328,127 @@ public class TestInterfaceAudienceAnnotations { + "have @InterfaceStability annotation as well", 0, classes.size()); } + + @Test + public void testProtosInReturnTypes() throws ClassNotFoundException, IOException, LinkageError { + Set> classes = findPublicClasses(); + List, Method>> protosReturnType = new ArrayList, Method>>(); + for (Class clazz : classes) { + findProtoInReturnType(clazz, protosReturnType); + } + if (protosReturnType.size() != 0) { + LOG.info("These are the methods that have Protos as the return type"); + for (Pair, Method> pair : protosReturnType) { + LOG.info(pair.getFirst().getName() + " " + pair.getSecond().getName() + " " + + pair.getSecond().getReturnType().getName()); + } + } + + Assert.assertEquals("Public exposed methods should not have protos in return type", 0, + protosReturnType.size()); + } + + private Set> findPublicClasses() + throws ClassNotFoundException, IOException, LinkageError { + ClassFinder classFinder = + new ClassFinder(new And(new MainCodeResourcePathFilter(), new TestFileNameFilter()), + new Not((FileNameFilter) new TestFileNameFilter()), + new And(new PublicClassFilter(), new Not(new TestClassFilter()), + new Not(new GeneratedClassFilter()), + new InterfaceAudiencePublicAnnotatedClassFilter())); + Set> classes = classFinder.findClasses(false); + return classes; + } + + @Test + public void testProtosInParamTypes() throws ClassNotFoundException, IOException, LinkageError { + Set> classes = findPublicClasses(); + List, Method, Class>> protosParamType = + new ArrayList, Method, Class>>(); + for (Class clazz : classes) { + findProtoInParamType(clazz, protosParamType); + } + + if (protosParamType.size() != 0) { + LOG.info("These are the methods that have Protos as the param type"); + for (Triple, Method, Class> pair : protosParamType) { + LOG.info(pair.getFirst().getName() + " " + pair.getSecond().getName() + " " + + pair.getThird().getName()); + } + } + + Assert.assertEquals("Public exposed methods should not have protos in param type", 0, + protosParamType.size()); + } + + @Test + public void testProtosInConstructors() throws ClassNotFoundException, IOException, LinkageError { + Set> classes = findPublicClasses(); + List> classList = new ArrayList>(); + for (Class clazz : classes) { + Constructor[] constructors = clazz.getConstructors(); + for (Constructor cons : constructors) { + if (!isInterfacePrivateContructor(cons)) { + Class[] parameterTypes = cons.getParameterTypes(); + for (Class param : parameterTypes) { + if (param.getName().contains(HBASE_PROTOBUF)) { + classList.add(clazz); + break; + } + } + } + } + } + + if (classList.size() != 0) { + LOG.info("These are the classes that have Protos in the constructor"); + for (Class clazz : classList) { + LOG.info(clazz.getName()); + } + } + + Assert.assertEquals("Public exposed classes should not have protos in constructors", 0, + classList.size()); + } + + private void findProtoInReturnType(Class clazz, + List, Method>> protosReturnType) { + Pair, Method> returnTypePair = new Pair, Method>(); + Method[] methods = clazz.getMethods(); + returnTypePair.setFirst(clazz); + for (Method method : methods) { + if (clazz.isInterface() || method.getModifiers() == Modifier.PUBLIC) { + if (!isInterfacePrivateMethod(method)) { + Class returnType = method.getReturnType(); + if (returnType.getName().contains(HBASE_PROTOBUF)) { + returnTypePair.setSecond(method); + protosReturnType.add(returnTypePair); + continue; + } + } + } + } + } + + private void findProtoInParamType(Class clazz, + List, Method, Class>> protosParamType) { + Triple, Method, Class> paramType = new Triple, Method, Class>(); + Method[] methods = clazz.getMethods(); + paramType.setFirst(clazz); + for (Method method : methods) { + if (clazz.isInterface() || method.getModifiers() == Modifier.PUBLIC) { + if (!isInterfacePrivateMethod(method)) { + Class[] parameters = method.getParameterTypes(); + for (Class param : parameters) { + if (param.getName().contains(HBASE_PROTOBUF)) { + paramType.setSecond(method); + paramType.setThird(param); + protosParamType.add(paramType); + break; + } + } + } + } + } + } } diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/Triple.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/Triple.java index 1438ab7..1de6bee 100644 --- a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/Triple.java +++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/Triple.java @@ -28,6 +28,10 @@ public class Triple { private A first; private B second; private C third; + // default constructor + public Triple() { + + } public Triple(A first, B second, C third) { this.first = first;