Repository: ambari
Updated Branches:
  refs/heads/ambari-rest-api-explorer 3acd2e6da -> 4ede67151


AMBARI-20735. Checkstyle rule to ensure that all API endpoints are documented


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/4ede6715
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/4ede6715
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/4ede6715

Branch: refs/heads/ambari-rest-api-explorer
Commit: 4ede671514563a3cc116bc2059d6d8b878a5a784
Parents: 3acd2e6
Author: Attila Doroszlai <adorosz...@hortonworks.com>
Authored: Tue Apr 11 17:24:36 2017 +0200
Committer: Attila Doroszlai <adorosz...@hortonworks.com>
Committed: Thu Apr 20 09:55:17 2017 +0200

----------------------------------------------------------------------
 ambari-server/checkstyle.xml                    |   1 +
 ambari-server/pom.xml                           |   2 +-
 ambari-server/src/main/assemblies/server.xml    |   2 +-
 utility/checkstyle.xml                          |  38 +++++
 utility/pom.xml                                 |   5 +-
 .../apache/ambari/annotations/ApiIgnore.java    |  29 ++++
 .../UndocumentedRestApiOperationCheck.java      |  76 ++++++++++
 ...dTransactionalOnPrivateMethodsCheckTest.java |   4 +-
 .../UndocumentedRestApiOperationCheckTest.java  |  53 +++++++
 .../checkstyle/InputRestApiOperation.java       | 138 +++++++++++++++++++
 10 files changed, 343 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/4ede6715/ambari-server/checkstyle.xml
----------------------------------------------------------------------
diff --git a/ambari-server/checkstyle.xml b/ambari-server/checkstyle.xml
index bf7698d..6b4824a 100644
--- a/ambari-server/checkstyle.xml
+++ b/ambari-server/checkstyle.xml
@@ -13,6 +13,7 @@
 <module name="Checker">
   <module name="TreeWalker">
     <module name="AvoidTransactionalOnPrivateMethodsCheck"/>
+    <!-- <module name="UndocumentedRestApiOperationCheck"/> Swagger - 
uncomment when API documentation is done -->
 
     <module name="FallThrough"/>
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/4ede6715/ambari-server/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-server/pom.xml b/ambari-server/pom.xml
index fbc2b9f..ba97f88 100644
--- a/ambari-server/pom.xml
+++ b/ambari-server/pom.xml
@@ -1631,7 +1631,7 @@
       <groupId>utility</groupId>
       <artifactId>utility</artifactId>
       <version>1.0.0.0-SNAPSHOT</version>
-      <scope>test</scope>
+      <scope>provided</scope> <!-- for @ApiIgnore -->
     </dependency>
     <dependency>
       <groupId>org.kohsuke</groupId>

http://git-wip-us.apache.org/repos/asf/ambari/blob/4ede6715/ambari-server/src/main/assemblies/server.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/assemblies/server.xml 
b/ambari-server/src/main/assemblies/server.xml
index 2783526..43053fb 100644
--- a/ambari-server/src/main/assemblies/server.xml
+++ b/ambari-server/src/main/assemblies/server.xml
@@ -418,7 +418,7 @@
       <fileMode>644</fileMode>
       <outputDirectory>/usr/lib/ambari-server</outputDirectory>
       <unpack>false</unpack>
-      <scope>compile</scope>
+      <scope>runtime</scope>
     </dependencySet>
   </dependencySets>
 </assembly>

http://git-wip-us.apache.org/repos/asf/ambari/blob/4ede6715/utility/checkstyle.xml
----------------------------------------------------------------------
diff --git a/utility/checkstyle.xml b/utility/checkstyle.xml
new file mode 100644
index 0000000..2e7d6f0
--- /dev/null
+++ b/utility/checkstyle.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<!-- Licensed 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.
+  See accompanying LICENSE file. -->
+<!DOCTYPE module PUBLIC
+  "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
+  "http://www.puppycrawl.com/dtds/configuration_1_3.dtd";>
+<module name="Checker">
+  <module name="TreeWalker">
+    <module name="FallThrough"/>
+
+    <!-- imports -->
+    <module name="AvoidStarImport"/>
+    <module name="IllegalImport"/>
+    <module name="ImportOrder">
+      <property name="groups" value="java,javax,org,com,*"/>
+      <property name="ordered" value="true"/>
+      <property name="separated" value="true"/>
+      <property name="option" value="top"/> <!-- static imports -->
+      <property name="sortStaticImportsAlphabetically" value="true"/>
+    </module>
+    <module name="RedundantImport"/>
+    <module name="UnusedImports"/>
+
+    <!-- blocks -->
+    <module name="AvoidNestedBlocks">
+      <property name="allowInSwitchCase" value="true"/>
+    </module>
+    <module name="EmptyBlock">
+      <property name="option" value="text"/>
+    </module>
+  </module>
+</module>

http://git-wip-us.apache.org/repos/asf/ambari/blob/4ede6715/utility/pom.xml
----------------------------------------------------------------------
diff --git a/utility/pom.xml b/utility/pom.xml
index 6f60206..7d5eb93 100644
--- a/utility/pom.xml
+++ b/utility/pom.xml
@@ -52,7 +52,6 @@
       <groupId>com.google.guava</groupId>
       <artifactId>guava</artifactId>
       <version>19.0</version> <!-- required for checkstyle -->
-      <scope>test</scope>
     </dependency>
   </dependencies>
 
@@ -96,6 +95,10 @@
           <mappings/>
         </configuration>
       </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+      </plugin>
     </plugins>
   </build>
 </project>

http://git-wip-us.apache.org/repos/asf/ambari/blob/4ede6715/utility/src/main/java/org/apache/ambari/annotations/ApiIgnore.java
----------------------------------------------------------------------
diff --git a/utility/src/main/java/org/apache/ambari/annotations/ApiIgnore.java 
b/utility/src/main/java/org/apache/ambari/annotations/ApiIgnore.java
new file mode 100644
index 0000000..d50c2fd
--- /dev/null
+++ b/utility/src/main/java/org/apache/ambari/annotations/ApiIgnore.java
@@ -0,0 +1,29 @@
+/*
+ * 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.ambari.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.SOURCE)
+@Target({ElementType.METHOD})
+public @interface ApiIgnore {
+  // marker
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/4ede6715/utility/src/main/java/org/apache/ambari/checkstyle/UndocumentedRestApiOperationCheck.java
----------------------------------------------------------------------
diff --git 
a/utility/src/main/java/org/apache/ambari/checkstyle/UndocumentedRestApiOperationCheck.java
 
b/utility/src/main/java/org/apache/ambari/checkstyle/UndocumentedRestApiOperationCheck.java
new file mode 100644
index 0000000..c6347db
--- /dev/null
+++ 
b/utility/src/main/java/org/apache/ambari/checkstyle/UndocumentedRestApiOperationCheck.java
@@ -0,0 +1,76 @@
+/*
+ * 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.ambari.checkstyle;
+
+import java.util.Set;
+
+import com.google.common.collect.ImmutableSet;
+import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
+import com.puppycrawl.tools.checkstyle.api.DetailAST;
+import com.puppycrawl.tools.checkstyle.api.TokenTypes;
+import com.puppycrawl.tools.checkstyle.utils.AnnotationUtility;
+
+/**
+ * REST API operations should either be documented, or marked to be ignored.
+ */
+public class UndocumentedRestApiOperationCheck extends AbstractCheck {
+
+  private static final Set<String> API_ANNOTATIONS = ImmutableSet.of("DELETE", 
"GET", "HEAD", "OPTIONS", "PUT", "POST");
+  private static final String API_OPERATION = "ApiOperation";
+  private static final String API_IGNORE = "ApiIgnore";
+  public static final String MESSAGE = "REST API operation should be 
documented";
+
+  @Override
+  public int[] getDefaultTokens() {
+    return new int[] { TokenTypes.METHOD_DEF };
+  }
+
+  @Override
+  public void visitToken(DetailAST ast) {
+    if (isApiOperation(ast) && !isDocumentedApiOperation(ast) && 
!isIgnoredApi(ast)) {
+      log(ast.getLineNo(), MESSAGE);
+    }
+  }
+
+  private static boolean isApiOperation(DetailAST ast) {
+    DetailAST modifiers = ast.findFirstToken(TokenTypes.MODIFIERS);
+    if (modifiers.findFirstToken(TokenTypes.LITERAL_PRIVATE) != null) {
+      return false;
+    }
+
+    DetailAST annotation = modifiers.findFirstToken(TokenTypes.ANNOTATION);
+    while (annotation != null) {
+      DetailAST name = annotation.findFirstToken(TokenTypes.IDENT);
+      if (name != null && API_ANNOTATIONS.contains(name.getText())) {
+        return true;
+      }
+      annotation = annotation.getNextSibling();
+    }
+
+    return false;
+  }
+
+  private static boolean isDocumentedApiOperation(DetailAST ast) {
+    return AnnotationUtility.containsAnnotation(ast, API_OPERATION);
+  }
+
+  private static boolean isIgnoredApi(DetailAST ast) {
+    return AnnotationUtility.containsAnnotation(ast, API_IGNORE);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/4ede6715/utility/src/test/java/org/apache/ambari/checkstyle/AvoidTransactionalOnPrivateMethodsCheckTest.java
----------------------------------------------------------------------
diff --git 
a/utility/src/test/java/org/apache/ambari/checkstyle/AvoidTransactionalOnPrivateMethodsCheckTest.java
 
b/utility/src/test/java/org/apache/ambari/checkstyle/AvoidTransactionalOnPrivateMethodsCheckTest.java
index 14d7486..bfdbfa1 100644
--- 
a/utility/src/test/java/org/apache/ambari/checkstyle/AvoidTransactionalOnPrivateMethodsCheckTest.java
+++ 
b/utility/src/test/java/org/apache/ambari/checkstyle/AvoidTransactionalOnPrivateMethodsCheckTest.java
@@ -22,11 +22,11 @@ import static 
org.apache.ambari.checkstyle.AvoidTransactionalOnPrivateMethodsChe
 import java.io.File;
 import java.io.IOException;
 
+import org.junit.Test;
+
 import com.puppycrawl.tools.checkstyle.BaseCheckTestSupport;
 import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
 
-import org.junit.Test;
-
 public class AvoidTransactionalOnPrivateMethodsCheckTest extends 
BaseCheckTestSupport {
 
   @Override

http://git-wip-us.apache.org/repos/asf/ambari/blob/4ede6715/utility/src/test/java/org/apache/ambari/checkstyle/UndocumentedRestApiOperationCheckTest.java
----------------------------------------------------------------------
diff --git 
a/utility/src/test/java/org/apache/ambari/checkstyle/UndocumentedRestApiOperationCheckTest.java
 
b/utility/src/test/java/org/apache/ambari/checkstyle/UndocumentedRestApiOperationCheckTest.java
new file mode 100644
index 0000000..7caf3cf
--- /dev/null
+++ 
b/utility/src/test/java/org/apache/ambari/checkstyle/UndocumentedRestApiOperationCheckTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.ambari.checkstyle;
+
+import static 
org.apache.ambari.checkstyle.UndocumentedRestApiOperationCheck.MESSAGE;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.junit.Test;
+
+import com.puppycrawl.tools.checkstyle.BaseCheckTestSupport;
+import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
+
+public class UndocumentedRestApiOperationCheckTest extends 
BaseCheckTestSupport {
+
+  @Override
+  protected String getPath(String filename) throws IOException {
+    return new File("src/test/resources/org/apache/ambari/checkstyle/" + 
filename)
+      .getCanonicalPath();
+  }
+
+  @Test
+  public void test() throws Exception {
+    final DefaultConfiguration config = 
createCheckConfig(UndocumentedRestApiOperationCheck.class);
+    final String[] expected = {
+      "36: " + MESSAGE,
+      "53: " + MESSAGE,
+      "70: " + MESSAGE,
+      "87: " + MESSAGE,
+      "104: " + MESSAGE,
+      "121: " + MESSAGE
+    };
+
+    verify(config, getPath("InputRestApiOperation.java"), expected);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/4ede6715/utility/src/test/resources/org/apache/ambari/checkstyle/InputRestApiOperation.java
----------------------------------------------------------------------
diff --git 
a/utility/src/test/resources/org/apache/ambari/checkstyle/InputRestApiOperation.java
 
b/utility/src/test/resources/org/apache/ambari/checkstyle/InputRestApiOperation.java
new file mode 100644
index 0000000..9aa35ba
--- /dev/null
+++ 
b/utility/src/test/resources/org/apache/ambari/checkstyle/InputRestApiOperation.java
@@ -0,0 +1,138 @@
+/*
+ * 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.ambari.checkstyle;
+
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.HEAD;
+import javax.ws.rs.OPTIONS;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+
+import io.swagger.annotations.ApiOperation;
+
+import org.apache.ambari.annotations.ApiIgnore;
+
+/**
+ * Input file for UndocumentedRestApiOperationCheck.
+ */
+public class InputRestApiOperation {
+
+  @DELETE
+  public void undocumentedDELETE() {
+    ;
+  }
+
+  @DELETE
+  @ApiOperation(value = "...")
+  public void documentedDELETE() {
+    ;
+  }
+
+  @DELETE
+  @ApiIgnore
+  public void ignoredDELETE() {
+    ;
+  }
+
+  @HEAD
+  public void undocumentedHEAD() {
+    ;
+  }
+
+  @HEAD
+  @ApiOperation(value = "...")
+  public void documentedHEAD() {
+    ;
+  }
+
+  @HEAD
+  @ApiIgnore
+  public void ignoredHEAD() {
+    ;
+  }
+
+  @GET
+  public void undocumentedGET() {
+    ;
+  }
+
+  @GET
+  @ApiOperation(value = "...")
+  public void documentedGET() {
+    ;
+  }
+
+  @GET
+  @ApiIgnore
+  public void ignoredGET() {
+    ;
+  }
+
+  @OPTIONS
+  public void undocumentedOPTIONS() {
+    ;
+  }
+
+  @OPTIONS
+  @ApiOperation(value = "...")
+  public void documentedOPTIONS() {
+    ;
+  }
+
+  @OPTIONS
+  @ApiIgnore
+  public void ignoredOPTIONS() {
+    ;
+  }
+
+  @POST
+  public void undocumentedPOST() {
+    ;
+  }
+
+  @POST
+  @ApiOperation(value = "...")
+  public void documentedPOST() {
+    ;
+  }
+
+  @POST
+  @ApiIgnore
+  public void ignoredPOST() {
+    ;
+  }
+
+  @PUT
+  public void undocumentedPUT() {
+    ;
+  }
+
+  @PUT
+  @ApiOperation(value = "...")
+  public void documentedPUT() {
+    ;
+  }
+
+  @PUT
+  @ApiIgnore
+  public void ignoredPUT() {
+    ;
+  }
+
+}

Reply via email to