]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6013 Return manual rules in /batch/project to be able to handle manual issues
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 22 Jan 2015 15:51:15 +0000 (16:51 +0100)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 22 Jan 2015 16:20:33 +0000 (17:20 +0100)
server/sonar-server/src/main/java/org/sonar/server/batch/ProjectRepositoryAction.java
server/sonar-server/src/main/java/org/sonar/server/batch/ProjectRepositoryLoader.java
server/sonar-server/src/main/java/org/sonar/server/component/db/ComponentDao.java
server/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java
server/sonar-server/src/test/java/org/sonar/server/batch/ProjectRepositoryLoaderMediumTest.java
server/sonar-server/src/test/java/org/sonar/server/component/db/ComponentDaoTest.java
server/sonar-server/src/test/java/org/sonar/server/rule/RuleTesting.java
sonar-core/src/main/java/org/sonar/core/component/db/ComponentMapper.java
sonar-core/src/main/resources/org/sonar/core/component/db/ComponentMapper.xml

index dd7d45c2d78dcdc78852bffca9cb53516a82e078..9f87aa9ad1f4678b9f535b019d412cd1ef9c336a 100644 (file)
@@ -74,4 +74,5 @@ public class ProjectRepositoryAction implements RequestHandler {
     response.stream().setMediaType(MimeTypes.JSON);
     IOUtils.write(ref.toJson(), response.stream().output());
   }
+
 }
index 61917a481939b1e8e9d511f623c1c13858ec2b35..90d0151b79c593bc2108991f05ad42842e6401e6 100644 (file)
@@ -26,6 +26,7 @@ import com.google.common.collect.Multimap;
 import org.sonar.api.ServerComponent;
 import org.sonar.api.resources.Language;
 import org.sonar.api.resources.Languages;
+import org.sonar.api.rule.RuleKey;
 import org.sonar.batch.protocol.input.FileData;
 import org.sonar.batch.protocol.input.ProjectReferentials;
 import org.sonar.core.UtcDateUtils;
@@ -43,11 +44,16 @@ import org.sonar.server.qualityprofile.QProfileFactory;
 import org.sonar.server.qualityprofile.QProfileLoader;
 import org.sonar.server.rule.Rule;
 import org.sonar.server.rule.RuleService;
+import org.sonar.server.rule.index.RuleNormalizer;
+import org.sonar.server.rule.index.RuleQuery;
+import org.sonar.server.search.QueryContext;
+import org.sonar.server.search.Result;
 import org.sonar.server.user.UserSession;
 
 import javax.annotation.Nullable;
 
 import java.util.Collections;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
@@ -82,41 +88,43 @@ public class ProjectRepositoryLoader implements ServerComponent {
       ComponentDto module = dbClient.componentDao().getNullableByKey(session, query.getModuleKey());
       // Current project/module can be null when analysing a new project
       if (module != null) {
-        ComponentDto project = dbClient.componentDao().getNullableRootProjectByKey(query.getModuleKey(), session);
-
-        // Can be null if the given project is a provisioned one
-        if (project != null) {
-          if (!project.key().equals(module.key())) {
-            addSettings(ref, module.getKey(), getSettingsFromParents(module.key(), hasScanPerm, session));
-            projectKey = project.key();
-          }
-
-          List<ComponentDto> moduleChildren = dbClient.componentDao().findChildrenModulesFromModule(session, query.getModuleKey());
-          Map<String, String> moduleUuidsByKey = moduleUuidsByKey(module, moduleChildren);
-          Map<String, Long> moduleIdsByKey = moduleIdsByKey(module, moduleChildren);
-
-          List<PropertyDto> moduleChildrenSettings = dbClient.propertiesDao().findChildrenModuleProperties(query.getModuleKey(), session);
-          TreeModuleSettings treeModuleSettings = new TreeModuleSettings(moduleUuidsByKey, moduleIdsByKey, moduleChildren, moduleChildrenSettings, module);
-
-          addSettingsToChildrenModules(ref, query.getModuleKey(), Maps.<String, String>newHashMap(), treeModuleSettings, hasScanPerm, session);
-          addFileData(session, ref, moduleChildren, module.key());
-        } else {
-          // Add settings of the provisioned project
-          addSettings(ref, query.getModuleKey(), getPropertiesMap(dbClient.propertiesDao().selectProjectProperties(query.getModuleKey(), session), hasScanPerm));
+        ComponentDto project = getProject(module, session);
+        if (!project.key().equals(module.key())) {
+          addSettings(ref, module.getKey(), getSettingsFromParents(module, hasScanPerm, session));
+          projectKey = project.key();
         }
+
+        List<ComponentDto> moduleChildren = dbClient.componentDao().findChildrenModulesFromModule(session, query.getModuleKey());
+        Map<String, String> moduleUuidsByKey = moduleUuidsByKey(module, moduleChildren);
+        Map<String, Long> moduleIdsByKey = moduleIdsByKey(module, moduleChildren);
+
+        List<PropertyDto> moduleChildrenSettings = dbClient.propertiesDao().findChildrenModuleProperties(query.getModuleKey(), session);
+        TreeModuleSettings treeModuleSettings = new TreeModuleSettings(moduleUuidsByKey, moduleIdsByKey, moduleChildren, moduleChildrenSettings, module);
+
+        addSettingsToChildrenModules(ref, query.getModuleKey(), Maps.<String, String>newHashMap(), treeModuleSettings, hasScanPerm, session);
+        addFileData(session, ref, moduleChildren, module.key());
       }
 
       addProfiles(ref, projectKey, query.getProfileName(), session);
       addActiveRules(ref);
+      addManualRules(ref);
       return ref;
     } finally {
       MyBatis.closeQuietly(session);
     }
   }
 
-  private Map<String, String> getSettingsFromParents(String moduleKey, boolean hasScanPerm, DbSession session) {
+  private ComponentDto getProject(ComponentDto module, DbSession session) {
+    if (!module.isRootProject()) {
+      return dbClient.componentDao().getNullableByUuid(session, module.projectUuid());
+    } else {
+      return module;
+    }
+  }
+
+  private Map<String, String> getSettingsFromParents(ComponentDto module, boolean hasScanPerm, DbSession session) {
     List<ComponentDto> parents = newArrayList();
-    aggregateParentModules(moduleKey, parents, session);
+    aggregateParentModules(module, parents, session);
     Collections.reverse(parents);
 
     Map<String, String> parentProperties = newHashMap();
@@ -126,11 +134,14 @@ public class ProjectRepositoryLoader implements ServerComponent {
     return parentProperties;
   }
 
-  private void aggregateParentModules(String component, List<ComponentDto> parents, DbSession session) {
-    ComponentDto parent = dbClient.componentDao().getParentModuleByKey(component, session);
-    if (parent != null) {
-      parents.add(parent);
-      aggregateParentModules(parent.key(), parents, session);
+  private void aggregateParentModules(ComponentDto component, List<ComponentDto> parents, DbSession session) {
+    String moduleUuid = component.moduleUuid();
+    if (moduleUuid != null) {
+      ComponentDto parent = dbClient.componentDao().getByUuid(session, moduleUuid);
+      if (parent != null) {
+        parents.add(parent);
+        aggregateParentModules(parent, parents, session);
+      }
     }
   }
 
@@ -220,6 +231,20 @@ public class ProjectRepositoryLoader implements ServerComponent {
     }
   }
 
+  private void addManualRules(ProjectReferentials ref) {
+    Result<Rule> ruleSearchResult = ruleService.search(new RuleQuery().setRepositories(newArrayList(RuleKey.MANUAL_REPOSITORY_KEY)), new QueryContext().setScroll(true)
+      .setFieldsToReturn(newArrayList(RuleNormalizer.RuleField.KEY.field(), RuleNormalizer.RuleField.NAME.field())));
+    Iterator<Rule> rules = ruleSearchResult.scroll();
+    while (rules.hasNext()) {
+      Rule rule = rules.next();
+      ref.addActiveRule(new org.sonar.batch.protocol.input.ActiveRule(
+        RuleKey.MANUAL_REPOSITORY_KEY,
+        rule.key().rule(),
+        rule.name(),
+        null, null, null));
+    }
+  }
+
   private void addFileData(DbSession session, ProjectReferentials ref, List<ComponentDto> moduleChildren, String moduleKey) {
     Map<String, String> moduleKeysByUuid = newHashMap();
     for (ComponentDto module : moduleChildren) {
index b96b81fdb8ba39a6f81a010abde1389e9ae59c7c..d91d1d6a71a9ebdabd1edbdbf447572543a9ce04 100644 (file)
@@ -83,28 +83,6 @@ public class ComponentDao extends BaseDao<ComponentMapper, ComponentDto, String>
     return mapper(session).countById(id) > 0;
   }
 
-  /**
-   * Return null only if the component does not exists.
-   * If the component if a root project, it will return itself.
-   */
-  @CheckForNull
-  public ComponentDto getNullableRootProjectByKey(String componentKey, DbSession session) {
-    return mapper(session).selectRootProjectByKey(componentKey);
-  }
-
-  public ComponentDto getRootProjectByKey(String componentKey, DbSession session) {
-    ComponentDto componentDto = getNullableRootProjectByKey(componentKey, session);
-    if (componentDto == null) {
-      throw new NotFoundException(String.format("Root project for project '%s' not found", componentKey));
-    }
-    return componentDto;
-  }
-
-  @CheckForNull
-  public ComponentDto getParentModuleByKey(String componentKey, DbSession session) {
-    return mapper(session).selectParentModuleByKey(componentKey);
-  }
-
   public List<ComponentDto> findModulesByProject(String projectKey, DbSession session) {
     return mapper(session).findModulesByProject(projectKey);
   }
index a74fcc1b7e135c67e949a13c1e9e39707feef88f..9790530b312373184b8cd5f17187927294da02f5 100644 (file)
@@ -38,7 +38,6 @@ import org.sonar.api.user.UserFinder;
 import org.sonar.api.web.UserRole;
 import org.sonar.core.component.ComponentDto;
 import org.sonar.core.issue.DefaultIssueBuilder;
-import org.sonar.server.issue.notification.IssueNotifications;
 import org.sonar.core.issue.IssueUpdater;
 import org.sonar.core.issue.db.IssueDao;
 import org.sonar.core.issue.db.IssueDto;
@@ -52,6 +51,7 @@ import org.sonar.server.db.DbClient;
 import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.issue.actionplan.ActionPlanService;
 import org.sonar.server.issue.index.IssueIndex;
+import org.sonar.server.issue.notification.IssueNotifications;
 import org.sonar.server.search.FacetValue;
 import org.sonar.server.search.IndexClient;
 import org.sonar.server.search.QueryContext;
@@ -251,7 +251,7 @@ public class IssueService implements ServerComponent {
     DbSession session = dbClient.openSession(false);
     try {
       ComponentDto component = dbClient.componentDao().getByKey(session, componentKey);
-      ComponentDto project = dbClient.componentDao().getRootProjectByKey(componentKey, session);
+      ComponentDto project = dbClient.componentDao().getByUuid(session, component.projectUuid());
 
       UserSession.get().checkProjectPermission(UserRole.USER, project.getKey());
       if (!ruleKey.isManual()) {
index bcc53133743f7b1283c49e2fcaa24481f526a26a..5726333c222851ef9129edbb130651a67664a259 100644 (file)
@@ -34,7 +34,6 @@ import org.sonar.batch.protocol.input.FileData;
 import org.sonar.batch.protocol.input.ProjectReferentials;
 import org.sonar.batch.protocol.input.QProfile;
 import org.sonar.core.component.ComponentDto;
-import org.sonar.core.component.SnapshotDto;
 import org.sonar.core.permission.GlobalPermissions;
 import org.sonar.core.persistence.DbSession;
 import org.sonar.core.properties.PropertyDto;
@@ -44,7 +43,6 @@ import org.sonar.core.rule.RuleParamDto;
 import org.sonar.core.source.db.FileSourceDao;
 import org.sonar.core.source.db.FileSourceDto;
 import org.sonar.server.component.ComponentTesting;
-import org.sonar.server.component.SnapshotTesting;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.qualityprofile.QProfileName;
@@ -296,28 +294,6 @@ public class ProjectRepositoryLoaderMediumTest {
       ));
   }
 
-  @Test
-  public void return_provisioned_project_settings() throws Exception {
-    MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
-
-    // No snapshot attached on the project -> provisioned project
-    ComponentDto project = ComponentTesting.newProjectDto();
-    tester.get(DbClient.class).componentDao().insert(dbSession, project);
-    addDefaultProfile();
-
-    // Project properties
-    tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()), dbSession);
-    tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()), dbSession);
-
-    dbSession.commit();
-
-    ProjectReferentials ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()));
-    assertThat(ref.settings(project.key())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR",
-      "sonar.jira.login.secured", "john"
-      ));
-  }
-
   @Test
   public void return_sub_module_settings() throws Exception {
     MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
@@ -357,8 +333,6 @@ public class ProjectRepositoryLoaderMediumTest {
 
     ComponentDto project = ComponentTesting.newProjectDto();
     tester.get(DbClient.class).componentDao().insert(dbSession, project);
-    SnapshotDto projectSnapshot = SnapshotTesting.createForProject(project);
-    tester.get(DbClient.class).snapshotDao().insert(dbSession, projectSnapshot);
     addDefaultProfile();
 
     // Project property
@@ -366,15 +340,12 @@ public class ProjectRepositoryLoaderMediumTest {
 
     ComponentDto module = ComponentTesting.newModuleDto(project);
     tester.get(DbClient.class).componentDao().insert(dbSession, module);
-    SnapshotDto moduleSnapshot = SnapshotTesting.createForComponent(module, projectSnapshot);
-    tester.get(DbClient.class).snapshotDao().insert(dbSession, moduleSnapshot);
 
     // Module property
     tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(module.getId()), dbSession);
 
     ComponentDto subModule = ComponentTesting.newModuleDto(module);
     tester.get(DbClient.class).componentDao().insert(dbSession, subModule);
-    tester.get(DbClient.class).snapshotDao().insert(dbSession, SnapshotTesting.createForComponent(subModule, moduleSnapshot));
 
     // Sub module properties
     tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(subModule.getId()), dbSession);
@@ -397,8 +368,6 @@ public class ProjectRepositoryLoaderMediumTest {
 
     ComponentDto project = ComponentTesting.newProjectDto();
     tester.get(DbClient.class).componentDao().insert(dbSession, project);
-    SnapshotDto projectSnapshot = SnapshotTesting.createForProject(project);
-    tester.get(DbClient.class).snapshotDao().insert(dbSession, projectSnapshot);
     addDefaultProfile();
 
     // Project properties
@@ -408,13 +377,10 @@ public class ProjectRepositoryLoaderMediumTest {
 
     ComponentDto module = ComponentTesting.newModuleDto(project);
     tester.get(DbClient.class).componentDao().insert(dbSession, module);
-    SnapshotDto moduleSnapshot = SnapshotTesting.createForComponent(module, projectSnapshot);
-    tester.get(DbClient.class).snapshotDao().insert(dbSession, moduleSnapshot);
     // No module property
 
     ComponentDto subModule = ComponentTesting.newModuleDto(module);
     tester.get(DbClient.class).componentDao().insert(dbSession, subModule);
-    tester.get(DbClient.class).snapshotDao().insert(dbSession, SnapshotTesting.createForComponent(subModule, moduleSnapshot));
     // No sub module property
 
     dbSession.commit();
@@ -435,8 +401,6 @@ public class ProjectRepositoryLoaderMediumTest {
 
     ComponentDto project = ComponentTesting.newProjectDto();
     tester.get(DbClient.class).componentDao().insert(dbSession, project);
-    SnapshotDto projectSnapshot = SnapshotTesting.createForProject(project);
-    tester.get(DbClient.class).snapshotDao().insert(dbSession, projectSnapshot);
     addDefaultProfile();
 
     // Project properties
@@ -445,15 +409,12 @@ public class ProjectRepositoryLoaderMediumTest {
 
     ComponentDto module = ComponentTesting.newModuleDto(project);
     tester.get(DbClient.class).componentDao().insert(dbSession, module);
-    SnapshotDto moduleSnapshot = SnapshotTesting.createForComponent(module, projectSnapshot);
-    tester.get(DbClient.class).snapshotDao().insert(dbSession, moduleSnapshot);
 
     // Module property
     tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module.getId()), dbSession);
 
     ComponentDto subModule = ComponentTesting.newModuleDto(module);
     tester.get(DbClient.class).componentDao().insert(dbSession, subModule);
-    tester.get(DbClient.class).snapshotDao().insert(dbSession, SnapshotTesting.createForComponent(subModule, moduleSnapshot));
     // No sub module property
 
     dbSession.commit();
@@ -637,10 +598,31 @@ public class ProjectRepositoryLoaderMediumTest {
     assertThat(activeRules.get(0).language()).isEqualTo("xoo");
     assertThat(activeRules.get(0).severity()).isEqualTo("MINOR");
     assertThat(activeRules.get(0).internalKey()).isEqualTo("squid-1");
-    assertThat(activeRules.get(0).language()).isEqualTo("xoo");
     assertThat(activeRules.get(0).params()).isEqualTo(ImmutableMap.of("max", "2"));
   }
 
+  @Test
+  public void return_manual_rules() throws Exception {
+    MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+
+    ComponentDto project = ComponentTesting.newProjectDto();
+    tester.get(DbClient.class).componentDao().insert(dbSession, project);
+    addDefaultProfile();
+
+    RuleDto rule = RuleTesting.newManualRule("manualRuleKey").setName("Name manualRuleKey");
+    tester.get(DbClient.class).ruleDao().insert(dbSession, rule);
+
+    dbSession.commit();
+
+    ProjectReferentials ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()));
+    List<ActiveRule> activeRules = newArrayList(ref.activeRules());
+    assertThat(activeRules).extracting("repositoryKey").containsOnly(RuleKey.MANUAL_REPOSITORY_KEY);
+    assertThat(activeRules).extracting("ruleKey").containsOnly("manualRuleKey");
+    assertThat(activeRules).extracting("name").containsOnly("Name manualRuleKey");
+    assertThat(activeRules).extracting("language").containsNull();
+    assertThat(activeRules).extracting("severity").containsNull();
+  }
+
   @Test
   public void fail_if_no_permission() throws Exception {
     MockUserSession.set().setLogin("john").setGlobalPermissions();
index aa7a3754861012f2ab5ee484e206b99e988a4eab..aaadc8b91fb3565acdecf17e5f74764c38f152d2 100644 (file)
@@ -256,46 +256,6 @@ public class ComponentDaoTest extends AbstractDaoTestCase {
     assertThat(dao.findModulesByProject("unknown", session)).isEmpty();
   }
 
-  @Test
-  public void get_nullable_root_project_by_key() throws Exception {
-    setupData("multi-modules");
-
-    assertThat(dao.getNullableRootProjectByKey("org.struts:struts-data", session).getKey()).isEqualTo("org.struts:struts");
-    assertThat(dao.getNullableRootProjectByKey("org.struts:struts-core", session).getKey()).isEqualTo("org.struts:struts");
-
-    // Root project of a project is itself
-    assertThat(dao.getNullableRootProjectByKey("org.struts:struts", session).getKey()).isEqualTo("org.struts:struts");
-
-    assertThat(dao.getNullableRootProjectByKey("unknown", session)).isNull();
-  }
-
-  @Test
-  public void get_root_project_by_key() throws Exception {
-    setupData("multi-modules");
-
-    assertThat(dao.getRootProjectByKey("org.struts:struts-data", session).getKey()).isEqualTo("org.struts:struts");
-    assertThat(dao.getRootProjectByKey("org.struts:struts-core", session).getKey()).isEqualTo("org.struts:struts");
-
-    // Root project of a project is itself
-    assertThat(dao.getRootProjectByKey("org.struts:struts", session).getKey()).isEqualTo("org.struts:struts");
-  }
-
-  @Test(expected = NotFoundException.class)
-  public void get_root_project_by_key_on_unknown_project() throws Exception {
-    dao.getRootProjectByKey("unknown", session);
-  }
-
-  @Test
-  public void get_parent_module_by_key() throws Exception {
-    setupData("multi-modules");
-
-    assertThat(dao.getParentModuleByKey("org.struts:struts-data", session).getKey()).isEqualTo("org.struts:struts-core");
-    assertThat(dao.getParentModuleByKey("org.struts:struts-core", session).getKey()).isEqualTo("org.struts:struts");
-    assertThat(dao.getParentModuleByKey("org.struts:struts", session)).isNull();
-
-    assertThat(dao.getParentModuleByKey("unknown", session)).isNull();
-  }
-
   @Test
   public void find_sub_projects_by_component_keys() throws Exception {
     setupData("multi-modules");
index 6cfd273bce40f91e655b0a000d620d937c6d4499..0cba9544e0bc5c83890c2e7d3afb47374b03e7b0 100644 (file)
@@ -98,7 +98,7 @@ public class RuleTesting {
   public static RuleDto newManualRule(String manualKey){
     return new RuleDto().setRuleKey(manualKey)
       .setName("Name " + manualKey)
-      .setRepositoryKey("manual")
+      .setRepositoryKey(RuleKey.MANUAL_REPOSITORY_KEY)
       .setDescription("Description " + manualKey)
       .setStatus(RuleStatus.READY);
   }
index 2c6cfe91be451cfb443700aa37f671f0838a30ad..04e4335382afd4f659cfe6fb495e51dbf169e83f 100644 (file)
@@ -52,12 +52,6 @@ public interface ComponentMapper {
   @CheckForNull
   ComponentDto selectByUuid(String uuid);
 
-  @CheckForNull
-  ComponentDto selectRootProjectByKey(String key);
-
-  @CheckForNull
-  ComponentDto selectParentModuleByKey(String key);
-
   /**
    * Return direct modules from a project/module
    */
index b47c06374d6248d580b4f084ab0cc39d7f12722b..d8067bf1215e39249a5ff15c13413f062ba148f2 100644 (file)
     </where>
   </select>
 
-  <select id="selectRootProjectByKey" parameterType="String" resultType="Component">
-    SELECT rootProject.*
-    FROM projects p
-    INNER JOIN projects rootProject ON rootProject.uuid=p.project_uuid
-    <where>
-      AND p.kee=#{componentKey}
-    </where>
-  </select>
-
-  <select id="selectParentModuleByKey" parameterType="String" resultType="Component">
-    SELECT <include refid="componentColumns"/>
-    FROM projects p
-    INNER JOIN snapshots s ON s.project_id=p.id AND s.islast=${_true}
-    INNER JOIN snapshots child_snapshots ON child_snapshots.parent_snapshot_id=s.id AND child_snapshots.islast=${_true}
-    INNER JOIN projects child ON child.id=child_snapshots.project_id AND child.enabled=${_true} AND child.kee=#{key}
-    <where>
-      AND p.enabled=${_true}
-      AND p.scope='PRJ'
-    </where>
-  </select>
-
   <select id="findModulesByProject" parameterType="String" resultType="Component">
     SELECT <include refid="componentColumns"/>
     FROM projects p