.../hbase/TestInterfaceAudienceAnnotations.java | 96 ++++++++++++++++++++++ .../java/org/apache/hadoop/hbase/util/Triple.java | 4 + 2 files changed, 100 insertions(+) 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..34cc43e 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.Method; import java.lang.reflect.Modifier; +import java.lang.reflect.Parameter; +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 */ @@ -299,4 +306,93 @@ public class TestInterfaceAudienceAnnotations { + "have @InterfaceStability annotation as well", 0, classes.size()); } + + @Test + public void testProtosInReturnTypes() 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); + 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()); + } + + @Test + public void testProtosInParamTypes() 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); + List, Method, Parameter>> protosParamType = + new ArrayList, Method, Parameter>>(); + 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, Parameter> pair : protosParamType) { + LOG.info(pair.getFirst().getName() + " " + pair.getSecond().getName() + " " + + pair.getThird().getType().getName()); + } + } + + Assert.assertEquals("Public exposed methods should not have protos in param type", 0, + protosParamType.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) { + Class returnType = method.getReturnType(); + if (returnType.getName().contains(HBASE_PROTOBUF)) { + returnTypePair.setSecond(method); + protosReturnType.add(returnTypePair); + continue; + } + } + } + } + + private void findProtoInParamType(Class clazz, + List, Method, Parameter>> protosParamType) { + Triple, Method, Parameter> paramType = new Triple, Method, Parameter>(); + Method[] methods = clazz.getMethods(); + paramType.setFirst(clazz); + for (Method method : methods) { + if (clazz.isInterface() || method.getModifiers() == Modifier.PUBLIC) { + Parameter[] parameters = method.getParameters(); + for (Parameter param : parameters) { + if (param.getType().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;