Browse Source

AMBARI-18966. Add check to ensure we do not have @Transactional annotations on private methods. (Attila Doroszlai via stoader)

Attila Doroszlai 8 years ago
parent
commit
9c902d681a
19 changed files with 274 additions and 15 deletions
  1. 41 0
      ambari-project/pom.xml
  2. 17 0
      ambari-server/checkstyle.xml
  3. 4 0
      ambari-server/pom.xml
  4. 1 1
      ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProvider.java
  5. 2 2
      ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
  6. 1 1
      ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
  7. 3 3
      ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
  8. 1 1
      ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java
  9. 1 1
      ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java
  10. 1 1
      ambari-server/src/main/java/org/apache/ambari/server/state/host/HostImpl.java
  11. 1 1
      ambari-server/src/main/java/org/apache/ambari/server/state/services/RetryUpgradeActionService.java
  12. 1 1
      ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
  13. 2 2
      ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java
  14. 1 0
      pom.xml
  15. 32 1
      utility/pom.xml
  16. 55 0
      utility/src/main/java/org/apache/ambari/checkstyle/AvoidTransactionalOnPrivateMethodsCheck.java
  17. 15 0
      utility/src/main/resources/checkstyle_packages.xml
  18. 49 0
      utility/src/test/java/org/apache/ambari/checkstyle/AvoidTransactionalOnPrivateMethodsCheckTest.java
  19. 46 0
      utility/src/test/resources/org/apache/ambari/checkstyle/InputTransactionalOnPrivateMethods.java

+ 41 - 0
ambari-project/pom.xml

@@ -30,6 +30,8 @@
     <ambari.dir>${project.parent.basedir}</ambari.dir>
     <powermock.version>1.6.3</powermock.version>
     <jetty.version>8.1.19.v20160209</jetty.version>
+    <checkstyle.version>6.19</checkstyle.version> <!-- last version that does not require Java 8 -->
+    <checkstyle.skip>false</checkstyle.skip>
   </properties>
   <profiles>
     <profile>
@@ -477,6 +479,11 @@
         <artifactId>jline</artifactId>
         <version>2.11</version>
       </dependency>
+      <dependency>
+        <groupId>com.puppycrawl.tools</groupId>
+        <artifactId>checkstyle</artifactId>
+        <version>${checkstyle.version}</version>
+      </dependency>
     </dependencies>
   </dependencyManagement>
   <build>
@@ -486,6 +493,40 @@
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-surefire-plugin</artifactId>
         </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-checkstyle-plugin</artifactId>
+          <version>2.17</version>
+          <executions>
+            <execution>
+              <id>checkstyle</id>
+              <phase>test</phase>
+              <configuration>
+                <configLocation>${project.basedir}/checkstyle.xml</configLocation>
+                <encoding>UTF-8</encoding>
+                <consoleOutput>true</consoleOutput>
+                <failsOnError>true</failsOnError>
+                <linkXRef>false</linkXRef>
+                <skip>${checkstyle.skip}</skip>
+              </configuration>
+              <goals>
+                <goal>check</goal>
+              </goals>
+            </execution>
+          </executions>
+          <dependencies>
+            <dependency>
+              <groupId>com.puppycrawl.tools</groupId>
+              <artifactId>checkstyle</artifactId>
+              <version>${checkstyle.version}</version>
+            </dependency>
+            <dependency>
+              <groupId>utility</groupId>
+              <artifactId>utility</artifactId>
+              <version>1.0.0.0-SNAPSHOT</version>
+            </dependency>
+          </dependencies>
+        </plugin>
       </plugins>
     </pluginManagement>
     <plugins>

+ 17 - 0
ambari-server/checkstyle.xml

@@ -0,0 +1,17 @@
+<?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="AvoidTransactionalOnPrivateMethodsCheck"/>
+  </module>
+</module>

+ 4 - 0
ambari-server/pom.xml

@@ -686,6 +686,10 @@
         <artifactId>jetty-maven-plugin</artifactId>
         <version>${jetty.version}</version>
       </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+      </plugin>
     </plugins>
     <resources>
       <resource>

+ 1 - 1
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProvider.java

@@ -374,7 +374,7 @@ public class AlertTargetResourceProvider extends
    */
   @Transactional
   @SuppressWarnings("unchecked")
-  private void updateAlertTargets(long alertTargetId,
+  void updateAlertTargets(long alertTargetId,
       Map<String, Object> requestMap)
       throws AmbariException {
 

+ 2 - 2
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java

@@ -442,7 +442,7 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
   }
 
   @Transactional
-  private void createHostVersions(Cluster cluster, List<Host> hosts, StackId stackId,
+  void createHostVersions(Cluster cluster, List<Host> hosts, StackId stackId,
       String desiredRepoVersion, RepositoryVersionState repoState)
       throws AmbariException, SystemException {
     final String clusterName = cluster.getClusterName();
@@ -482,7 +482,7 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
   }
 
   @Transactional
-  private RequestStageContainer createOrchestration(Cluster cluster, StackId stackId,
+  RequestStageContainer createOrchestration(Cluster cluster, StackId stackId,
       List<Host> hosts, RepositoryVersionEntity repoVersionEnt, Map<String, Object> propertyMap)
       throws AmbariException, SystemException {
     final AmbariManagementController managementController = getManagementController();

+ 1 - 1
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java

@@ -956,7 +956,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
    * @throws AmbariException
    */
   @Transactional
-  private UpgradeEntity createUpgradeInsideTransaction(Cluster cluster,
+  UpgradeEntity createUpgradeInsideTransaction(Cluster cluster,
       RequestStageContainer request,
       UpgradeEntity upgradeEntity) throws AmbariException {
 

+ 3 - 3
ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java

@@ -1492,7 +1492,7 @@ public class AlertsDAO implements Cleanable {
    * @return a long representing the number of affected (deleted) records
    */
   @Transactional
-  private int cleanAlertNoticesForClusterBeforeDate(Long clusterId, long beforeDateMillis) {
+  int cleanAlertNoticesForClusterBeforeDate(Long clusterId, long beforeDateMillis) {
     LOG.info("Deleting AlertNotice entities before date " + new Date(beforeDateMillis));
     EntityManager entityManager = m_entityManagerProvider.get();
     List<Integer> ids = findAllAlertHistoryIdsBeforeDate(clusterId, beforeDateMillis);
@@ -1523,7 +1523,7 @@ public class AlertsDAO implements Cleanable {
    * @return a long representing the number of affected (deleted) records
    */
   @Transactional
-  private int cleanAlertCurrentsForClusterBeforeDate(long clusterId, long beforeDateMillis) {
+  int cleanAlertCurrentsForClusterBeforeDate(long clusterId, long beforeDateMillis) {
     LOG.info("Deleting AlertCurrent entities before date " + new Date(beforeDateMillis));
     EntityManager entityManager = m_entityManagerProvider.get();
     List<Integer> ids = findAllAlertHistoryIdsBeforeDate(clusterId, beforeDateMillis);
@@ -1553,7 +1553,7 @@ public class AlertsDAO implements Cleanable {
    */
 
   @Transactional
-  private int cleanAlertHistoriesForClusterBeforeDate(Long clusterId, long beforeDateMillis) {
+  int cleanAlertHistoriesForClusterBeforeDate(Long clusterId, long beforeDateMillis) {
     return executeQuery("AlertHistoryEntity.removeInClusterBeforeDate", AlertHistoryEntity.class, clusterId, beforeDateMillis);
   }
 

+ 1 - 1
ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java

@@ -451,7 +451,7 @@ public class ServiceImpl implements Service {
   }
 
   @Transactional
-  private void persistEntities(ClusterServiceEntity serviceEntity) {
+  void persistEntities(ClusterServiceEntity serviceEntity) {
     long clusterId = cluster.getClusterId();
     ClusterEntity clusterEntity = clusterDAO.findById(clusterId);
     serviceEntity.setClusterEntity(clusterEntity);

+ 1 - 1
ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java

@@ -183,7 +183,7 @@ public class ClustersImpl implements Clusters {
    */
   @Inject
   @Transactional
-  private void loadClustersAndHosts() {
+  void loadClustersAndHosts() {
     List<HostEntity> hostEntities = hostDAO.findAll();
     for (HostEntity hostEntity : hostEntities) {
       Host host = hostFactory.create(hostEntity);

+ 1 - 1
ambari-server/src/main/java/org/apache/ambari/server/state/host/HostImpl.java

@@ -954,7 +954,7 @@ public class HostImpl implements Host {
   }
 
   @Transactional
-  private void persistEntities(HostEntity hostEntity) {
+  void persistEntities(HostEntity hostEntity) {
     hostDAO.create(hostEntity);
     if (!hostEntity.getClusterEntities().isEmpty()) {
       for (ClusterEntity clusterEntity : hostEntity.getClusterEntities()) {

+ 1 - 1
ambari-server/src/main/java/org/apache/ambari/server/state/services/RetryUpgradeActionService.java

@@ -190,7 +190,7 @@ public class RetryUpgradeActionService extends AbstractScheduledService {
    * @param requestId Request Id to search tasks for.
    */
   @Transactional
-  private void retryHoldingCommandsInRequest(Long requestId) {
+  void retryHoldingCommandsInRequest(Long requestId) {
     if (requestId == null) {
       return;
     }

+ 1 - 1
ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java

@@ -1313,7 +1313,7 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
   }
 
   @Transactional
-  private void persistEntities(HostEntity hostEntity, HostComponentStateEntity stateEntity,
+  void persistEntities(HostEntity hostEntity, HostComponentStateEntity stateEntity,
       HostComponentDesiredStateEntity desiredStateEntity) {
     ServiceComponentDesiredStateEntity serviceComponentDesiredStateEntity = serviceComponentDesiredStateDAO.findByName(
         serviceComponent.getClusterId(), serviceComponent.getServiceName(),

+ 2 - 2
ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java

@@ -1553,7 +1553,7 @@ public class UpgradeCatalog240 extends AbstractUpgradeCatalog {
    * @throws SQLException
    */
   @Transactional
-  private void updateServiceComponentDesiredStateTableDDL() throws SQLException {
+  void updateServiceComponentDesiredStateTableDDL() throws SQLException {
     if (dbAccessor.tableHasPrimaryKey(SERVICE_COMPONENT_DS_TABLE, ID)) {
       LOG.info("Skipping {} table Primary Key modifications since the new {} column already exists",
           SERVICE_COMPONENT_DS_TABLE, ID);
@@ -2755,7 +2755,7 @@ public class UpgradeCatalog240 extends AbstractUpgradeCatalog {
    *  instead of cluster_name
    */
   @Transactional
-  private void updateViewInstanceTable() throws SQLException {
+  void updateViewInstanceTable() throws SQLException {
     try {
       if (Long.class.equals(dbAccessor.getColumnClass(VIEWINSTANCE_TABLE, CLUSTER_HANDLE_COLUMN))) {
         LOG.info(String.format("%s column is already numeric. Skipping an update of %s table.", CLUSTER_HANDLE_COLUMN, VIEWINSTANCE_TABLE));

+ 1 - 0
pom.xml

@@ -266,6 +266,7 @@
             <exclude>contrib/agent-simulator/docker_image/package_list.txt</exclude>
             <exclude>contrib/agent-simulator/config/cluster.txt</exclude>
             <exclude>version</exclude>
+            <exclude>**/target/surefire-reports/</exclude>
             <!--IDE and GIT files-->
             <exclude>**/.idea/</exclude>
             <exclude>**/.classpath/</exclude>

+ 32 - 1
utility/pom.xml

@@ -20,6 +20,13 @@
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
 
+  <parent>
+    <groupId>org.apache.ambari</groupId>
+    <artifactId>ambari-project</artifactId>
+    <version>2.5.0.0.0</version>
+    <relativePath>../ambari-project</relativePath>
+  </parent>
+
   <artifactId>utility</artifactId>
   <groupId>utility</groupId>
   <version>1.0.0.0-SNAPSHOT</version>
@@ -28,9 +35,25 @@
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
-      <version>4.12</version>
       <scope>compile</scope>    <!-- has to be compile-time dependency on junit -->
     </dependency>
+    <dependency>
+      <groupId>com.puppycrawl.tools</groupId>
+      <artifactId>checkstyle</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.puppycrawl.tools</groupId>
+      <artifactId>checkstyle</artifactId>
+      <type>test-jar</type>
+      <version>${checkstyle.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+      <version>19.0</version> <!-- required for checkstyle -->
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
   <build>
@@ -44,6 +67,14 @@
           <useIncrementalCompilation>false</useIncrementalCompilation>
         </configuration>
       </plugin>
+      <plugin>
+        <artifactId>maven-assembly-plugin</artifactId>
+        <configuration>
+          <descriptors>
+            <descriptor>${project.parent.basedir}/src/main/assemblies/empty.xml</descriptor>
+          </descriptors>
+        </configuration>
+      </plugin>
       <plugin>
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>rpm-maven-plugin</artifactId>

+ 55 - 0
utility/src/main/java/org/apache/ambari/checkstyle/AvoidTransactionalOnPrivateMethodsCheck.java

@@ -0,0 +1,55 @@
+/*
+ * 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 com.puppycrawl.tools.checkstyle.api.AbstractCheck;
+import com.puppycrawl.tools.checkstyle.api.DetailAST;
+import com.puppycrawl.tools.checkstyle.api.TokenTypes;
+
+/**
+ * Detects private methods annotated as <code>Transactional</code>.
+ * See https://github.com/google/guice/wiki/Transactions for why this should be
+ * avoided.
+ */
+public class AvoidTransactionalOnPrivateMethodsCheck extends AbstractCheck {
+
+  private static final String ANNOTATION_NAME = "Transactional";
+  public static final String MSG_TRANSACTIONAL_ON_PRIVATE_METHOD = "@" + ANNOTATION_NAME + " should not be used on private methods";
+
+  @Override
+  public int[] getDefaultTokens() {
+    return new int[] { TokenTypes.METHOD_DEF };
+  }
+
+  @Override
+  public void visitToken(DetailAST ast) {
+    DetailAST modifiers = ast.findFirstToken(TokenTypes.MODIFIERS);
+    if (modifiers.findFirstToken(TokenTypes.LITERAL_PRIVATE) != null) {
+      DetailAST annotation = modifiers.findFirstToken(TokenTypes.ANNOTATION);
+      while (annotation != null) {
+        DetailAST name = annotation.findFirstToken(TokenTypes.IDENT);
+        if (name != null && ANNOTATION_NAME.equals(name.getText())) {
+          log(ast.getLineNo(), MSG_TRANSACTIONAL_ON_PRIVATE_METHOD);
+          break;
+        }
+        annotation = annotation.getNextSibling();
+      }
+    }
+  }
+
+}

+ 15 - 0
utility/src/main/resources/checkstyle_packages.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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 checkstyle-packages PUBLIC
+  "-//Puppy Crawl//DTD Package Names 1.0//EN"
+  "http://www.puppycrawl.com/dtds/packages_1_0.dtd">
+<checkstyle-packages>
+  <package name="org.apache.ambari.checkstyle"/>
+</checkstyle-packages>

+ 49 - 0
utility/src/test/java/org/apache/ambari/checkstyle/AvoidTransactionalOnPrivateMethodsCheckTest.java

@@ -0,0 +1,49 @@
+/*
+ * 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.AvoidTransactionalOnPrivateMethodsCheck.MSG_TRANSACTIONAL_ON_PRIVATE_METHOD;
+
+import java.io.File;
+import java.io.IOException;
+
+import com.puppycrawl.tools.checkstyle.BaseCheckTestSupport;
+import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
+
+import org.junit.Test;
+
+public class AvoidTransactionalOnPrivateMethodsCheckTest 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 transactionalOnPrivateMethod() throws Exception {
+    final DefaultConfiguration config = createCheckConfig(AvoidTransactionalOnPrivateMethodsCheck.class);
+    final String[] expected = {
+      "32: " + MSG_TRANSACTIONAL_ON_PRIVATE_METHOD,
+      "41: " + MSG_TRANSACTIONAL_ON_PRIVATE_METHOD,
+    };
+
+    verify(config, getPath("InputTransactionalOnPrivateMethods.java"), expected);
+  }
+
+}

+ 46 - 0
utility/src/test/resources/org/apache/ambari/checkstyle/InputTransactionalOnPrivateMethods.java

@@ -0,0 +1,46 @@
+/*
+ * 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 com.google.inject.persist.Transactional;
+
+/**
+ * Input file for AvoidTransactionalOnPrivateMethodsCheckTest.
+ */
+public class InputTransactionalOnPrivateMethods {
+
+  @Transactional
+  public void publicMethodWithTransactional() {
+    ;
+  }
+
+  @Transactional
+  private void privateMethodWithTransactional() {
+    ;
+  }
+
+  private void privateMethodWithoutTransactional() {
+    ;
+  }
+
+  @Transactional
+  private void otherPrivateMethodWithTransactional() {
+    ;
+  }
+
+}