]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-17352 Refactor component keys to not include branch suffix
authorDuarte Meneses <duarte.meneses@sonarsource.com>
Fri, 30 Sep 2022 17:23:26 +0000 (12:23 -0500)
committersonartech <sonartech@sonarsource.com>
Wed, 12 Oct 2022 20:03:44 +0000 (20:03 +0000)
74 files changed:
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/analysis/ProjectConfigurationFactory.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/ComponentUuidFactoryImpl.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/ComponentUuidFactoryWithMigration.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/ConfigurationRepositoryImpl.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/ReferenceBranchComponentUuids.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/SiblingComponentsWithOpenIssues.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/ProjectTrackerBaseLazyInput.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/SiblingsIssuesLoader.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/SourceBranchComponentUuids.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/TargetBranchComponentUuids.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/period/NewCodeReferenceBranchComponentUuids.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/BuildComponentTreeStep.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistComponentsStep.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/ValidateProjectStep.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/analysis/ProjectConfigurationFactoryTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/ComponentUuidFactoryWithMigrationTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/ConfigurationRepositoryTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/SiblingsIssueMergerTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/PersistComponentsStepTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ReportPersistComponentsStepTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ValidateProjectStepTest.java
server/sonar-ce/src/main/java/org/sonar/ce/notification/ReportAnalysisFailureNotificationExecutionListener.java
server/sonar-ce/src/test/java/org/sonar/ce/notification/ReportAnalysisFailureNotificationExecutionListenerTest.java
server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDao.java
server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDto.java
server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java
server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterMapper.java
server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentMapper.java
server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesDao.java
server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java
server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java
server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentKeyUpdaterMapper.xml
server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml
server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml
server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentDaoTest.java
server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentKeyUpdaterDaoTest.java
server/sonar-db-dao/src/test/java/org/sonar/db/property/PropertiesDaoTest.java
server/sonar-db-dao/src/testFixtures/java/org/sonar/db/component/ComponentDbTester.java
server/sonar-db-dao/src/testFixtures/java/org/sonar/db/property/PropertyDbTester.java
server/sonar-server-common/src/main/java/org/sonar/server/setting/ProjectConfigurationLoader.java
server/sonar-server-common/src/main/java/org/sonar/server/setting/ProjectConfigurationLoaderImpl.java
server/sonar-server-common/src/test/java/org/sonar/server/setting/ProjectConfigurationLoaderImplTest.java
server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/batch/IssuesAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ComponentFinder.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/ShowAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/SuggestionsAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/TreeAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/developers/ws/SearchEventsAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/duplication/ws/DuplicationsParser.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/duplication/ws/ShowResponseBuilder.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/SearchAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchResponseData.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchResponseFormat.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchResponseLoader.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeData.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/setting/ws/ValuesAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/ui/ws/ComponentAction.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ComponentFinderTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ComponentUpdaterTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ws/TreeActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/duplication/ws/DuplicationsParserTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/duplication/ws/ShowActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/favorite/ws/RemoveActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/hotspot/ws/SearchActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/SearchActionComponentsTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/SearchActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/SearchResponseFormatFormatOperationTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/measure/ws/ComponentTreeActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/setting/TestProjectConfigurationLoader.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/setting/ws/SetActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/setting/ws/ValuesActionTest.java

index 4d65f85396515eb2053c8a3b4cc34375a5b60611..abb3952be3a3700599e1e4cb079243fcf606e203 100644 (file)
@@ -37,17 +37,18 @@ public class ProjectConfigurationFactory {
     this.dbClient = dbClient;
   }
 
-  public Configuration newProjectConfiguration(String projectKey, Branch branch) {
+  public Configuration newProjectConfiguration(String projectUuid, String branchUuid) {
     Settings projectSettings = new ChildSettings(globalSettings);
-    addSettings(projectSettings, projectKey);
-    // TODO branch / PR
-    addSettings(projectSettings, projectKey);
+    addSettings(projectSettings, projectUuid);
+    if (!projectUuid.equals(branchUuid)) {
+      addSettings(projectSettings, branchUuid);
+    }
     return new ConfigurationBridge(projectSettings);
   }
 
-  private void addSettings(Settings settings, String componentDbKey) {
+  private void addSettings(Settings settings, String componentUuid) {
     dbClient.propertiesDao()
-      .selectProjectProperties(componentDbKey)
+      .selectComponentProperties(componentUuid)
       .forEach(property -> settings.setProperty(property.getKey(), property.getValue()));
   }
 }
index 31b044c65e47ecafd8303b1b25f88bfd5830b868..26e3fd4feb001a285049f13a6039fb17e2459ee7 100644 (file)
@@ -22,9 +22,11 @@ package org.sonar.ce.task.projectanalysis.component;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import org.sonar.ce.task.projectanalysis.analysis.Branch;
 import org.sonar.core.util.Uuids;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
+import org.sonar.db.component.BranchType;
 import org.sonar.db.component.KeyWithUuidDto;
 
 public class ComponentUuidFactoryImpl implements ComponentUuidFactory {
@@ -35,6 +37,18 @@ public class ComponentUuidFactoryImpl implements ComponentUuidFactory {
     keys.forEach(dto -> uuidsByKey.put(dto.key(), dto.uuid()));
   }
 
+  public ComponentUuidFactoryImpl(DbClient dbClient, DbSession dbSession, String rootKey, Branch branch) {
+    List<KeyWithUuidDto> keys;
+    if (branch.isMain()) {
+      keys = dbClient.componentDao().selectUuidsByKeyFromProjectKey(dbSession, rootKey);
+    } else if (branch.getType() == BranchType.PULL_REQUEST) {
+      keys = dbClient.componentDao().selectUuidsByKeyFromProjectKeyAndPullRequest(dbSession, rootKey, branch.getPullRequestKey());
+    } else {
+      keys = dbClient.componentDao().selectUuidsByKeyFromProjectKeyAndBranch(dbSession, rootKey, branch.getName());
+    }
+    keys.forEach(dto -> uuidsByKey.put(dto.key(), dto.uuid()));
+  }
+
   /**
    * Get UUID from database if it exists, otherwise generate a new one.
    */
index 894853ba7c6b19594fd366908fd2501970e1c02c..c8b963690d74d4e7310c71f7483975217d8bb4dd 100644 (file)
@@ -30,9 +30,11 @@ import javax.annotation.Nullable;
 import org.apache.commons.lang.StringUtils;
 import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.resources.Scopes;
+import org.sonar.ce.task.projectanalysis.analysis.Branch;
 import org.sonar.core.util.Uuids;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
+import org.sonar.db.component.BranchType;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.component.ComponentWithModuleUuidDto;
 import org.sonar.db.component.KeyWithUuidDto;
@@ -41,13 +43,22 @@ public class ComponentUuidFactoryWithMigration implements ComponentUuidFactory {
   private final Map<String, String> uuidsByDbKey = new HashMap<>();
   private final Map<String, String> uuidsByMigratedKey = new HashMap<>();
 
-  public ComponentUuidFactoryWithMigration(DbClient dbClient, DbSession dbSession, String rootKey, Function<String, String> pathToKey, Map<String, String> reportModulesPath) {
+  public ComponentUuidFactoryWithMigration(DbClient dbClient, DbSession dbSession, String rootKey, Branch branch,
+    Function<String, String> pathToKey, Map<String, String> reportModulesPath) {
     Map<String, String> modulePathsByUuid;
-    List<KeyWithUuidDto> keys = dbClient.componentDao().selectUuidsByKeyFromProjectKey(dbSession, rootKey);
+    List<KeyWithUuidDto> keys;
+    if (branch.isMain()) {
+      keys = dbClient.componentDao().selectUuidsByKeyFromProjectKey(dbSession, rootKey);
+    } else if (branch.getType() == BranchType.PULL_REQUEST) {
+      keys = dbClient.componentDao().selectUuidsByKeyFromProjectKeyAndPullRequest(dbSession, rootKey, branch.getPullRequestKey());
+    } else {
+      keys = dbClient.componentDao().selectUuidsByKeyFromProjectKeyAndBranch(dbSession, rootKey, branch.getName());
+    }
+
     keys.forEach(dto -> uuidsByDbKey.put(dto.key(), dto.uuid()));
 
     if (!reportModulesPath.isEmpty()) {
-      modulePathsByUuid = loadModulePathsByUuid(dbClient, dbSession, rootKey, reportModulesPath);
+      modulePathsByUuid = loadModulePathsByUuid(dbClient, dbSession, rootKey, branch, reportModulesPath);
 
       if (!modulePathsByUuid.isEmpty()) {
         doMigration(dbClient, dbSession, rootKey, pathToKey, modulePathsByUuid);
@@ -96,9 +107,13 @@ public class ComponentUuidFactoryWithMigration implements ComponentUuidFactory {
     return dbClient.componentDao().selectEnabledComponentsWithModuleUuidFromProjectKey(dbSession, rootKey);
   }
 
-  private static Map<String, String> loadModulePathsByUuid(DbClient dbClient, DbSession dbSession, String rootKey, Map<String, String> pathByModuleKey) {
+  private static Map<String, String> loadModulePathsByUuid(DbClient dbClient, DbSession dbSession, String rootKey,
+    Branch branch, Map<String, String> pathByModuleKey) {
+    String branchKey = branch.getType() == BranchType.BRANCH ? branch.getName() : null;
+    String prKey = branch.getType() == BranchType.PULL_REQUEST ? branch.getPullRequestKey() : null;
+
     List<ComponentDto> moduleDtos = dbClient.componentDao()
-      .selectProjectAndModulesFromProjectKey(dbSession, rootKey, true).stream()
+      .selectProjectAndModulesFromProjectKey(dbSession, rootKey, true, branchKey, prKey).stream()
       .filter(c -> Qualifiers.MODULE.equals(c.qualifier()))
       .collect(Collectors.toList());
 
index 04970136a940e332a1c6704775cd9dbb1d463951..02aba3d59feb973929075def3cbbda3dc3500d1a 100644 (file)
@@ -32,8 +32,10 @@ public class ConfigurationRepositoryImpl implements ConfigurationRepository {
 
   private final Supplier<Configuration> configuration;
 
-  public ConfigurationRepositoryImpl(AnalysisMetadataHolder analysisMetadataHolder, ProjectConfigurationFactory f) {
-    this.configuration = Suppliers.memoize(() -> f.newProjectConfiguration(analysisMetadataHolder.getProject().getKey(), analysisMetadataHolder.getBranch()));
+  public ConfigurationRepositoryImpl(TreeRootHolder treeRootHolder, AnalysisMetadataHolder analysisMetadataHolder, ProjectConfigurationFactory f) {
+    String branchUuid = treeRootHolder.getRoot().getUuid();
+    String projectUuid = analysisMetadataHolder.getProject().getUuid();
+    this.configuration = Suppliers.memoize(() -> f.newProjectConfiguration(projectUuid, branchUuid));
   }
 
   @Override
index f77a898e369885e4c21c85fcaa47a4fd62543917..099fbcd4e19bfbd77a9ac1974c27fe3706c619e2 100644 (file)
@@ -31,7 +31,6 @@ import org.sonar.db.component.BranchDto;
 import org.sonar.db.component.ComponentDto;
 
 import static com.google.common.base.Preconditions.checkState;
-import static org.sonar.db.component.ComponentDto.removeBranchAndPullRequestFromKey;
 
 /**
  * Cache a map between component keys and uuids in the reference branch
@@ -87,9 +86,8 @@ public class ReferenceBranchComponentUuids {
   }
 
   @CheckForNull
-  public String getComponentUuid(String dbKey) {
+  public String getComponentUuid(String key) {
     lazyInit();
-    String cleanComponentKey = removeBranchAndPullRequestFromKey(dbKey);
-    return referenceBranchComponentsUuidsByKey.get(cleanComponentKey);
+    return referenceBranchComponentsUuidsByKey.get(key);
   }
 }
index ffa537805b2c468c8f98a0974b0d4b5baf5bfa4a..1bd2e4499a13aab4a3e1041a420220d085df55e2 100644 (file)
@@ -30,8 +30,6 @@ import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.component.KeyWithUuidDto;
 
-import static org.sonar.db.component.ComponentDto.removeBranchAndPullRequestFromKey;
-
 /**
  * Cache a map of component key -> set&lt;uuid&gt; in:
  * - sibling PRs that have open issues
index ea027852f8380bb0705d2946ef4b9e235c5a24bf..06c825707e91421168877d72382e8bb9d9ae7c16 100644 (file)
@@ -72,7 +72,11 @@ class ProjectTrackerBaseLazyInput extends BaseInputFactory.BaseLazyInput {
       if (!dirOrModulesUuidsWithIssues.isEmpty()) {
         Map<String, String> pathByModuleKey = reportModulesPath.get();
         // Migrate issues that were previously on modules or directories to the root project
-        Map<String, ComponentDto> modulesByUuid = dbClient.componentDao().selectProjectAndModulesFromProjectKey(dbSession, component.getKey(), true)
+        String branchKey = analysisMetadataHolder.isBranch() ? analysisMetadataHolder.getBranch().getName() : null;
+        String prKey = analysisMetadataHolder.isPullRequest() ? analysisMetadataHolder.getBranch().getPullRequestKey() : null;
+
+        Map<String, ComponentDto> modulesByUuid = dbClient.componentDao()
+          .selectProjectAndModulesFromProjectKey(dbSession, component.getKey(), true, branchKey, prKey)
           .stream().collect(Collectors.toMap(ComponentDto::uuid, Function.identity()));
         List<ComponentDto> dirOrModulesWithIssues = dbClient.componentDao().selectByUuids(dbSession, dirOrModulesUuidsWithIssues);
         dirOrModulesWithIssues.forEach(c -> {
index 60c94d1f999a764bfded4bf11fb12ee997a9c67d..661820926b3502eaf561c2139694c406504a9052 100644 (file)
@@ -30,7 +30,6 @@ import org.sonar.ce.task.projectanalysis.component.SiblingComponentsWithOpenIssu
 import org.sonar.core.issue.DefaultIssue;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
-import org.sonar.db.component.ComponentDto;
 import org.sonar.db.issue.IssueDto;
 import org.sonar.db.issue.PrIssueDto;
 
@@ -52,8 +51,7 @@ public class SiblingsIssuesLoader {
   }
 
   public Collection<SiblingIssue> loadCandidateSiblingIssuesForMerging(Component component) {
-    String componentKey = ComponentDto.removeBranchAndPullRequestFromKey(component.getKey());
-    Set<String> uuids = siblingComponentsWithOpenIssues.getUuids(componentKey);
+    Set<String> uuids = siblingComponentsWithOpenIssues.getUuids(component.getKey());
     if (uuids.isEmpty()) {
       return Collections.emptyList();
     }
index 409c8204d4803cd188ef8918acb0252f2314d5ad..bca0a4af370bdbba3c21a1f3534e121c4d63f0e8 100644 (file)
@@ -30,8 +30,6 @@ import org.sonar.db.DbSession;
 import org.sonar.db.component.BranchDto;
 import org.sonar.db.component.ComponentDto;
 
-import static org.sonar.db.component.ComponentDto.removeBranchAndPullRequestFromKey;
-
 /**
  * Cache a map between component keys and uuids in the source branch of a pull request
  */
@@ -79,9 +77,8 @@ public class SourceBranchComponentUuids {
   }
 
   @CheckForNull
-  public String getSourceBranchComponentUuid(String dbKey) {
+  public String getSourceBranchComponentUuid(String key) {
     lazyInit();
-    String cleanComponentKey = removeBranchAndPullRequestFromKey(dbKey);
-    return sourceBranchComponentsUuidsByKey.get(cleanComponentKey);
+    return sourceBranchComponentsUuidsByKey.get(key);
   }
 }
index 725cf52f6da46a3e080aac2e73ebc816e353806a..40ffea79fe2956e7615e893ab366a4b2c73762f3 100644 (file)
@@ -30,8 +30,6 @@ import org.sonar.db.DbSession;
 import org.sonar.db.component.BranchDto;
 import org.sonar.db.component.ComponentDto;
 
-import static org.sonar.db.component.ComponentDto.removeBranchAndPullRequestFromKey;
-
 /**
  * Cache a map between component keys and uuids in the merge branch and optionally the target branch (for PR and SLB, and only if this target branch is analyzed)
  */
index c45a933d1d32b61e2dde1fe82bc77b558e89e3c3..5833d847ea21d017052b27cf77e7a6cb1ea89b1b 100644 (file)
@@ -32,8 +32,6 @@ import org.sonar.db.component.BranchDto;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.newcodeperiod.NewCodePeriodType;
 
-import static org.sonar.db.component.ComponentDto.removeBranchAndPullRequestFromKey;
-
 /**
  * Cache a map between component keys and uuids in the reference branch
  */
@@ -76,9 +74,8 @@ public class NewCodeReferenceBranchComponentUuids {
   }
 
   @CheckForNull
-  public String getComponentUuid(String dbKey) {
+  public String getComponentUuid(String key) {
     lazyInit();
-    String cleanComponentKey = removeBranchAndPullRequestFromKey(dbKey);
-    return referenceBranchComponentsUuidsByKey.get(cleanComponentKey);
+    return referenceBranchComponentsUuidsByKey.get(key);
   }
 }
index 6607b973a75a0ed8826f29f76e0291cfd223218b..e27cb71510deee370c0aa20f8c2a178eb4b72a05 100644 (file)
@@ -79,7 +79,8 @@ public class BuildComponentTreeStep implements ComputationStep {
       String rootKey = keyGenerator.generateKey(reportProject.getKey(), null);
       Function<String, String> pathToKey = path -> keyGenerator.generateKey(reportProject.getKey(), path);
       // loads the UUIDs from database. If they don't exist, then generate new ones
-      ComponentUuidFactoryWithMigration componentUuidFactoryWithMigration = new ComponentUuidFactoryWithMigration(dbClient, dbSession, rootKey, pathToKey, reportModulesPath.get());
+      ComponentUuidFactoryWithMigration componentUuidFactoryWithMigration =
+        new ComponentUuidFactoryWithMigration(dbClient, dbSession, rootKey, analysisMetadataHolder.getBranch(), pathToKey, reportModulesPath.get());
 
       String rootUuid = componentUuidFactoryWithMigration.getOrCreateForKey(rootKey);
       Optional<SnapshotDto> baseAnalysis = dbClient.snapshotDao().selectLastAnalysisByRootComponentUuid(dbSession, rootUuid);
index 16adb079fbdae2273777bec29f4d7e56c933cbbd..28ff34d9775cfaa9b299a1b14475eb17e1bc1269 100644 (file)
@@ -149,7 +149,7 @@ public class PersistComponentsStep implements ComputationStep {
    * disabled components.
    */
   private Map<String, ComponentDto> indexExistingDtosByUuids(DbSession session) {
-    return dbClient.componentDao().selectAllComponentsFromProjectKey(session, treeRootHolder.getRoot().getKey())
+    return dbClient.componentDao().selectByBranchUuid(treeRootHolder.getRoot().getUuid(), session)
       .stream()
       .collect(Collectors.toMap(ComponentDto::uuid, Function.identity()));
   }
index 52716dd4e90307f3a666a79a423ec2c806113f2a..ac1a139afc5ca5406b50e74b2fd10ec447743607 100644 (file)
@@ -67,7 +67,9 @@ public class ValidateProjectStep implements ComputationStep {
       validateTargetBranch(dbSession);
       Component root = treeRootHolder.getRoot();
       // FIXME if module have really be dropped, no more need to load them
-      List<ComponentDto> baseModules = dbClient.componentDao().selectEnabledModulesFromProjectKey(dbSession, root.getKey());
+      String branchKey = analysisMetadataHolder.isBranch() ? analysisMetadataHolder.getBranch().getName() : null;
+      String prKey = analysisMetadataHolder.isPullRequest() ? analysisMetadataHolder.getBranch().getPullRequestKey() : null;
+      List<ComponentDto> baseModules = dbClient.componentDao().selectEnabledModulesFromProjectKey(dbSession, root.getKey(), branchKey, prKey);
       Map<String, ComponentDto> baseModulesByKey = baseModules.stream().collect(Collectors.toMap(ComponentDto::getKey, x -> x));
       ValidateProjectsVisitor visitor = new ValidateProjectsVisitor(dbSession, dbClient.componentDao(), baseModulesByKey);
       new DepthTraversalTypeAwareCrawler(visitor).visit(root);
@@ -134,7 +136,7 @@ public class ValidateProjectStep implements ComputationStep {
       Long lastAnalysisDate = snapshotDto.map(SnapshotDto::getCreatedAt).orElse(null);
       if (lastAnalysisDate != null && currentAnalysisDate <= lastAnalysisDate) {
         validationMessages.add(format("Date of analysis cannot be older than the date of the last known analysis on this project. Value: \"%s\". " +
-          "Latest analysis: \"%s\". It's only possible to rebuild the past in a chronological order.",
+            "Latest analysis: \"%s\". It's only possible to rebuild the past in a chronological order.",
           formatDateTime(new Date(currentAnalysisDate)), formatDateTime(new Date(lastAnalysisDate))));
       }
     }
@@ -143,7 +145,11 @@ public class ValidateProjectStep implements ComputationStep {
       ComponentDto baseComponent = baseModulesByKey.get(rawComponentKey);
       if (baseComponent == null) {
         // Load component from key to be able to detect issue (try to analyze a module, etc.)
-        return componentDao.selectByKey(session, rawComponentKey);
+        if (analysisMetadataHolder.isBranch()) {
+          return componentDao.selectByKeyAndBranch(session, rawComponentKey, analysisMetadataHolder.getBranch().getName());
+        } else {
+          return componentDao.selectByKeyAndPullRequest(session, rawComponentKey, analysisMetadataHolder.getBranch().getPullRequestKey());
+        }
       }
       return Optional.of(baseComponent);
     }
index f6c512561db72e77e19864309187c3a76cd4520a..69011ec0095ed29d325fc455f662d8dd08629fba 100644 (file)
@@ -31,20 +31,16 @@ import static org.assertj.core.api.Assertions.assertThat;
 import static org.sonar.db.property.PropertyTesting.newComponentPropertyDto;
 
 public class ProjectConfigurationFactoryTest {
-
-  private static final String PROJECT_KEY = "PROJECT_KEY";
-
   @Rule
   public DbTester db = DbTester.create();
 
   private MapSettings settings = new MapSettings();
-
   private ProjectConfigurationFactory underTest = new ProjectConfigurationFactory(settings, db.getDbClient());
 
   @Test
   public void return_global_settings() {
     settings.setProperty("key", "value");
-    Configuration config = underTest.newProjectConfiguration(PROJECT_KEY, new DefaultBranchImpl());
+    Configuration config = underTest.newProjectConfiguration("unknown", "unknown");
 
     assertThat(config.get("key")).hasValue("value");
   }
@@ -57,7 +53,7 @@ public class ProjectConfigurationFactoryTest {
       newComponentPropertyDto(project).setKey("2").setValue("val2"),
       newComponentPropertyDto(project).setKey("3").setValue("val3"));
 
-    Configuration config = underTest.newProjectConfiguration(project.getKey(), new DefaultBranchImpl());
+    Configuration config = underTest.newProjectConfiguration(project.uuid(), project.uuid());
 
     assertThat(config.get("1")).hasValue("val1");
     assertThat(config.get("2")).hasValue("val2");
@@ -71,7 +67,7 @@ public class ProjectConfigurationFactoryTest {
     db.properties().insertProperties(null, project.getKey(), project.name(), project.qualifier(),
       newComponentPropertyDto(project).setKey("key").setValue("value2"));
 
-    Configuration projectConfig = underTest.newProjectConfiguration(project.getKey(), new DefaultBranchImpl());
+    Configuration projectConfig = underTest.newProjectConfiguration(project.uuid(), project.uuid());
 
     assertThat(projectConfig.get("key")).hasValue("value2");
   }
index 230d04ee3d359903598d73bf4870355e438d1d3b..7f3839bab0f07ed53ab1902e3a39b35f95130d29 100644 (file)
@@ -26,6 +26,7 @@ import java.util.function.Function;
 import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.utils.System2;
+import org.sonar.ce.task.projectanalysis.analysis.Branch;
 import org.sonar.db.DbTester;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.component.ComponentTesting;
@@ -33,7 +34,7 @@ import org.sonar.db.component.ComponentTesting;
 import static org.assertj.core.api.Assertions.assertThat;
 
 public class ComponentUuidFactoryWithMigrationTest {
-
+  private final Branch mainBranch = new DefaultBranchImpl();
   @Rule
   public DbTester db = DbTester.create(System2.INSTANCE);
   private Function<String, String> pathToKey = path -> path != null ? "project:" + path : "project";
@@ -45,7 +46,8 @@ public class ComponentUuidFactoryWithMigrationTest {
     Map<String, String> reportModulesPath = Collections.singletonMap(module.getKey(), "module1_path");
     pathToKey = path -> path != null ? project.getKey() + ":" + path : project.getKey();
 
-    ComponentUuidFactoryWithMigration underTest = new ComponentUuidFactoryWithMigration(db.getDbClient(), db.getSession(), project.getKey(), pathToKey, reportModulesPath);
+    ComponentUuidFactoryWithMigration underTest =
+      new ComponentUuidFactoryWithMigration(db.getDbClient(), db.getSession(), project.getKey(), mainBranch, pathToKey, reportModulesPath);
 
     assertThat(underTest.getOrCreateForKey(project.getKey())).isEqualTo(project.uuid());
     assertThat(underTest.getOrCreateForKey(module.getKey())).isEqualTo(module.uuid());
@@ -69,7 +71,8 @@ public class ComponentUuidFactoryWithMigrationTest {
     Map<String, String> modulesRelativePaths = new HashMap<>();
     modulesRelativePaths.put("project:module1", "module1_path");
     modulesRelativePaths.put("project:module1:module2", "module1_path/module2_path");
-    ComponentUuidFactoryWithMigration underTest = new ComponentUuidFactoryWithMigration(db.getDbClient(), db.getSession(), project.getKey(), pathToKey, modulesRelativePaths);
+    ComponentUuidFactoryWithMigration underTest =
+      new ComponentUuidFactoryWithMigration(db.getDbClient(), db.getSession(), project.getKey(), mainBranch, pathToKey, modulesRelativePaths);
 
     // migrated files
     assertThat(underTest.getOrCreateForKey("project:file1_path")).isEqualTo(file1.uuid());
@@ -94,7 +97,8 @@ public class ComponentUuidFactoryWithMigrationTest {
 
     Map<String, String> modulesRelativePaths = new HashMap<>();
     modulesRelativePaths.put("project:module1", "module1_path");
-    ComponentUuidFactoryWithMigration underTest = new ComponentUuidFactoryWithMigration(db.getDbClient(), db.getSession(), project.getKey(), pathToKey, modulesRelativePaths);
+    ComponentUuidFactoryWithMigration underTest =
+      new ComponentUuidFactoryWithMigration(db.getDbClient(), db.getSession(), project.getKey(), mainBranch, pathToKey, modulesRelativePaths);
 
     // migrated files
     assertThat(underTest.getOrCreateForKey("project:file1")).isEqualTo(file1.uuid());
@@ -118,7 +122,8 @@ public class ComponentUuidFactoryWithMigrationTest {
 
     Map<String, String> modulesRelativePaths = new HashMap<>();
     modulesRelativePaths.put("project:module1", "module1_path");
-    ComponentUuidFactoryWithMigration underTest = new ComponentUuidFactoryWithMigration(db.getDbClient(), db.getSession(), project.getKey(), pathToKey, modulesRelativePaths);
+    ComponentUuidFactoryWithMigration underTest =
+      new ComponentUuidFactoryWithMigration(db.getDbClient(), db.getSession(), project.getKey(), mainBranch, pathToKey, modulesRelativePaths);
 
     // migrated files
     assertThat(underTest.getOrCreateForKey("project:file1")).isEqualTo(file1.uuid());
@@ -142,7 +147,8 @@ public class ComponentUuidFactoryWithMigrationTest {
 
     Map<String, String> modulesRelativePaths = new HashMap<>();
     modulesRelativePaths.put("project:module1", "module1_path");
-    ComponentUuidFactoryWithMigration underTest = new ComponentUuidFactoryWithMigration(db.getDbClient(), db.getSession(), project.getKey(), pathToKey, modulesRelativePaths);
+    ComponentUuidFactoryWithMigration underTest =
+      new ComponentUuidFactoryWithMigration(db.getDbClient(), db.getSession(), project.getKey(), mainBranch, pathToKey, modulesRelativePaths);
 
     // in theory we should migrate file1. But since disabledFileSameKey already have the expected migrated key, let's reuse it.
     assertThat(underTest.getOrCreateForKey("project:module1/file1")).isEqualTo(disabledFileSameKey.uuid());
@@ -170,7 +176,8 @@ public class ComponentUuidFactoryWithMigrationTest {
     Map<String, String> modulesRelativePaths = new HashMap<>();
     modulesRelativePaths.put("project:module1", "module1_path");
     modulesRelativePaths.put("project:module1:module2", "module1_path/module2_path");
-    ComponentUuidFactoryWithMigration underTest = new ComponentUuidFactoryWithMigration(db.getDbClient(), db.getSession(), project.getKey(), pathToKey, modulesRelativePaths);
+    ComponentUuidFactoryWithMigration underTest =
+      new ComponentUuidFactoryWithMigration(db.getDbClient(), db.getSession(), project.getKey(), mainBranch, pathToKey, modulesRelativePaths);
 
     // migrated files
     assertThat(underTest.getOrCreateForKey("project:file1_path")).isEqualTo(file1.uuid());
@@ -189,7 +196,8 @@ public class ComponentUuidFactoryWithMigrationTest {
       .setKey("project:module1:/"));
 
     Map<String, String> modulesRelativePaths = Collections.singletonMap("project:module1", "module1_path");
-    ComponentUuidFactoryWithMigration underTest = new ComponentUuidFactoryWithMigration(db.getDbClient(), db.getSession(), project.getKey(), pathToKey, modulesRelativePaths);
+    ComponentUuidFactoryWithMigration underTest =
+      new ComponentUuidFactoryWithMigration(db.getDbClient(), db.getSession(), project.getKey(), mainBranch, pathToKey, modulesRelativePaths);
 
     // project remains the same
     assertThat(underTest.getOrCreateForKey(project.getKey())).isEqualTo(project.uuid());
@@ -210,7 +218,8 @@ public class ComponentUuidFactoryWithMigrationTest {
     Map<String, String> modulesRelativePaths = new HashMap<>();
     modulesRelativePaths.put("project", "");
     modulesRelativePaths.put("project:module2", "module2");
-    ComponentUuidFactoryWithMigration underTest = new ComponentUuidFactoryWithMigration(db.getDbClient(), db.getSession(), project.getKey(), pathToKey, modulesRelativePaths);
+    ComponentUuidFactoryWithMigration underTest =
+      new ComponentUuidFactoryWithMigration(db.getDbClient(), db.getSession(), project.getKey(), mainBranch, pathToKey, modulesRelativePaths);
 
     // check root project.
     assertThat(underTest.getOrCreateForKey("project")).isEqualTo(project.uuid());
@@ -218,7 +227,8 @@ public class ComponentUuidFactoryWithMigrationTest {
 
   @Test
   public void generate_uuid_if_it_does_not_exist_in_db() {
-    ComponentUuidFactoryWithMigration underTest = new ComponentUuidFactoryWithMigration(db.getDbClient(), db.getSession(), "theProjectKey", pathToKey, Collections.emptyMap());
+    ComponentUuidFactoryWithMigration underTest =
+      new ComponentUuidFactoryWithMigration(db.getDbClient(), db.getSession(), "theProjectKey", mainBranch, pathToKey, Collections.emptyMap());
 
     String generatedKey = underTest.getOrCreateForKey("foo");
     assertThat(generatedKey).isNotEmpty();
index 072eec8a5ba97fc9b224def05974ebc6f7eeb63a..a7e43c2b8130c9275a713acc73de8bf263330ba7 100644 (file)
@@ -41,28 +41,30 @@ import static org.mockito.Mockito.when;
 import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
 
 public class ConfigurationRepositoryTest {
-
-  private static Project PROJECT = Project.from(newPrivateProjectDto());
-
   @Rule
   public final DbTester db = DbTester.create(System2.INSTANCE);
+  @Rule
+  public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
+  @Rule
+  public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule();
 
-  private DbClient dbClient = db.getDbClient();
-  private MapSettings globalSettings = new MapSettings();
-  private Branch branch = mock(Branch.class);
-  private AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule();
+  private final DbClient dbClient = db.getDbClient();
+  private final MapSettings globalSettings = new MapSettings();
+  private final Project project = Project.from(newPrivateProjectDto());
+  private final Component root = mock(Component.class);
   private ConfigurationRepository underTest;
 
+
   @Before
   public void setUp() {
-    when(branch.getName()).thenReturn("branchName");
-    analysisMetadataHolder.setBranch(branch);
-    underTest = new ConfigurationRepositoryImpl(analysisMetadataHolder, new ProjectConfigurationFactory(globalSettings, dbClient));
+    analysisMetadataHolder.setProject(project);
+    when(root.getUuid()).thenReturn(project.getUuid());
+    treeRootHolder.setRoot(root);
+    underTest = new ConfigurationRepositoryImpl(treeRootHolder, analysisMetadataHolder, new ProjectConfigurationFactory(globalSettings, dbClient));
   }
 
   @Test
   public void get_project_settings_from_global_settings() {
-    analysisMetadataHolder.setProject(PROJECT);
     globalSettings.setProperty("key", "value");
 
     Configuration config = underTest.getConfiguration();
@@ -72,9 +74,7 @@ public class ConfigurationRepositoryTest {
 
   @Test
   public void get_project_settings_from_db() {
-    ComponentDto project = db.components().insertPrivateProject();
-    analysisMetadataHolder.setProject(Project.from(project));
-    insertProjectProperty(project, "key", "value");
+    insertComponentProperty(project.getUuid(), "key", "value");
 
     Configuration config = underTest.getConfiguration();
 
@@ -83,7 +83,6 @@ public class ConfigurationRepositoryTest {
 
   @Test
   public void call_twice_get_project_settings() {
-    analysisMetadataHolder.setProject(PROJECT);
     globalSettings.setProperty("key", "value");
 
     Configuration config = underTest.getConfiguration();
@@ -96,9 +95,7 @@ public class ConfigurationRepositoryTest {
   @Test
   public void project_settings_override_global_settings() {
     globalSettings.setProperty("key", "value1");
-    ComponentDto project = db.components().insertPrivateProject();
-    insertProjectProperty(project, "key", "value2");
-    analysisMetadataHolder.setProject(Project.from(project));
+    insertComponentProperty(project.getUuid(), "key", "value2");
 
     Configuration config = underTest.getConfiguration();
     assertThat(config.get("key")).hasValue("value2");
@@ -106,9 +103,7 @@ public class ConfigurationRepositoryTest {
 
   @Test
   public void project_settings_are_cached_to_avoid_db_access() {
-    ComponentDto project = db.components().insertPrivateProject();
-    insertProjectProperty(project, "key", "value");
-    analysisMetadataHolder.setProject(Project.from(project));
+    insertComponentProperty(project.getUuid(), "key", "value");
 
     Configuration config = underTest.getConfiguration();
     assertThat(config.get("key")).hasValue("value");
@@ -121,17 +116,9 @@ public class ConfigurationRepositoryTest {
 
   @Test
   public void branch_settings() {
-    ComponentDto project = db.components().insertPublicProject();
-    String branchName = randomAlphanumeric(248);
-    ComponentDto branchDto = db.components().insertProjectBranch(project, b -> b.setKey(branchName));
-    Branch branch = mock(Branch.class);
-    when(branch.getName()).thenReturn(branchName);
-    analysisMetadataHolder
-      .setProject(Project.from(project))
-      .setBranch(branch);
     globalSettings.setProperty("global", "global value");
-    insertProjectProperty(project, "project", "project value");
-    insertProjectProperty(branchDto, "branch", "branch value");
+    insertComponentProperty(project.getUuid(), "project", "project value");
+    insertComponentProperty(root.getUuid(), "branch", "branch value");
 
     Configuration config = underTest.getConfiguration();
 
@@ -140,8 +127,8 @@ public class ConfigurationRepositoryTest {
     assertThat(config.get("branch")).hasValue("branch value");
   }
 
-  private void insertProjectProperty(ComponentDto project, String propertyKey, String propertyValue) {
-    db.properties().insertProperties(null, project.getKey(), project.name(), project.qualifier(),
-      new PropertyDto().setKey(propertyKey).setValue(propertyValue).setComponentUuid(project.uuid()));
+  private void insertComponentProperty(String componentUuid, String propertyKey, String propertyValue) {
+    db.properties().insertProperties(null, null, null, null,
+      new PropertyDto().setKey(propertyKey).setValue(propertyValue).setComponentUuid(componentUuid));
   }
 }
index ebd2a0573cf78838f8320597652aec3034ce481f..05ebd80be50bac84a2558ecde9c1a2006e330317 100644 (file)
@@ -115,9 +115,9 @@ public class SiblingsIssueMergerTest {
     branch3Dto = db.components().insertProjectBranch(projectDto, b -> b.setKey("myBranch3")
       .setBranchType(BranchType.PULL_REQUEST)
       .setMergeBranchUuid(projectDto.uuid()));
-    fileOnBranch1Dto = db.components().insertComponent(newFileDto(branch1Dto).setKey(FILE_1_KEY + ":PULL_REQUEST:myBranch1"));
-    fileOnBranch2Dto = db.components().insertComponent(newFileDto(branch2Dto).setKey(FILE_1_KEY + ":PULL_REQUEST:myBranch2"));
-    fileOnBranch3Dto = db.components().insertComponent(newFileDto(branch3Dto).setKey(FILE_1_KEY + ":PULL_REQUEST:myBranch3"));
+    fileOnBranch1Dto = db.components().insertComponent(newFileDto(branch1Dto).setKey(FILE_1_KEY));
+    fileOnBranch2Dto = db.components().insertComponent(newFileDto(branch2Dto).setKey(FILE_1_KEY));
+    fileOnBranch3Dto = db.components().insertComponent(newFileDto(branch3Dto).setKey(FILE_1_KEY));
     rule = db.rules().insert();
     when(branch.getReferenceBranchUuid()).thenReturn(projectDto.uuid());
     metadataHolder.setBranch(branch);
index b20ca1a60886c157a49aebaba1ecd788af06a665..fbce8cc4f18966b312664a1adfcbed7cda9e1123 100644 (file)
@@ -53,7 +53,7 @@ public class PersistComponentsStepTest {
     doReturn(component).when(treeRootHolder).getRoot();
     doReturn(projectKey).when(component).getKey();
     doReturn(componentDao).when(dbClient).componentDao();
-    doReturn(emptyList()).when(componentDao).selectAllComponentsFromProjectKey(any(DbSession.class), eq(projectKey));
+    doReturn(emptyList()).when(componentDao).selectByBranchUuid(eq(projectKey), any(DbSession.class));
 
     assertThatThrownBy(() -> {
       new PersistComponentsStep(
index 0f8bf052a3d05c8605a13133e881cf34662b879e..ec94c78144125706b4c56f7f77e0d51b79e1a61e 100644 (file)
@@ -184,7 +184,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest {
     assertThat(directoryDto.getUuidPath()).isEqualTo(UUID_PATH_SEPARATOR + branch.uuid() + UUID_PATH_SEPARATOR);
     assertThat(directoryDto.moduleUuid()).isEqualTo(branch.uuid());
     assertThat(directoryDto.moduleUuidPath()).isEqualTo(branch.moduleUuidPath());
-    assertThat(directoryDto.getMainBranchProjectUuid()).isEqualTo(branch.uuid());
+    assertThat(directoryDto.getMainBranchProjectUuid()).isEqualTo(analysisMetadataHolder.getProject().getUuid());
     assertThat(directoryDto.branchUuid()).isEqualTo(branch.uuid());
     assertThat(directoryDto.qualifier()).isEqualTo("DIR");
     assertThat(directoryDto.scope()).isEqualTo("DIR");
@@ -201,7 +201,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest {
     assertThat(fileDto.getUuidPath()).isEqualTo(directoryDto.getUuidPath() + directoryDto.uuid() + UUID_PATH_SEPARATOR);
     assertThat(fileDto.moduleUuid()).isEqualTo(branch.uuid());
     assertThat(fileDto.moduleUuidPath()).isEqualTo(branch.moduleUuidPath());
-    assertThat(fileDto.getMainBranchProjectUuid()).isEqualTo(branch.uuid());
+    assertThat(fileDto.getMainBranchProjectUuid()).isEqualTo(analysisMetadataHolder.getProject().getUuid());
     assertThat(fileDto.branchUuid()).isEqualTo(branch.uuid());
     assertThat(fileDto.qualifier()).isEqualTo("FIL");
     assertThat(fileDto.scope()).isEqualTo("FIL");
index 0e36782973a4f387b2c5dee3533c118ec6844f8c..fdc355dfe2ac90eef8cb795ecdf42fe069b2eab7 100644 (file)
@@ -80,8 +80,7 @@ public class ValidateProjectStepTest {
 
   @Test
   public void not_fail_if_analysis_date_is_after_last_analysis() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto("ABCD").setKey(PROJECT_KEY);
-    db.components().insertComponent(project);
+    ComponentDto project = db.components().insertPrivateProject("ABCD", c -> c.setKey(PROJECT_KEY));
     dbClient.snapshotDao().insert(db.getSession(), SnapshotTesting.newAnalysis(project).setCreatedAt(PAST_ANALYSIS_TIME));
     db.getSession().commit();
 
@@ -112,8 +111,7 @@ public class ValidateProjectStepTest {
   public void fail_if_analysis_date_is_before_last_analysis() {
     analysisMetadataHolder.setAnalysisDate(DateUtils.parseDate("2015-01-01"));
 
-    ComponentDto project = ComponentTesting.newPrivateProjectDto("ABCD").setKey(PROJECT_KEY);
-    db.components().insertComponent(project);
+    ComponentDto project = db.components().insertPrivateProject("ABCD", c -> c.setKey(PROJECT_KEY));
     dbClient.snapshotDao().insert(db.getSession(), SnapshotTesting.newAnalysis(project).setCreatedAt(1433131200000L)); // 2015-06-01
     db.getSession().commit();
 
index 942135a776ca805c20657666ce3af05edc40a1e0..aa62c8cf56ecef55664933f427e22554f3b90af8 100644 (file)
@@ -22,7 +22,6 @@ package org.sonar.ce.notification;
 import java.time.Duration;
 import javax.annotation.Nullable;
 import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.resources.Scopes;
 import org.sonar.api.utils.System2;
 import org.sonar.ce.task.CeTask;
 import org.sonar.ce.task.CeTaskResult;
@@ -37,6 +36,7 @@ import org.sonar.db.ce.CeActivityDto;
 import org.sonar.db.ce.CeTaskTypes;
 import org.sonar.db.component.BranchDto;
 import org.sonar.db.component.ComponentDto;
+import org.sonar.db.project.ProjectDto;
 import org.sonar.server.notification.NotificationService;
 
 import static com.google.common.base.Preconditions.checkArgument;
@@ -74,10 +74,11 @@ public class ReportAnalysisFailureNotificationExecutionListener implements CeWor
 
     if (notificationService.hasProjectSubscribersForTypes(projectUuid, singleton(ReportAnalysisFailureNotification.class))) {
       try (DbSession dbSession = dbClient.openSession(false)) {
-        ComponentDto projectDto = dbClient.componentDao().selectOrFailByUuid(dbSession, projectUuid);
-        BranchDto branchDto = dbClient.branchDao().selectByUuid(dbSession, projectDto.branchUuid())
-          .orElseThrow(() -> new IllegalStateException("Could not find a branch for component uuid " + projectDto.uuid()));
-        checkScopeAndQualifier(projectDto);
+        ProjectDto projectDto = dbClient.projectDao().selectByUuid(dbSession, projectUuid)
+          .orElseThrow(() -> new IllegalStateException("Could not find project uuid " + projectUuid));
+        BranchDto branchDto = dbClient.branchDao().selectByUuid(dbSession, projectDto.getUuid())
+          .orElseThrow(() -> new IllegalStateException("Could not find a branch for project uuid " + projectDto.getUuid()));
+        checkQualifier(projectDto);
         CeActivityDto ceActivityDto = dbClient.ceActivityDao().selectByUuid(dbSession, ceTask.getUuid())
           .orElseThrow(() -> new RowNotFoundException(format("CeActivity with uuid '%s' not found", ceTask.getUuid())));
         ReportAnalysisFailureNotificationBuilder taskFailureNotification = buildNotification(ceActivityDto, projectDto, branchDto, error);
@@ -93,23 +94,20 @@ public class ReportAnalysisFailureNotificationExecutionListener implements CeWor
   /**
    * @throws IllegalArgumentException if specified {@link ComponentDto} is not a project.
    */
-  private static void checkScopeAndQualifier(ComponentDto projectDto) {
-    String scope = projectDto.scope();
-    String qualifier = projectDto.qualifier();
-    checkArgument(
-      scope.equals(Scopes.PROJECT) && qualifier.equals(Qualifiers.PROJECT),
-      "Component %s must be a project (scope=%s, qualifier=%s)", projectDto.uuid(), scope, qualifier);
+  private static void checkQualifier(ProjectDto projectDto) {
+    String qualifier = projectDto.getQualifier();
+    checkArgument(qualifier.equals(Qualifiers.PROJECT), "Component %s must be a project (qualifier=%s)", projectDto.getUuid(), qualifier);
   }
 
-  private ReportAnalysisFailureNotificationBuilder buildNotification(CeActivityDto ceActivityDto, ComponentDto projectDto, BranchDto branchDto,
+  private ReportAnalysisFailureNotificationBuilder buildNotification(CeActivityDto ceActivityDto, ProjectDto projectDto, BranchDto branchDto,
     @Nullable Throwable error) {
     String projectBranch = branchDto.isMain() ? null : branchDto.getBranchKey();
     Long executedAt = ceActivityDto.getExecutedAt();
     return new ReportAnalysisFailureNotificationBuilder(
       new ReportAnalysisFailureNotificationBuilder.Project(
-        projectDto.uuid(),
+        projectDto.getUuid(),
         projectDto.getKey(),
-        projectDto.name(),
+        projectDto.getName(),
         projectBranch),
       new ReportAnalysisFailureNotificationBuilder.Task(
         ceActivityDto.getUuid(),
index c91133baf29e6116b6931ca72e12689bbcdf4670..da0c7e7cb7a096bdad461d8ceeb8ae6c1a43f6a1 100644 (file)
@@ -25,11 +25,11 @@ import java.util.Arrays;
 import java.util.Optional;
 import java.util.Random;
 import javax.annotation.Nullable;
-import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 import org.sonar.api.notifications.Notification;
+import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.utils.System2;
 import org.sonar.ce.task.CeTask;
 import org.sonar.ce.task.CeTaskResult;
@@ -44,6 +44,7 @@ import org.sonar.db.ce.CeQueueDto;
 import org.sonar.db.ce.CeTaskTypes;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.component.ComponentTesting;
+import org.sonar.db.project.ProjectDto;
 import org.sonar.server.notification.NotificationService;
 
 import static java.util.Collections.singleton;
@@ -57,7 +58,6 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoInteractions;
 import static org.mockito.Mockito.when;
-import static org.sonar.db.component.BranchDto.DEFAULT_MAIN_BRANCH_NAME;
 import static org.sonar.db.component.ComponentTesting.newDirectory;
 import static org.sonar.db.component.ComponentTesting.newModuleDto;
 
@@ -79,11 +79,6 @@ public class ReportAnalysisFailureNotificationExecutionListenerTest {
   private final ReportAnalysisFailureNotificationExecutionListener underTest = new ReportAnalysisFailureNotificationExecutionListener(
     notificationService, dbClient, serializer, system2);
 
-  @Before
-  public void setUp() {
-
-  }
-
   @Test
   public void onStart_has_no_effect() {
     CeTask mockedCeTask = mock(CeTask.class);
@@ -132,7 +127,7 @@ public class ReportAnalysisFailureNotificationExecutionListenerTest {
   }
 
   @Test
-  public void onEnd_fails_with_RowNotFoundException_if_component_does_not_exist_in_DB() {
+  public void onEnd_fails_with_ISE_if_project_does_not_exist_in_DB() {
     String componentUuid = randomAlphanumeric(6);
     when(ceTaskMock.getType()).thenReturn(CeTaskTypes.REPORT);
     when(ceTaskMock.getComponent()).thenReturn(Optional.of(new CeTask.Component(componentUuid, null, null)));
@@ -140,8 +135,24 @@ public class ReportAnalysisFailureNotificationExecutionListenerTest {
       .thenReturn(true);
 
     assertThatThrownBy(() -> underTest.onEnd(ceTaskMock, CeActivityDto.Status.FAILED, randomDuration(), ceTaskResultMock, throwableMock))
-      .isInstanceOf(RowNotFoundException.class)
-      .hasMessage("Component with uuid '" + componentUuid + "' not found");
+      .isInstanceOf(IllegalStateException.class)
+      .hasMessage("Could not find project uuid " + componentUuid);
+  }
+
+  @Test
+  public void onEnd_fails_with_ISE_if_branch_does_not_exist_in_DB() {
+    String componentUuid = randomAlphanumeric(6);
+    ProjectDto project = new ProjectDto().setUuid(componentUuid).setKey(randomAlphanumeric(5)).setQualifier(Qualifiers.PROJECT);
+    dbTester.getDbClient().projectDao().insert(dbTester.getSession(), project);
+    dbTester.getSession().commit();
+    when(ceTaskMock.getType()).thenReturn(CeTaskTypes.REPORT);
+    when(ceTaskMock.getComponent()).thenReturn(Optional.of(new CeTask.Component(componentUuid, null, null)));
+    when(notificationService.hasProjectSubscribersForTypes(componentUuid, singleton(ReportAnalysisFailureNotification.class)))
+      .thenReturn(true);
+
+    assertThatThrownBy(() -> underTest.onEnd(ceTaskMock, CeActivityDto.Status.FAILED, randomDuration(), ceTaskResultMock, throwableMock))
+      .isInstanceOf(IllegalStateException.class)
+      .hasMessage("Could not find a branch for project uuid " + componentUuid);
   }
 
   @Test
@@ -167,8 +178,9 @@ public class ReportAnalysisFailureNotificationExecutionListenerTest {
 
           fail("An IllegalArgumentException should have been thrown for component " + component);
         } catch (IllegalArgumentException e) {
-          assertThat(e.getMessage()).isEqualTo(String.format(
-            "Component %s must be a project (scope=%s, qualifier=%s)", component.uuid(), component.scope(), component.qualifier()));
+          assertThat(e.getMessage()).isEqualTo(String.format("Component %s must be a project (qualifier=%s)", component.uuid(), component.qualifier()));
+        } catch (IllegalStateException e) {
+          assertThat(e.getMessage()).isEqualTo("Could not find project uuid " + component.uuid());
         }
       });
   }
@@ -184,7 +196,7 @@ public class ReportAnalysisFailureNotificationExecutionListenerTest {
       .thenReturn(true);
     dbTester.components().insertPrivateProject(s -> s.setUuid(componentUuid));
 
-    assertThatThrownBy(() ->  underTest.onEnd(ceTaskMock, CeActivityDto.Status.FAILED, randomDuration(), ceTaskResultMock, throwableMock))
+    assertThatThrownBy(() -> underTest.onEnd(ceTaskMock, CeActivityDto.Status.FAILED, randomDuration(), ceTaskResultMock, throwableMock))
       .isInstanceOf(RowNotFoundException.class)
       .hasMessage("CeActivity with uuid '" + taskUuid + "' not found");
   }
@@ -208,7 +220,7 @@ public class ReportAnalysisFailureNotificationExecutionListenerTest {
     assertThat(notificationProject.getName()).isEqualTo(project.name());
     assertThat(notificationProject.getKey()).isEqualTo(project.getKey());
     assertThat(notificationProject.getUuid()).isEqualTo(project.uuid());
-    assertThat(notificationProject.getBranchName()).isEqualTo(DEFAULT_MAIN_BRANCH_NAME);
+    assertThat(notificationProject.getBranchName()).isNull();
     ReportAnalysisFailureNotificationBuilder.Task notificationTask = reportAnalysisFailureNotificationBuilder.getTask();
     assertThat(notificationTask.getUuid()).isEqualTo(taskUuid);
     assertThat(notificationTask.getCreatedAt()).isEqualTo(createdAt);
@@ -305,8 +317,8 @@ public class ReportAnalysisFailureNotificationExecutionListenerTest {
       .setTaskType(CeTaskTypes.REPORT)
       .setComponentUuid(project.uuid())
       .setCreatedAt(createdAt))
-        .setExecutedAt(executedAt)
-        .setStatus(CeActivityDto.Status.FAILED));
+      .setExecutedAt(executedAt)
+      .setStatus(CeActivityDto.Status.FAILED));
     dbTester.getSession().commit();
   }
 
index 56f6bae2fd14e9a4a82cc6c9de1441a6374ec8f8..687d4e574aa2d7832b0a2b384d687f5b055ed83a 100644 (file)
@@ -23,17 +23,14 @@ import com.google.common.collect.Ordering;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import javax.annotation.Nullable;
-import org.apache.commons.lang.StringUtils;
 import org.apache.ibatis.session.ResultHandler;
 import org.apache.ibatis.session.RowBounds;
 import org.sonar.api.resources.Qualifiers;
@@ -45,6 +42,7 @@ import org.sonar.db.audit.AuditPersister;
 import org.sonar.db.audit.model.ComponentNewValue;
 
 import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
 import static java.util.Collections.emptyList;
 import static org.sonar.db.DatabaseUtils.checkThatNotTooManyConditions;
 import static org.sonar.db.DatabaseUtils.executeLargeInputs;
@@ -58,26 +56,9 @@ public class ComponentDao implements Dao {
     this.auditPersister = auditPersister;
   }
 
-  private static List<ComponentDto> selectByQueryImpl(DbSession session, ComponentQuery query, int offset, int limit) {
-    if (query.hasEmptySetOfComponents()) {
-      return emptyList();
-    }
-    checkThatNotTooManyComponents(query);
-    return mapper(session).selectByQuery(query, new RowBounds(offset, limit));
-  }
-
-  private static int countByQueryImpl(DbSession session, ComponentQuery query) {
-    if (query.hasEmptySetOfComponents()) {
-      return 0;
-    }
-    checkThatNotTooManyComponents(query);
-    return mapper(session).countByQuery(query);
-  }
-
-  private static ComponentMapper mapper(DbSession session) {
-    return session.getMapper(ComponentMapper.class);
-  }
-
+  /*
+   * SELECT BY UUID
+   */
   public Optional<ComponentDto> selectByUuid(DbSession session, String uuid) {
     return Optional.ofNullable(mapper(session).selectByUuid(uuid));
   }
@@ -86,22 +67,12 @@ public class ComponentDao implements Dao {
     return selectByUuid(session, uuid).orElseThrow(() -> new RowNotFoundException(String.format("Component with uuid '%s' not found", uuid)));
   }
 
-  /**
-   * @throws IllegalArgumentException if parameter query#getComponentIds() has more than {@link org.sonar.db.DatabaseUtils#PARTITION_SIZE_FOR_ORACLE} values
-   * @throws IllegalArgumentException if parameter query#getComponentKeys() has more than {@link org.sonar.db.DatabaseUtils#PARTITION_SIZE_FOR_ORACLE} values
-   * @throws IllegalArgumentException if parameter query#getMainComponentUuids() has more than {@link org.sonar.db.DatabaseUtils#PARTITION_SIZE_FOR_ORACLE} values
-   */
-  public List<ComponentDto> selectByQuery(DbSession dbSession, ComponentQuery query, int offset, int limit) {
-    return selectByQueryImpl(dbSession, query, offset, limit);
+  public List<ComponentDto> selectByUuids(DbSession session, Collection<String> uuids) {
+    return executeLargeInputs(uuids, mapper(session)::selectByUuids);
   }
 
-  /**
-   * @throws IllegalArgumentException if parameter query#getComponentIds() has more than {@link org.sonar.db.DatabaseUtils#PARTITION_SIZE_FOR_ORACLE} values
-   * @throws IllegalArgumentException if parameter query#getComponentKeys() has more than {@link org.sonar.db.DatabaseUtils#PARTITION_SIZE_FOR_ORACLE} values
-   * @throws IllegalArgumentException if parameter query#getMainComponentUuids() has more than {@link org.sonar.db.DatabaseUtils#PARTITION_SIZE_FOR_ORACLE} values
-   */
-  public int countByQuery(DbSession session, ComponentQuery query) {
-    return countByQueryImpl(session, query);
+  public List<String> selectExistingUuids(DbSession session, Collection<String> uuids) {
+    return executeLargeInputs(uuids, mapper(session)::selectExistingUuids);
   }
 
   public List<ComponentDto> selectSubProjectsByComponentUuids(DbSession session, Collection<String> uuids) {
@@ -127,81 +98,100 @@ public class ComponentDao implements Dao {
     return mapper(session).selectEnabledFilesFromProject(rootComponentUuid);
   }
 
-  public List<ComponentDto> selectByUuids(DbSession session, Collection<String> uuids) {
-    return executeLargeInputs(uuids, mapper(session)::selectByUuids);
+  /**
+   * Retrieves all components with a specific branch UUID, no other filtering is done by this method.
+   */
+  public List<ComponentDto> selectByBranchUuid(String branchUuid, DbSession dbSession) {
+    return mapper(dbSession).selectByBranchUuid(branchUuid);
   }
 
-  public List<String> selectExistingUuids(DbSession session, Collection<String> uuids) {
-    return executeLargeInputs(uuids, mapper(session)::selectExistingUuids);
+  public int countEnabledModulesByBranchUuid(DbSession session, String branchUuid) {
+    return mapper(session).countEnabledModulesByBranchUuid(branchUuid);
   }
 
+  /*
+    SELECT BY QUERY
+   */
+
   /**
-   * Return all components of a project (including disable ones)
+   * @throws IllegalArgumentException if parameter query#getComponentIds() has more than {@link org.sonar.db.DatabaseUtils#PARTITION_SIZE_FOR_ORACLE} values
+   * @throws IllegalArgumentException if parameter query#getComponentKeys() has more than {@link org.sonar.db.DatabaseUtils#PARTITION_SIZE_FOR_ORACLE} values
+   * @throws IllegalArgumentException if parameter query#getMainComponentUuids() has more than {@link org.sonar.db.DatabaseUtils#PARTITION_SIZE_FOR_ORACLE} values
    */
-  public List<ComponentDto> selectAllComponentsFromProjectKey(DbSession session, String projectKey) {
-    return mapper(session).selectComponentsFromProjectKeyAndScope(projectKey, null, false);
+  public List<ComponentDto> selectByQuery(DbSession dbSession, ComponentQuery query, int offset, int limit) {
+    return selectByQueryImpl(dbSession, query, offset, limit);
   }
 
-  public List<KeyWithUuidDto> selectUuidsByKeyFromProjectKey(DbSession session, String projectKey) {
-    return mapper(session).selectUuidsByKeyFromProjectKey(projectKey);
+  /**
+   * @throws IllegalArgumentException if parameter query#getComponentIds() has more than {@link org.sonar.db.DatabaseUtils#PARTITION_SIZE_FOR_ORACLE} values
+   * @throws IllegalArgumentException if parameter query#getComponentKeys() has more than {@link org.sonar.db.DatabaseUtils#PARTITION_SIZE_FOR_ORACLE} values
+   * @throws IllegalArgumentException if parameter query#getMainComponentUuids() has more than {@link org.sonar.db.DatabaseUtils#PARTITION_SIZE_FOR_ORACLE} values
+   */
+  public int countByQuery(DbSession session, ComponentQuery query) {
+    return countByQueryImpl(session, query);
   }
 
-  public List<ComponentDto> selectProjectAndModulesFromProjectKey(DbSession session, String projectKey, boolean excludeDisabled) {
-    return mapper(session).selectComponentsFromProjectKeyAndScope(projectKey, Scopes.PROJECT, excludeDisabled);
+  private static List<ComponentDto> selectByQueryImpl(DbSession session, ComponentQuery query, int offset, int limit) {
+    if (query.hasEmptySetOfComponents()) {
+      return emptyList();
+    }
+    checkThatNotTooManyComponents(query);
+    return mapper(session).selectByQuery(query, new RowBounds(offset, limit));
   }
 
-  public int countEnabledModulesByBranchUuid(DbSession session, String branchUuid) {
-    return mapper(session).countEnabledModulesByBranchUuid(branchUuid);
+  private static int countByQueryImpl(DbSession session, ComponentQuery query) {
+    if (query.hasEmptySetOfComponents()) {
+      return 0;
+    }
+    checkThatNotTooManyComponents(query);
+    return mapper(session).countByQuery(query);
   }
 
-  public List<ComponentDto> selectEnabledModulesFromProjectKey(DbSession session, String projectKey) {
-    return selectProjectAndModulesFromProjectKey(session, projectKey, true);
-  }
+  /*
+     SELECT BY KEY
+   */
 
-  public List<ComponentDto> selectByKeys(DbSession session, Collection<String> keys) {
-    return executeLargeInputs(keys, mapper(session)::selectByKeys);
+  /**
+   * Return all components of a project (including disable ones)
+   */
+  public List<KeyWithUuidDto> selectUuidsByKeyFromProjectKey(DbSession session, String projectKey) {
+    return mapper(session).selectUuidsByKeyFromProjectKeyAndBranchOrPr(projectKey, null, null);
   }
 
-  public List<ComponentDto> selectByKeysAndBranch(DbSession session, Collection<String> keys, String branch) {
-    return executeLargeInputs(keys, subKeys -> mapper(session).selectByKeysAndBranch(subKeys, branch));
+  public List<KeyWithUuidDto> selectUuidsByKeyFromProjectKeyAndBranch(DbSession session, String projectKey, String branch) {
+    return mapper(session).selectUuidsByKeyFromProjectKeyAndBranchOrPr(projectKey, branch, null);
   }
 
-  public List<ComponentDto> selectByKeysAndPullRequest(DbSession session, Collection<String> keys, String pullRequestId) {
-    return executeLargeInputs(keys, subKeys -> mapper(session).selectByKeysAndBranch(subKeys, pullRequestId));
+  public List<KeyWithUuidDto> selectUuidsByKeyFromProjectKeyAndPullRequest(DbSession session, String projectKey, String pullrequest) {
+    return mapper(session).selectUuidsByKeyFromProjectKeyAndBranchOrPr(projectKey, null, pullrequest);
   }
 
-  public List<ComponentDto> selectByDbKeys(DbSession session, Collection<String> dbKeys) {
-    Map<String, List<String>> keyByBranchKey = new HashMap<>();
-    Map<String, List<String>> keyByPrKey = new HashMap<>();
-    List<String> mainBranchKeys = new LinkedList<>();
-
-    for (String dbKey : dbKeys) {
-      String branchKey = StringUtils.substringAfterLast(dbKey, ComponentDto.BRANCH_KEY_SEPARATOR);
-      if (!StringUtils.isEmpty(branchKey)) {
-        keyByBranchKey.computeIfAbsent(branchKey, b -> new LinkedList<>())
-          .add(StringUtils.substringBeforeLast(dbKey, ComponentDto.BRANCH_KEY_SEPARATOR));
-        continue;
-      }
+  /**
+   * If no branch or pull request is provided, returns components in the main branch
+   */
+  public List<ComponentDto> selectProjectAndModulesFromProjectKey(DbSession session, String projectKey, boolean excludeDisabled,
+    @Nullable String branch, @Nullable String pullRequest) {
+    checkState(branch == null || pullRequest == null, "Can't set both branch and pull request");
+    return mapper(session).selectComponentsFromProjectKeyAndScope(projectKey, Scopes.PROJECT, excludeDisabled, branch, pullRequest);
+  }
 
-      String prKey = StringUtils.substringAfterLast(dbKey, ComponentDto.PULL_REQUEST_SEPARATOR);
-      if (!StringUtils.isEmpty(prKey)) {
-        keyByPrKey.computeIfAbsent(prKey, b -> new LinkedList<>())
-          .add(StringUtils.substringBeforeLast(dbKey, ComponentDto.PULL_REQUEST_SEPARATOR));
-        continue;
-      }
+  /**
+   * If no branch or pull request is provided, returns components in the main branch
+   */
+  public List<ComponentDto> selectEnabledModulesFromProjectKey(DbSession session, String projectKey, @Nullable String branch, @Nullable String pullRequest) {
+    return selectProjectAndModulesFromProjectKey(session, projectKey, true, branch, pullRequest);
+  }
 
-      mainBranchKeys.add(dbKey);
-    }
+  public List<ComponentDto> selectByKeys(DbSession session, Collection<String> keys) {
+    return selectByKeys(session, keys, null, null);
+  }
 
-    List<ComponentDto> components = new LinkedList<>();
-    for (Map.Entry<String, List<String>> e : keyByBranchKey.entrySet()) {
-      components.addAll(selectByKeysAndBranch(session, e.getValue(), e.getKey()));
-    }
-    for (Map.Entry<String, List<String>> e : keyByPrKey.entrySet()) {
-      components.addAll(selectByKeysAndPullRequest(session, e.getValue(), e.getKey()));
-    }
-    components.addAll(selectByKeys(session, mainBranchKeys));
-    return components;
+  /**
+   * If no branch or pull request is provided, returns components in the main branch
+   */
+  public List<ComponentDto> selectByKeys(DbSession session, Collection<String> keys, @Nullable String branch, @Nullable String pullRequest) {
+    checkState(branch == null || pullRequest == null, "Can't set both branch and pull request");
+    return executeLargeInputs(keys, subKeys -> mapper(session).selectByKeysAndBranchOrPr(subKeys, branch, pullRequest));
   }
 
   /**
@@ -258,10 +248,25 @@ public class ComponentDao implements Dao {
     return Optional.ofNullable(mapper(session).selectByKeyAndPrKey(key, pullRequestId));
   }
 
+  /*
+    SELECT ALL
+   */
   public List<UuidWithBranchUuidDto> selectAllViewsAndSubViews(DbSession session) {
     return mapper(session).selectUuidsForQualifiers(Qualifiers.APP, Qualifiers.VIEW, Qualifiers.SUBVIEW);
   }
 
+  /**
+   * Returns all projects (Scope {@link Scopes#PROJECT} and qualifier
+   * {@link Qualifiers#PROJECT}) which are enabled.
+   * <p>
+   * Branches are not returned.
+   * <p>
+   * Used by Views.
+   */
+  public List<ComponentDto> selectProjects(DbSession session) {
+    return mapper(session).selectProjects();
+  }
+
   /**
    * Used by Governance
    */
@@ -276,18 +281,6 @@ public class ComponentDao implements Dao {
     return mapper(session).selectProjectsFromView("%." + escapedViewUuid + ".%", projectViewUuid);
   }
 
-  /**
-   * Returns all projects (Scope {@link Scopes#PROJECT} and qualifier
-   * {@link Qualifiers#PROJECT}) which are enabled.
-   * <p>
-   * Branches are not returned.
-   * <p>
-   * Used by Views.
-   */
-  public List<ComponentDto> selectProjects(DbSession session) {
-    return mapper(session).selectProjects();
-  }
-
   /**
    * Selects all components that are relevant for indexing. The result is not returned (since it is usually too big), but handed over to the <code>handler</code>
    *
@@ -299,15 +292,6 @@ public class ComponentDao implements Dao {
     mapper(session).scrollForIndexing(projectUuid, handler);
   }
 
-  /**
-   * Retrieves all components with a specific branch UUID, no other filtering is done by this method.
-   * <p>
-   * Used by Views plugin
-   */
-  public List<ComponentDto> selectByBranchUuid(String branchUuid, DbSession dbSession) {
-    return mapper(dbSession).selectByBranchUuid(branchUuid);
-  }
-
   /**
    * Retrieve enabled components keys with given qualifiers
    * <p>
@@ -349,6 +333,25 @@ public class ComponentDao implements Dao {
     mapper(session).scrollAllFilesForFileMove(branchUuid, handler);
   }
 
+  public List<ProjectNclocDistributionDto> selectPrivateProjectsWithNcloc(DbSession dbSession) {
+    return mapper(dbSession).selectPrivateProjectsWithNcloc();
+  }
+
+  public boolean existAnyOfComponentsWithQualifiers(DbSession session, Collection<String> componentKeys, Set<String> qualifiers) {
+    if (!componentKeys.isEmpty()) {
+      List<Boolean> result = new LinkedList<>();
+      return executeLargeInputs(componentKeys, input -> {
+        boolean groupNeedIssueSync = mapper(session).checkIfAnyOfComponentsWithQualifiers(input, qualifiers) > 0;
+        result.add(groupNeedIssueSync);
+        return result;
+      }).stream().anyMatch(b -> b);
+    }
+    return false;
+  }
+
+  /*
+    INSERT / UPDATE
+   */
   public void insert(DbSession session, ComponentDto item) {
     mapper(session).insert(item);
     if (!isBranchOrPullRequest(item)) {
@@ -396,27 +399,18 @@ public class ComponentDao implements Dao {
     mapper(session).setPrivateForRootComponentUuid(branchUuid, isPrivate);
   }
 
+  /*
+     UTIL
+   */
+  private static ComponentMapper mapper(DbSession session) {
+    return session.getMapper(ComponentMapper.class);
+  }
+
   private static void checkThatNotTooManyComponents(ComponentQuery query) {
     checkThatNotTooManyConditions(query.getComponentKeys(), "Too many component keys in query");
     checkThatNotTooManyConditions(query.getComponentUuids(), "Too many component UUIDs in query");
   }
 
-  public List<ProjectNclocDistributionDto> selectPrivateProjectsWithNcloc(DbSession dbSession) {
-    return mapper(dbSession).selectPrivateProjectsWithNcloc();
-  }
-
-  public boolean existAnyOfComponentsWithQualifiers(DbSession session, Collection<String> componentKeys, Set<String> qualifiers) {
-    if (!componentKeys.isEmpty()) {
-      List<Boolean> result = new LinkedList<>();
-      return executeLargeInputs(componentKeys, input -> {
-        boolean groupNeedIssueSync = mapper(session).checkIfAnyOfComponentsWithQualifiers(input, qualifiers) > 0;
-        result.add(groupNeedIssueSync);
-        return result;
-      }).stream().anyMatch(b -> b);
-    }
-    return false;
-  }
-
   private static boolean isBranchOrPullRequest(ComponentDto item) {
     return item.getMainBranchProjectUuid() != null;
   }
index d3303761465535f140e3800648af2528ea0ac2dd..ba308ad3ec2af1426e3cc3ac0db99cf1aef40ef3 100644 (file)
@@ -46,8 +46,6 @@ public class ComponentDto {
   public static final String BRANCH_KEY_SEPARATOR = ":BRANCH:";
   public static final String PULL_REQUEST_SEPARATOR = ":PULL_REQUEST:";
 
-  private static final Splitter BRANCH_KEY_SPLITTER = Splitter.on(BRANCH_KEY_SEPARATOR);
-
   public static final String UUID_PATH_SEPARATOR = ".";
   public static final String UUID_PATH_OF_ROOT = UUID_PATH_SEPARATOR;
   private static final Splitter UUID_PATH_SPLITTER = Splitter.on(UUID_PATH_SEPARATOR).omitEmptyStrings();
index ec86e389fe3bfb15e362bbac4330f156bd3aa5fc..5e247061a92c2a6cecc64d2e361dc7ed340fcf66 100644 (file)
@@ -32,9 +32,6 @@ import org.sonar.db.DbSession;
 import org.sonar.db.audit.AuditPersister;
 import org.sonar.db.audit.model.ComponentKeyNewValue;
 
-import static org.sonar.db.component.ComponentDto.BRANCH_KEY_SEPARATOR;
-import static org.sonar.db.component.ComponentDto.generateBranchKey;
-
 /**
  * Class used to rename the key of a project and its resources.
  *
@@ -52,17 +49,17 @@ public class ComponentKeyUpdaterDao implements Dao {
     checkExistentKey(mapper, newKey);
 
     // must SELECT first everything
-    ResourceDto project = mapper.selectProjectByUuid(projectUuid);
+    ResourceDto project = mapper.selectComponentByUuid(projectUuid);
     String projectOldKey = project.getKey();
-    List<ResourceDto> resources = mapper.selectProjectResources(projectUuid);
+    List<ResourceDto> resources = mapper.selectBranchResources(projectUuid);
     resources.add(project);
 
     // add branch components
     dbSession.getMapper(BranchMapper.class).selectByProjectUuid(projectUuid).stream()
       .filter(branch -> !projectUuid.equals(branch.getUuid()))
       .forEach(branch -> {
-        resources.addAll(mapper.selectProjectResources(branch.getUuid()));
-        resources.add(mapper.selectProjectByUuid(branch.getUuid()));
+        resources.addAll(mapper.selectBranchResources(branch.getUuid()));
+        resources.add(mapper.selectComponentByUuid(branch.getUuid()));
       });
 
     // and then proceed with the batch UPDATE at once
@@ -70,29 +67,6 @@ public class ComponentKeyUpdaterDao implements Dao {
     }, dbSession);
   }
 
-  public void updateApplicationBranchKey(DbSession dbSession, String appBranchUuid, String appKey, String newBranchName) {
-    // TODO review
-    ComponentKeyUpdaterMapper mapper = dbSession.getMapper(ComponentKeyUpdaterMapper.class);
-
-    String newAppBranchKey = generateBranchKey(appKey, newBranchName);
-    checkExistentKey(mapper, newAppBranchKey);
-
-    ResourceDto appBranch = mapper.selectProjectByUuid(appBranchUuid);
-    String appBranchOldKey = appBranch.getKey();
-    appBranch.setKey(newAppBranchKey);
-    mapper.updateComponent(appBranch);
-
-    auditPersister.componentKeyBranchUpdate(dbSession, new ComponentKeyNewValue(appBranchUuid, appBranchOldKey, newAppBranchKey), Qualifiers.APP);
-
-    String oldAppBranchFragment = appBranchOldKey.replace(BRANCH_KEY_SEPARATOR, "");
-    String newAppBranchFragment = appKey + newBranchName;
-    for (ResourceDto appBranchResource : mapper.selectProjectResources(appBranchUuid)) {
-      String newKey = computeNewKey(appBranchResource.getKey(), oldAppBranchFragment, newAppBranchFragment);
-      appBranchResource.setKey(newKey);
-      mapper.updateComponent(appBranchResource);
-    }
-  }
-
   @VisibleForTesting
   static String computeNewKey(String key, String stringToReplace, String replacementString) {
     return key.replace(stringToReplace, replacementString);
index 6a67af03dc27d8840e475e1b4c2d0316e9401133..f4c38fdf60cbec1aa6c29369be895ea4586523d3 100644 (file)
@@ -26,9 +26,9 @@ public interface ComponentKeyUpdaterMapper {
 
   int countComponentsByKey(String key);
 
-  ResourceDto selectProjectByUuid(@Param("uuid") String uuid);
+  ResourceDto selectComponentByUuid(@Param("uuid") String uuid);
 
-  List<ResourceDto> selectProjectResources(@Param("rootUuid") String rootUuid);
+  List<ResourceDto> selectBranchResources(@Param("rootUuid") String rootUuid);
 
   void updateComponent(ResourceDto resource);
 
index 982972780933b1ec4261a519a34d1eee88cd7dc0..f669ff574df7e79f95f7e6a5b1823706919951e3 100644 (file)
@@ -29,18 +29,11 @@ import org.apache.ibatis.session.ResultHandler;
 import org.apache.ibatis.session.RowBounds;
 
 public interface ComponentMapper {
-
-  @CheckForNull
-  ComponentDto selectByKey(@Param("key") String key);
-
   @CheckForNull
   ComponentDto selectByKeyCaseInsensitive(@Param("key") String key);
 
   @CheckForNull
-  ComponentDto selectByKeyAndBranchKey(@Param("key") String key, @Param("branch") String branch);
-
-  @CheckForNull
-  ComponentDto selectByKeyAndPrKey(@Param("key") String key, @Param("pr") String pr);
+  ComponentDto selectByKeyAndBranchOrPr(@Param("key") String key, @Nullable @Param("branch") String branch, @Nullable @Param("pullRequest") String pullRequest);
 
   @CheckForNull
   ComponentDto selectByUuid(@Param("uuid") String uuid);
@@ -50,9 +43,8 @@ public interface ComponentMapper {
    */
   List<ComponentDto> selectSubProjectsByComponentUuids(@Param("uuids") Collection<String> uuids);
 
-  List<ComponentDto> selectByKeys(@Param("keys") Collection<String> keys);
-
-  List<ComponentDto> selectByKeysAndBranch(@Param("keys") Collection<String> keys, @Param("branch") String branch);
+  List<ComponentDto> selectByKeysAndBranchOrPr(@Param("keys") Collection<String> keys,
+    @Nullable @Param("branch") String branch, @Nullable @Param("pullRequest") String pullRequest);
 
   List<ComponentDto> selectByUuids(@Param("uuids") Collection<String> uuids);
 
@@ -109,12 +101,13 @@ public interface ComponentMapper {
    * @param scope scope of components to return. If null, all components are returned
    */
   List<ComponentDto> selectComponentsFromProjectKeyAndScope(@Param("projectKey") String projectKey, @Nullable @Param("scope") String scope,
-    @Param(value = "excludeDisabled") boolean excludeDisabled);
+    @Param(value = "excludeDisabled") boolean excludeDisabled, @Nullable @Param("branch") String branch, @Nullable @Param("pullRequest") String pullRequest);
 
   /**
    * Return keys and UUIDs of all components belonging to a project
    */
-  List<KeyWithUuidDto> selectUuidsByKeyFromProjectKey(@Param("projectKey") String projectKey);
+  List<KeyWithUuidDto> selectUuidsByKeyFromProjectKeyAndBranchOrPr(@Param("projectKey") String projectKey,
+    @Nullable @Param("branch") String branch, @Nullable @Param("pullRequest") String pullRequest);
 
   Set<String> selectViewKeysWithEnabledCopyOfProject(@Param("projectUuids") Collection<String> projectUuids);
 
@@ -142,7 +135,7 @@ public interface ComponentMapper {
   void delete(String componentUuid);
 
   List<KeyWithUuidDto> selectComponentsFromPullRequestsTargetingCurrentBranchThatHaveOpenIssues(@Param("referenceBranchUuid") String referenceBranchUuid,
-                                                                                                @Param("currentBranchUuid") String currentBranchUuid);
+    @Param("currentBranchUuid") String currentBranchUuid);
 
   List<KeyWithUuidDto> selectComponentsFromBranchesThatHaveOpenIssues(@Param("branchUuids") List<String> branchUuids);
 
index ecf0f8520b8bdacf93c5171e43769b3de65463fb..ae54ec9fd17060f334dbe3a017cae054294d3d7b 100644 (file)
@@ -42,6 +42,8 @@ import org.sonar.db.audit.AuditPersister;
 import org.sonar.db.audit.model.PropertyNewValue;
 
 import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.Collections.emptyList;
+import static java.util.Collections.singletonList;
 import static org.apache.commons.lang.StringUtils.repeat;
 import static org.sonar.db.DatabaseUtils.executeLargeInputs;
 import static org.sonar.db.DatabaseUtils.executeLargeInputsIntoSet;
@@ -67,7 +69,6 @@ public class PropertiesDao implements Dao {
   /**
    * Returns the logins of users who have subscribed to the given notification dispatcher with the given notification channel.
    * If a resource ID is passed, the search is made on users who have specifically subscribed for the given resource.
-   *
    * Note that {@link  UserRole#USER} permission is not checked here, filter the results with
    * {@link org.sonar.db.permission.AuthorizationDao#keepAuthorizedLoginsOnProject}
    *
@@ -151,14 +152,13 @@ public class PropertiesDao implements Dao {
     }
   }
 
-  // TODO distinguish branch from project
-  public List<PropertyDto> selectProjectProperties(DbSession session, String projectKey) {
-    return getMapper(session).selectProjectProperties(projectKey);
+  public List<PropertyDto> selectComponentProperties(DbSession session, String uuid) {
+    return getMapper(session).selectByComponentUuids(singletonList(uuid));
   }
 
-  public List<PropertyDto> selectProjectProperties(String resourceKey) {
+  public List<PropertyDto> selectComponentProperties(String uuid) {
     try (DbSession session = mybatis.openSession(false)) {
-      return selectProjectProperties(session, resourceKey);
+      return selectComponentProperties(session, uuid);
     }
   }
 
@@ -261,7 +261,6 @@ public class PropertiesDao implements Dao {
    * Delete either global, user, component or component per user properties.
    * <p>Behaves in exactly the same way as {@link #selectByQuery(PropertyQuery, DbSession)} but deletes rather than
    * selects</p>
-   *
    * Used by Governance.
    */
   public int deleteByQuery(DbSession dbSession, PropertyQuery query) {
index 2b4255ef3e0e09356d3a4f16b994a651ca83389b..e5975bd34588692e930170e225c853bbb39e8bb7 100644 (file)
@@ -262,7 +262,7 @@ class PurgeCommands {
 
   void deleteComponents(String rootUuid) {
     profiler.start("deleteComponents (projects)");
-    purgeMapper.deleteComponentsByProjectUuid(rootUuid);
+    purgeMapper.deleteComponentsByBranchUuid(rootUuid);
     session.commit();
     profiler.stop();
   }
index 1e8687178d47ece081787b552569ca189fc1be0c..c6139a7646108058130ad8ca93b9f7c750a86954 100644 (file)
@@ -66,7 +66,7 @@ public interface PurgeMapper {
 
   void deletePropertiesByComponentUuids(@Param("componentUuids") List<String> componentUuids);
 
-  void deleteComponentsByProjectUuid(@Param("rootUuid") String rootUuid);
+  void deleteComponentsByBranchUuid(@Param("rootUuid") String rootUuid);
 
   void deleteComponentsByMainBranchProjectUuid(@Param("uuid") String uuid);
 
index 8112fb214dd8853db64216137d1a5c957ed4428b..e004a66d79a22379851667a7ef82f56c8f61d667 100644 (file)
     WHERE kee = #{key,jdbcType=VARCHAR}
   </select>
 
-  <select id="selectProjectByUuid" parameterType="String" resultMap="resourceResultMap">
+  <select id="selectComponentByUuid" parameterType="String" resultMap="resourceResultMap">
     select * from components
     where uuid = #{uuid,jdbcType=VARCHAR}
   </select>
 
-  <select id="selectProjectResources" parameterType="String" resultMap="resourceResultMap">
+  <select id="selectBranchResources" parameterType="String" resultMap="resourceResultMap">
     select * from components
     where
     root_uuid = #{rootUuid,jdbcType=VARCHAR}
index c25cc05c20bc0c451bb38457758e24cdbdeb6df3..5f67411da9d4ac31fece74132606b5a4d4b5bb47 100644 (file)
       and pb.branch_type='BRANCH'
   </select>
 
-  <select id="selectByKeyAndPrKey" parameterType="String" resultType="Component">
+  <select id="selectByKeyAndBranchOrPr" parameterType="String" resultType="Component">
     select
       <include refid="componentColumns"/>
     from components p
-    inner join project_branches pb on pb.uuid = p.branch_uuid
+    <if test="branch != null || pullRequest != null">
+      inner join project_branches pb on pb.uuid = p.branch_uuid
+    </if>
     where
       p.kee=#{key,jdbcType=VARCHAR}
-      and pb.kee=#{pr,jdbcType=VARCHAR}
-      and pb.branch_type='PULL_REQUEST'
+    <choose>
+      <when test="branch != null">
+        AND pb.kee=#{branch,jdbcType=VARCHAR}
+        AND pb.branch_type = 'BRANCH'
+      </when>
+      <when test="pullRequest != null">
+        AND pb.kee=#{pullRequest,jdbcType=VARCHAR}
+        AND pb.branch_type = 'PULL_REQUEST'
+      </when>
+      <otherwise>
+        AND p.main_branch_project_uuid is NULL
+      </otherwise>
+    </choose>
   </select>
 
   <select id="selectByUuid" parameterType="String" resultType="Component">
       p.uuid=#{uuid,jdbcType=VARCHAR}
   </select>
 
-  <select id="selectByBranchUuid" parameterType="string" resultType="Component">
-    select
-    <include refid="componentColumns"/>
-    from components root
-    inner join components p on p.branch_uuid=root.uuid
-    where
-      root.uuid=#{branchUuid,jdbcType=VARCHAR}
-  </select>
-
-  <select id="selectByKeys" parameterType="String" resultType="Component">
-    select
-    <include refid="componentColumns"/>
-    from components p
-    where
-      p.enabled=${_true}
-      and p.main_branch_project_uuid is null
-      and p.kee in
-      <foreach collection="keys" open="(" close=")" item="key" separator=",">
-        #{key,jdbcType=VARCHAR}
-      </foreach>
-  </select>
-
-  <select id="selectByKeysAndBranch" parameterType="String" resultType="Component">
+  <select id="selectByKeysAndBranchOrPr" parameterType="String" resultType="Component">
     SELECT
     <include refid="componentColumns"/>
     FROM components p
-    INNER JOIN project_branches pb on pb.uuid = p.branch_uuid
-    <where>
+    <if test="branch != null || pullRequest != null">
+      INNER JOIN project_branches pb on pb.uuid = p.branch_uuid
+    </if>
+    WHERE
     p.enabled=${_true}
     AND p.kee IN
     <foreach collection="keys" open="(" close=")" item="key" separator=",">
       #{key,jdbcType=VARCHAR}
     </foreach>
-    AND pb.kee=#{branch,jdbcType=VARCHAR}
-    </where>
+    <choose>
+      <when test="branch != null">
+        AND pb.kee=#{branch,jdbcType=VARCHAR}
+        AND pb.branch_type = 'BRANCH'
+      </when>
+      <when test="pullRequest != null">
+        AND pb.kee=#{pullRequest,jdbcType=VARCHAR}
+        AND pb.branch_type = 'PULL_REQUEST'
+      </when>
+      <otherwise>
+        AND p.main_branch_project_uuid IS NULL
+      </otherwise>
+    </choose>
   </select>
 
   <select id="selectByUuids" parameterType="String" resultType="Component">
     <include refid="componentColumns"/>
     FROM components p
     INNER JOIN components root ON root.uuid=p.branch_uuid AND root.kee=#{projectKey,jdbcType=VARCHAR}
+    <if test="branch != null || pullRequest != null">
+      INNER JOIN project_branches pb ON pb.uuid=p.branch_uuid
+    </if>
     <where>
       <if test="excludeDisabled">
         p.enabled = ${_true}
       <if test="scope != null">
         AND p.scope=#{scope,jdbcType=VARCHAR}
       </if>
+      <choose>
+        <when test="branch != null">
+          AND pb.kee=#{branch,jdbcType=VARCHAR} AND pb.branch_type = 'BRANCH'
+        </when>
+        <when test="pullRequest != null">
+          AND pb.kee=#{pullRequest,jdbcType=VARCHAR} AND pb.branch_type = 'PULL_REQUEST'
+        </when>
+        <otherwise>
+          AND root.main_branch_project_uuid is null
+        </otherwise>
+      </choose>
     </where>
   </select>
 
+  <select id="selectByBranchUuid" parameterType="map" resultType="Component">
+    SELECT
+    <include refid="componentColumns"/>
+    FROM components p
+    WHERE
+      p.branch_uuid = #{branchUuid,jdbcType=VARCHAR}
+  </select>
+
   <select id="selectEnabledComponentsWithModuleUuidFromProjectKey" resultType="ComponentWithModuleUuid">
     SELECT
       p.uuid as uuid, p.module_uuid as moduleUuid, p.path as path, p.scope as scope
       components root ON root.uuid=p.branch_uuid AND p.enabled = ${_true} AND root.kee=#{projectKey,jdbcType=VARCHAR}
   </select>
 
-  <select id="selectUuidsByKeyFromProjectKey" parameterType="string" resultType="KeyWithUuid">
+  <select id="selectUuidsByKeyFromProjectKeyAndBranchOrPr" parameterType="string" resultType="KeyWithUuid">
     SELECT
      p.kee, p.uuid
     FROM
       components p
     INNER JOIN
       components root ON root.uuid=p.branch_uuid AND root.kee=#{projectKey,jdbcType=VARCHAR}
+    <if test="branch != null || pullRequest != null">
+      INNER JOIN project_branches pb ON pb.uuid = root.uuid
+    </if>
+
+    <choose>
+      <when test="branch != null">
+        AND pb.kee = #{branch,jdbcType=VARCHAR}
+        AND pb.branch_type = 'BRANCH'
+      </when>
+      <when test="pullRequest != null">
+        AND pb.kee=#{pullRequest,jdbcType=VARCHAR}
+        AND pb.branch_type = 'PULL_REQUEST'
+      </when>
+      <otherwise>
+        AND root.main_branch_project_uuid is NULL
+      </otherwise>
+    </choose>
+
   </select>
 
   <select id="scrollForIndexing" parameterType="map" resultType="Component" fetchSize="${_scrollFetchSize}" resultSetType="FORWARD_ONLY">
index db14d3c66467dcfd0a8c265b96ed4a78a187e8af..94b0f1f028dd11496d0b3038f4a873d4411571a4 100644 (file)
       </foreach>
   </delete>
 
-  <delete id="deleteComponentsByProjectUuid" parameterType="map">
+  <delete id="deleteComponentsByBranchUuid" parameterType="map">
     delete from components
     where
       branch_uuid = #{rootUuid,jdbcType=VARCHAR}
index 8104002008b886ebbac9ee76c6e6cc574a0ee6fd..12d3bcd450a9bd1cc0261f4a867061650605c102 100644 (file)
@@ -200,8 +200,9 @@ public class ComponentDaoTest {
   }
 
   @Test
-  public void selectByKey() {
+  public void select_by_key() {
     ComponentDto project = db.components().insertPrivateProject();
+    ComponentDto branch = db.components().insertProjectBranch(project);
     ComponentDto directory = db.components().insertComponent(newDirectory(project, "src"));
     ComponentDto file = db.components().insertComponent(newFileDto(project, directory)
       .setKey("org.struts:struts-core:src/org/struts/RequestContext.java")
@@ -210,6 +211,7 @@ public class ComponentDaoTest {
       .setLanguage("java")
       .setPath("src/RequestContext.java"));
 
+    assertThat(underTest.selectByKey(dbSession, project.getKey())).isPresent();
     Optional<ComponentDto> optional = underTest.selectByKey(dbSession, file.getKey());
 
     ComponentDto result = optional.get();
@@ -227,7 +229,7 @@ public class ComponentDaoTest {
   }
 
   @Test
-  public void selectByKeyAndBranch() {
+  public void select_by_key_and_branch() {
     ComponentDto project = db.components().insertPublicProject();
     ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("my_branch").setBranchType(BRANCH));
     ComponentDto file = db.components().insertComponent(newFileDto(branch));
@@ -240,7 +242,7 @@ public class ComponentDaoTest {
   }
 
   @Test
-  public void selectByKeyAndPullRequest() {
+  public void select_by_key_and_pull_request() {
     ComponentDto project = db.components().insertPublicProject();
     ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("my_branch"));
     ComponentDto pullRequest = db.components().insertProjectBranch(project, b -> b.setKey("my_PR").setBranchType(PULL_REQUEST));
@@ -256,19 +258,11 @@ public class ComponentDaoTest {
     assertThat(underTest.selectByKeyAndPullRequest(dbSession, file.getKey(), "unknown")).isNotPresent();
   }
 
-  @Test
-  public void selectOrFailByKey_fails_when_component_not_found() {
-    db.components().insertPrivateProject();
-
-    assertThatThrownBy(() -> underTest.selectOrFailByKey(dbSession, "unknown"))
-      .isInstanceOf(RowNotFoundException.class);
-  }
-
   @Test
   public void get_by_key_on_disabled_component() {
     ComponentDto project = db.components().insertPrivateProject(p -> p.setEnabled(false));
 
-    ComponentDto result = underTest.selectOrFailByKey(dbSession, project.getKey());
+    ComponentDto result = underTest.selectByKey(dbSession, project.getKey()).get();
 
     assertThat(result.isEnabled()).isFalse();
   }
@@ -277,7 +271,7 @@ public class ComponentDaoTest {
   public void get_by_key_on_a_root_project() {
     ComponentDto project = db.components().insertPrivateProject();
 
-    ComponentDto result = underTest.selectOrFailByKey(dbSession, project.getKey());
+    ComponentDto result = underTest.selectByKey(dbSession, project.getKey()).get();
 
     assertThat(result.getKey()).isEqualTo(project.getKey());
     assertThat(result.uuid()).isEqualTo(project.uuid());
@@ -287,8 +281,9 @@ public class ComponentDaoTest {
   }
 
   @Test
-  public void get_by_keys() {
+  public void select_by_keys() {
     ComponentDto project1 = db.components().insertPrivateProject();
+    ComponentDto branch = db.components().insertProjectBranch(project1);
     ComponentDto project2 = db.components().insertPrivateProject();
 
     List<ComponentDto> results = underTest.selectByKeys(dbSession, asList(project1.getKey(), project2.getKey()));
@@ -299,26 +294,52 @@ public class ComponentDaoTest {
         tuple(project1.uuid(), project1.getKey()),
         tuple(project2.uuid(), project2.getKey()));
 
-    assertThat(underTest.selectByKeys(dbSession, singletonList("unknown"))).isEmpty();
+    assertThat(underTest.selectByKeys(dbSession, singletonList("unknown"), null, null)).isEmpty();
+  }
+
+  @Test
+  public void select_by_keys_throws_ISE_if_both_branch_and_pr_are_passed() {
+    assertThatThrownBy(() -> underTest.selectByKeys(db.getSession(), List.of("key"), "branch", "pr"))
+      .isInstanceOf(IllegalStateException.class);
   }
 
   @Test
-  public void selectByKeysAndBranch() {
+  public void select_by_keys_with_branch() {
+    String branchKey = "my_branch";
     ComponentDto project = db.components().insertPublicProject();
-    ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("my_branch"));
+    ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey(branchKey));
     ComponentDto file1 = db.components().insertComponent(newFileDto(branch));
     ComponentDto file2 = db.components().insertComponent(newFileDto(branch));
     ComponentDto anotherBranch = db.components().insertProjectBranch(project, b -> b.setKey("another_branch"));
     ComponentDto fileOnAnotherBranch = db.components().insertComponent(newFileDto(anotherBranch));
 
-    assertThat(underTest.selectByKeysAndBranch(dbSession, asList(branch.getKey(), file1.getKey(), file2.getKey()), "my_branch")).extracting(ComponentDto::uuid)
+    assertThat(underTest.selectByKeys(dbSession, asList(branch.getKey(), file1.getKey(), file2.getKey()), branchKey, null)).extracting(ComponentDto::uuid)
       .containsExactlyInAnyOrder(branch.uuid(), file1.uuid(), file2.uuid());
-    assertThat(underTest.selectByKeysAndBranch(dbSession, asList(file1.getKey(), file2.getKey(), fileOnAnotherBranch.getKey()), "my_branch")).extracting(ComponentDto::uuid)
+    assertThat(underTest.selectByKeys(dbSession, asList(file1.getKey(), file2.getKey(), fileOnAnotherBranch.getKey()), branchKey, null)).extracting(ComponentDto::uuid)
       .containsExactlyInAnyOrder(file1.uuid(), file2.uuid());
-    assertThat(underTest.selectByKeysAndBranch(dbSession, singletonList(fileOnAnotherBranch.getKey()), "my_branch")).isEmpty();
-    assertThat(underTest.selectByKeysAndBranch(dbSession, singletonList(file1.getKey()), "unknown")).isEmpty();
-    assertThat(underTest.selectByKeysAndBranch(dbSession, singletonList("unknown"), "my_branch")).isEmpty();
-    assertThat(underTest.selectByKeysAndBranch(dbSession, singletonList(branch.getKey()), "my_branch")).extracting(ComponentDto::uuid).containsExactlyInAnyOrder(branch.uuid());
+    assertThat(underTest.selectByKeys(dbSession, singletonList(fileOnAnotherBranch.getKey()), branchKey, null)).isEmpty();
+    assertThat(underTest.selectByKeys(dbSession, singletonList(file1.getKey()), "unknown", null)).isEmpty();
+    assertThat(underTest.selectByKeys(dbSession, singletonList("unknown"), branchKey, null)).isEmpty();
+    assertThat(underTest.selectByKeys(dbSession, singletonList(branch.getKey()), branchKey, null)).extracting(ComponentDto::uuid).containsExactlyInAnyOrder(branch.uuid());
+  }
+
+  @Test
+  public void select_by_keys_with_pr() {
+    String prKey = "my_branch";
+    ComponentDto project = db.components().insertPublicProject();
+    ComponentDto pr = db.components().insertProjectBranch(project, b -> b.setKey(prKey).setBranchType(PULL_REQUEST));
+    ComponentDto file1 = db.components().insertComponent(newFileDto(pr));
+    ComponentDto anotherBranch = db.components().insertProjectBranch(project, b -> b.setKey(prKey));
+    ComponentDto fileOnAnotherBranch = db.components().insertComponent(newFileDto(anotherBranch));
+
+    assertThat(underTest.selectByKeys(dbSession, asList(pr.getKey(), file1.getKey()), null, prKey)).extracting(ComponentDto::uuid)
+      .containsExactlyInAnyOrder(pr.uuid(), file1.uuid());
+    assertThat(underTest.selectByKeys(dbSession, asList(file1.getKey(), fileOnAnotherBranch.getKey()), null, prKey)).extracting(ComponentDto::uuid)
+      .containsExactlyInAnyOrder(file1.uuid());
+    assertThat(underTest.selectByKeys(dbSession, singletonList(fileOnAnotherBranch.getKey()), null, prKey)).isEmpty();
+    assertThat(underTest.selectByKeys(dbSession, singletonList(file1.getKey()), null, "unknown")).isEmpty();
+    assertThat(underTest.selectByKeys(dbSession, singletonList("unknown"), null, prKey)).isEmpty();
+    assertThat(underTest.selectByKeys(dbSession, singletonList(pr.getKey()), null, prKey)).extracting(ComponentDto::uuid).containsExactlyInAnyOrder(pr.uuid());
   }
 
   @Test
@@ -598,7 +619,7 @@ public class ComponentDaoTest {
   }
 
   @Test
-  public void select_all_components_from_project() {
+  public void select_by_branch_uuid() {
     ComponentDto project = db.components().insertPrivateProject();
     ComponentDto removedProject = db.components().insertPrivateProject(p -> p.setEnabled(false));
     ComponentDto module = db.components().insertComponent(newModuleDto(project));
@@ -611,17 +632,18 @@ public class ComponentDaoTest {
     ComponentDto removedFile = db.components().insertComponent(newFileDto(subModule, directory).setEnabled(false));
 
     // Removed components are included
-    assertThat(underTest.selectAllComponentsFromProjectKey(dbSession, project.getKey()))
+    assertThat(underTest.selectByBranchUuid(project.uuid(), dbSession))
       .extracting(ComponentDto::getKey)
       .containsExactlyInAnyOrder(project.getKey(), module.getKey(), removedModule.getKey(), subModule.getKey(), removedSubModule.getKey(),
         directory.getKey(), removedDirectory.getKey(), file.getKey(), removedFile.getKey());
 
-    assertThat(underTest.selectAllComponentsFromProjectKey(dbSession, "UNKNOWN")).isEmpty();
+    assertThat(underTest.selectByBranchUuid("UNKNOWN", dbSession)).isEmpty();
   }
 
   @Test
   public void select_uuids_by_key_from_project() {
     ComponentDto project = db.components().insertPrivateProject();
+    ComponentDto branch = db.components().insertProjectBranch(project);
     ComponentDto removedProject = db.components().insertPrivateProject(p -> p.setEnabled(false));
     ComponentDto module = db.components().insertComponent(newModuleDto(project));
     ComponentDto removedModule = db.components().insertComponent(newModuleDto(project).setEnabled(false));
@@ -647,6 +669,52 @@ public class ComponentDaoTest {
       entry(removedFile.getKey(), removedFile.uuid()));
   }
 
+  @Test
+  public void select_uuids_by_key_from_project_and_branch() {
+    String branchKey = "branch1";
+    ComponentDto project = db.components().insertPrivateProject();
+    ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey(branchKey));
+    ComponentDto pr = db.components().insertProjectBranch(project, b -> b.setKey(branchKey).setBranchType(PULL_REQUEST));
+    ComponentDto module = db.components().insertComponent(newModuleDto(branch));
+    ComponentDto subModule = db.components().insertComponent(newModuleDto(module));
+    ComponentDto directory = db.components().insertComponent(newDirectory(subModule, "src"));
+    ComponentDto file = db.components().insertComponent(newFileDto(subModule, directory));
+    ComponentDto projectFile = db.components().insertComponent(newFileDto(project, directory));
+
+    Map<String, String> uuidsByKey = underTest.selectUuidsByKeyFromProjectKeyAndBranch(dbSession, project.getKey(), branchKey)
+      .stream().collect(Collectors.toMap(KeyWithUuidDto::key, KeyWithUuidDto::uuid));
+
+    assertThat(uuidsByKey).containsOnly(
+      entry(branch.getKey(), branch.uuid()),
+      entry(module.getKey(), module.uuid()),
+      entry(subModule.getKey(), subModule.uuid()),
+      entry(directory.getKey(), directory.uuid()),
+      entry(file.getKey(), file.uuid()));
+  }
+
+  @Test
+  public void select_uuids_by_key_from_project_and_pr() {
+    String prKey = "pr1";
+    ComponentDto project = db.components().insertPrivateProject();
+    ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey(prKey).setBranchType(PULL_REQUEST));
+    ComponentDto pr = db.components().insertProjectBranch(project, b -> b.setKey(prKey).setBranchType(BRANCH));
+    ComponentDto module = db.components().insertComponent(newModuleDto(branch));
+    ComponentDto subModule = db.components().insertComponent(newModuleDto(module));
+    ComponentDto directory = db.components().insertComponent(newDirectory(subModule, "src"));
+    ComponentDto file = db.components().insertComponent(newFileDto(subModule, directory));
+    ComponentDto projectFile = db.components().insertComponent(newFileDto(project, directory));
+
+    Map<String, String> uuidsByKey = underTest.selectUuidsByKeyFromProjectKeyAndPullRequest(dbSession, project.getKey(), prKey)
+      .stream().collect(Collectors.toMap(KeyWithUuidDto::key, KeyWithUuidDto::uuid));
+
+    assertThat(uuidsByKey).containsOnly(
+      entry(branch.getKey(), branch.uuid()),
+      entry(module.getKey(), module.uuid()),
+      entry(subModule.getKey(), subModule.uuid()),
+      entry(directory.getKey(), directory.uuid()),
+      entry(file.getKey(), file.uuid()));
+  }
+
   @Test
   public void select_enabled_modules_from_project() {
     ComponentDto project = db.components().insertPrivateProject();
@@ -661,11 +729,41 @@ public class ComponentDaoTest {
     ComponentDto removedFile = db.components().insertComponent(newFileDto(subModule, directory).setEnabled(false));
 
     // Removed modules are not included
-    assertThat(underTest.selectEnabledModulesFromProjectKey(dbSession, project.getKey()))
+    assertThat(underTest.selectEnabledModulesFromProjectKey(dbSession, project.getKey(), null, null))
       .extracting(ComponentDto::getKey)
       .containsExactlyInAnyOrder(project.getKey(), module.getKey(), subModule.getKey());
 
-    assertThat(underTest.selectEnabledModulesFromProjectKey(dbSession, "UNKNOWN")).isEmpty();
+    assertThat(underTest.selectEnabledModulesFromProjectKey(dbSession, "UNKNOWN", null, null)).isEmpty();
+  }
+
+  @Test
+  public void select_enabled_modules_from_branch() {
+    ComponentDto project = db.components().insertPrivateProject();
+    ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("branch1"));
+    ComponentDto module = db.components().insertComponent(newModuleDto(branch));
+    ComponentDto subModule = db.components().insertComponent(newModuleDto(module));
+    ComponentDto directory = db.components().insertComponent(newDirectory(subModule, "src"));
+    ComponentDto file = db.components().insertComponent(newFileDto(subModule, directory));
+
+    // Removed modules are not included
+    assertThat(underTest.selectEnabledModulesFromProjectKey(dbSession, project.getKey(), "branch1", null))
+      .extracting(ComponentDto::getKey)
+      .containsExactlyInAnyOrder(project.getKey(), module.getKey(), subModule.getKey());
+  }
+
+  @Test
+  public void select_enabled_modules_from_pr() {
+    ComponentDto project = db.components().insertPrivateProject();
+    ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setBranchType(PULL_REQUEST).setKey("pr1"));
+    ComponentDto module = db.components().insertComponent(newModuleDto(branch));
+    ComponentDto subModule = db.components().insertComponent(newModuleDto(module));
+    ComponentDto directory = db.components().insertComponent(newDirectory(subModule, "src"));
+    ComponentDto file = db.components().insertComponent(newFileDto(subModule, directory));
+
+    // Removed modules are not included
+    assertThat(underTest.selectEnabledModulesFromProjectKey(dbSession, project.getKey(), null, "pr1"))
+      .extracting(ComponentDto::getKey)
+      .containsExactlyInAnyOrder(project.getKey(), module.getKey(), subModule.getKey());
   }
 
   @Test
@@ -1948,7 +2046,7 @@ public class ComponentDaoTest {
     ComponentDto project = db.components().insertPublicProject();
     BranchDto branch = newBranchDto(project);
     ComponentDto branchComponent = newBranchComponent(project, branch);
-    
+
     underTestWithAuditPersister.insert(dbSession, branchComponent);
 
     verifyNoInteractions(auditPersister);
@@ -1981,8 +2079,8 @@ public class ComponentDaoTest {
 
   private static Set<String> shuffleWithNonExistentUuids(String... uuids) {
     return Stream.concat(
-      IntStream.range(0, 1 + new Random().nextInt(5)).mapToObj(i -> randomAlphabetic(9)),
-      Arrays.stream(uuids))
+        IntStream.range(0, 1 + new Random().nextInt(5)).mapToObj(i -> randomAlphabetic(9)),
+        Arrays.stream(uuids))
       .collect(toSet());
   }
 
index 963b007a7e84547ac9b84d7d786100444bc31503..56da8d37e2966028749ac4009353c99769dc7e1e 100644 (file)
@@ -21,11 +21,9 @@ package org.sonar.db.component;
 
 import com.google.common.base.Strings;
 import java.util.List;
-import java.util.Map;
 import org.assertj.core.groups.Tuple;
 import org.junit.Rule;
 import org.junit.Test;
-import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.utils.System2;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
@@ -42,8 +40,6 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.sonar.db.component.BranchType.PULL_REQUEST;
-import static org.sonar.db.component.ComponentDto.BRANCH_KEY_SEPARATOR;
-import static org.sonar.db.component.ComponentDto.generateBranchKey;
 import static org.sonar.db.component.ComponentKeyUpdaterDao.computeNewKey;
 import static org.sonar.db.component.ComponentTesting.newDirectory;
 import static org.sonar.db.component.ComponentTesting.newFileDto;
@@ -95,66 +91,13 @@ public class ComponentKeyUpdaterDaoTest {
     underTest.updateKey(dbSession, "A", "your_project");
     dbSession.commit();
 
-    List<ComponentDto> result = dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, "your_project");
+    List<ComponentDto> result = dbClient.componentDao().selectByBranchUuid("A", dbSession);
     assertThat(result)
       .hasSize(5)
       .extracting(ComponentDto::getKey)
       .containsOnlyOnce("your_project", "your_project:directory", "your_project:directory/file", "your_project:inactive_directory", "your_project:inactive_directory/file");
   }
 
-  @Test
-  public void update_application_branch_key() {
-    ComponentDto app = db.components().insertPublicProject();
-    ComponentDto appBranch = db.components().insertProjectBranch(app);
-    ComponentDto appBranchProj1 = appBranch.copy()
-      .setKey(appBranch.getKey().replace(BRANCH_KEY_SEPARATOR, "") + "appBranchProj1").setUuid("appBranchProj1").setScope(Qualifiers.FILE);
-    ComponentDto appBranchProj2 = appBranch.copy()
-      .setKey(appBranch.getKey().replace(BRANCH_KEY_SEPARATOR, "") + "appBranchProj2").setUuid("appBranchProj2").setScope(Qualifiers.FILE);
-    db.components().insertComponent(appBranchProj1);
-    db.components().insertComponent(appBranchProj2);
-    int branchComponentCount = 3;
-
-    String oldBranchKey = appBranch.getKey();
-    assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldBranchKey)).hasSize(branchComponentCount);
-
-    String newBranchName = "newKey";
-    String newAppBranchKey = ComponentDto.generateBranchKey(app.getKey(), newBranchName);
-    String newAppBranchFragment = app.getKey() + newBranchName;
-    underTest.updateApplicationBranchKey(dbSession, appBranch.uuid(), app.getKey(), newBranchName);
-
-    assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldBranchKey)).isEmpty();
-
-    assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, newAppBranchKey)).hasSize(branchComponentCount);
-
-    List<Map<String, Object>> result = db.select(dbSession, String.format("select kee from components where root_uuid = '%s' and scope != 'PRJ'", appBranch.uuid()));
-
-    assertThat(result).hasSize(2);
-    result.forEach(map -> map.values().forEach(k -> assertThat(k.toString()).startsWith(newAppBranchFragment)));
-  }
-
-  @Test
-  public void update_application_branch_key_will_fail_if_newKey_exist() {
-    ComponentDto app = db.components().insertPublicProject();
-    ComponentDto appBranch = db.components().insertProjectBranch(app);
-    db.components().insertProjectBranch(app, b -> b.setKey("newName"));
-
-    assertThatThrownBy(() -> underTest.updateApplicationBranchKey(dbSession, appBranch.uuid(), app.getKey(), "newName"))
-      .isInstanceOf(IllegalArgumentException.class)
-      .hasMessage(String.format("Impossible to update key: a component with key \"%s\" already exists.", generateBranchKey(app.getKey(), "newName")));
-  }
-
-  @Test
-  public void updateApplicationBranchKey_callsAuditPersister() {
-    ComponentDto app = db.components().insertPublicProject();
-    ComponentDto appBranch = db.components().insertProjectBranch(app);
-    db.components().insertProjectBranch(app, b -> b.setKey("newName"));
-
-    underTestWithAuditPersister.updateApplicationBranchKey(dbSession, appBranch.uuid(), app.getKey(), "newName2");
-
-    verify(auditPersister, times(1))
-      .componentKeyBranchUpdate(any(DbSession.class), any(ComponentKeyNewValue.class), anyString());
-  }
-
   @Test
   public void updateKey_updates_branches_too() {
     ComponentDto project = db.components().insertPublicProject();
index 40cf19f892a7004331db5515c501361bacbe0797..f71e2089de1e99522ffedb818c6edafa5507403d 100644 (file)
@@ -155,7 +155,7 @@ public class PropertiesDaoTest {
       user1.getLogin(), projectKey, projectName);
     // global subscription
     insertProperty("notification.DispatcherWithGlobalAndProjectSubscribers.Email", "true", null, user2.getUuid(),
-      user2.getLogin(), null,null);
+      user2.getLogin(), null, null);
 
     // Nobody is subscribed
     assertThat(underTest.hasProjectNotificationSubscribersForDispatchers(projectUuid, singletonList("NotSexyDispatcher")))
@@ -459,8 +459,8 @@ public class PropertiesDaoTest {
   @Test
   public void selectGlobalProperties() {
     // global
-    insertProperty("global.one", "one", null, null, null, null,null);
-    insertProperty("global.two", "two", null, null, null, null,null);
+    insertProperty("global.one", "one", null, null, null, null, null);
+    insertProperty("global.two", "two", null, null, null, null, null);
 
     List<PropertyDto> properties = underTest.selectGlobalProperties();
     assertThat(properties.size())
@@ -492,7 +492,7 @@ public class PropertiesDaoTest {
   @Test
   public void selectGlobalProperty() {
     // global
-    insertProperty("global.one", "one", null, null, null, null,null);
+    insertProperty("global.one", "one", null, null, null, null, null);
     insertProperty("global.two", "two", null, null, null, null, null);
     // project
     insertProperty("project.one", "one", "uuid10", null, null, "component", "component");
@@ -518,36 +518,13 @@ public class PropertiesDaoTest {
       .containsExactly(null, null, expected);
   }
 
-  @Test
-  public void selectProjectProperties() {
-    ComponentDto projectDto = insertPrivateProject("A");
-    String projectUuid = projectDto.uuid();
-    // global
-    insertProperty("global.one", "one", null, null, null, null, null);
-    insertProperty("global.two", "two", null, null, null, null, null);
-    // project
-    insertProperty("project.one", "Pone", projectUuid, null, null, projectDto.getKey(), projectDto.name());
-    insertProperty("project.two", "Ptwo", projectUuid, null, null, projectDto.getKey(), projectDto.name());
-
-    List<PropertyDto> dtos = underTest.selectProjectProperties(projectDto.getKey());
-    assertThat(dtos)
-      .hasSize(2);
-    assertThat(findByKey(dtos, "project.one"))
-      .extracting(PropertyDto::getKey, PropertyDto::getComponentUuid, PropertyDto::getValue)
-      .containsExactly("project.one", projectUuid, "Pone");
-
-    assertThat(findByKey(dtos, "project.two"))
-      .extracting(PropertyDto::getKey, PropertyDto::getComponentUuid, PropertyDto::getValue)
-      .containsExactly("project.two", projectUuid, "Ptwo");
-  }
-
   @Test
   @UseDataProvider("allValuesForSelect")
   public void selectProjectProperties_supports_all_values(String dbValue, String expected) {
     ComponentDto projectDto = insertPrivateProject("A");
     insertProperty("project.one", dbValue, projectDto.uuid(), null, null, projectDto.getKey(), projectDto.name());
 
-    List<PropertyDto> dtos = underTest.selectProjectProperties(projectDto.getKey());
+    List<PropertyDto> dtos = underTest.selectComponentProperties(projectDto.uuid());
     assertThat(dtos).hasSize(1);
 
     assertThat(dtos.iterator().next())
@@ -654,6 +631,8 @@ public class PropertiesDaoTest {
 
     assertThat(underTest.selectPropertiesByComponentUuids(session, newHashSet(project.uuid())))
       .extracting("key", "componentUuid").containsOnly(tuple(key, project.uuid()));
+    assertThat(underTest.selectComponentProperties(session, (project.uuid())))
+      .extracting("key", "componentUuid").containsOnly(tuple(key, project.uuid()));
     assertThat(underTest.selectPropertiesByComponentUuids(session, newHashSet(project.uuid(), project2.uuid())))
       .extracting("key", "componentUuid").containsOnly(
         tuple(key, project.uuid()),
@@ -671,7 +650,7 @@ public class PropertiesDaoTest {
 
     String key = "key";
     String anotherKey = "anotherKey";
-    insertProperties(null, null,null, newGlobalPropertyDto().setKey(key));
+    insertProperties(null, null, null, newGlobalPropertyDto().setKey(key));
     insertProperties(null, project.getKey(), project.name(), newComponentPropertyDto(project).setKey(key));
     insertProperties(null, project2.getKey(), project2.name(), newComponentPropertyDto(project2).setKey(key),
       newComponentPropertyDto(project2).setKey(anotherKey));
@@ -1250,7 +1229,7 @@ public class PropertiesDaoTest {
 
   @Test
   public void rename_to_same_key_has_no_effect() {
-    String uuid = insertProperty("foo", "bar", null, null, null, null,null);
+    String uuid = insertProperty("foo", "bar", null, null, null, null, null);
 
     assertThatPropertiesRowByUuid(uuid)
       .hasCreatedAt(INITIAL_DATE);
index 2d7c7987556bd01d26995f2a4da9c971d9c088a0..8681d7b8391c9f7cf559c11ac1dac0fc0114eaa6 100644 (file)
@@ -94,6 +94,11 @@ public class ComponentDbTester {
     return insertComponentAndBranchAndProject(ComponentTesting.newPublicProjectDto(uuid), false);
   }
 
+  public ComponentDto insertPublicProject(String uuid, Consumer<ComponentDto> dtoPopulator) {
+    return insertComponentAndBranchAndProject(ComponentTesting.newPublicProjectDto(uuid), false, defaults(), dtoPopulator);
+  }
+
+
   public ComponentDto insertPublicProject(ComponentDto componentDto) {
     return insertComponentAndBranchAndProject(componentDto, false);
   }
index 76f9af0eee16decceb32f04a84be2d43336603d1..98f07e9ddb6ad3b78215d6c4dd0a209b3c2a8af1 100644 (file)
@@ -31,6 +31,7 @@ import org.sonar.db.DbTester;
 import org.sonar.db.component.ComponentDto;
 
 import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.sonar.db.property.PropertyTesting.newComponentPropertyDto;
 import static org.sonar.db.property.PropertyTesting.newGlobalPropertyDto;
@@ -55,8 +56,7 @@ public class PropertyDbTester {
   }
 
   public void insertProperties(@Nullable String userLogin, @Nullable String projectKey,
-    @Nullable String projectName, @Nullable String qualifier,
-    PropertyDto... properties) {
+    @Nullable String projectName, @Nullable String qualifier, PropertyDto... properties) {
     insertProperties(asList(properties), userLogin, projectKey, projectName, qualifier);
   }
 
@@ -68,6 +68,14 @@ public class PropertyDbTester {
     dbSession.commit();
   }
 
+  public void insertProperty(String propKey, String propValue, @Nullable String componentUuid) {
+    insertProperties(singletonList(new PropertyDto()
+        .setKey(propKey)
+        .setValue(propValue)
+        .setComponentUuid(componentUuid)),
+      null, null, null, null);
+  }
+
   public void insertPropertySet(String settingBaseKey, @Nullable ComponentDto componentDto, Map<String, String>... fieldValues) {
     int index = 1;
     List<PropertyDto> propertyDtos = new ArrayList<>();
@@ -96,22 +104,6 @@ public class PropertyDbTester {
     insertProperties(propertyDtos, null, componentKey, componentName, qualififer);
   }
 
-  public PropertyDbTester verifyInternal(String key, @Nullable String expectedValue) {
-    Optional<String> value = dbClient.internalPropertiesDao().selectByKey(dbSession, key);
-    if (expectedValue == null) {
-      assertThat(value).isEmpty();
-    } else {
-      assertThat(value).hasValue(expectedValue);
-    }
-    return this;
-  }
-
-  public PropertyDbTester insertInternal(String key, String value) {
-    dbClient.internalPropertiesDao().save(dbSession, key, value);
-    dbSession.commit();
-    return this;
-  }
-
   public Optional<PropertyDto> findFirstUserProperty(String userUuid, String key) {
     PropertyQuery query = new PropertyQuery.Builder()
       .setUserUuid(userUuid)
index 7ccb239e9c2fd624ba04f6329b33aace09cbd15e..afcb0965883121a0398b96ecc4c8c60610fcccb6 100644 (file)
  */
 package org.sonar.server.setting;
 
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
 import org.sonar.api.config.Configuration;
 import org.sonar.db.DbSession;
 import org.sonar.db.component.ComponentDto;
 
-import static java.lang.String.format;
-import static java.util.Objects.requireNonNull;
-
 public interface ProjectConfigurationLoader {
   /**
    * Loads configuration for the specified components.
-   *
    * <p>
    * Returns the applicable component configuration with most specific configuration overriding more global ones
    * (eg. global > project > branch).
-   *
    * <p>
    * Any component is accepted but SQ only supports specific properties for projects and branches.
    */
-  Map<String, Configuration> loadProjectConfigurations(DbSession dbSession, Set<ComponentDto> projects);
-
-  default Configuration loadProjectConfiguration(DbSession dbSession, ComponentDto project) {
-    Map<String, Configuration> configurations = loadProjectConfigurations(dbSession, Collections.singleton(project));
-    return requireNonNull(configurations.get(project.uuid()), () -> format("Configuration for project '%s' is not found", project.getKey()));
-  }
+  Configuration loadProjectConfiguration(DbSession dbSession, ComponentDto project);
 }
index fc7c5b17148587b2cb8ab689e8e5cb78f6a2e678..8343fc87f38371182cc46c49da51508f22575fed 100644 (file)
 package org.sonar.server.setting;
 
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.stream.Collectors;
 import org.sonar.api.config.Configuration;
 import org.sonar.api.config.internal.Settings;
 import org.sonar.db.DbClient;
@@ -31,8 +27,6 @@ import org.sonar.db.DbSession;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.property.PropertyDto;
 
-import static org.sonar.core.util.stream.MoreCollectors.uniqueIndex;
-
 public class ProjectConfigurationLoaderImpl implements ProjectConfigurationLoader {
   private final Settings globalSettings;
   private final DbClient dbClient;
@@ -43,31 +37,26 @@ public class ProjectConfigurationLoaderImpl implements ProjectConfigurationLoade
   }
 
   @Override
-  public Map<String, Configuration> loadProjectConfigurations(DbSession dbSession, Set<ComponentDto> projects) {
-    Set<String> mainBranchDbKeys = projects.stream().map(ComponentDto::getKey).collect(Collectors.toSet());
-    Map<String, ChildSettings> mainBranchSettingsByDbKey = loadMainBranchConfigurations(dbSession, mainBranchDbKeys);
-    return projects.stream()
-      .collect(uniqueIndex(ComponentDto::uuid, component -> {
-        if (component.getKey().equals(component.getKey())) {
-          return mainBranchSettingsByDbKey.get(component.getKey()).asConfiguration();
-        }
+  public Configuration loadProjectConfiguration(DbSession dbSession, ComponentDto projectOrBranch) {
+    boolean isMainBranch = projectOrBranch.getMainBranchProjectUuid() == null;
+    String mainBranchUuid = isMainBranch ? projectOrBranch.branchUuid() : projectOrBranch.getMainBranchProjectUuid();
+    ChildSettings mainBranchSettings = loadMainBranchConfiguration(dbSession, mainBranchUuid);
+
+    if (isMainBranch) {
+      return mainBranchSettings.asConfiguration();
+    }
 
-        ChildSettings settings = new ChildSettings(mainBranchSettingsByDbKey.get(component.getKey()));
-        dbClient.propertiesDao()
-            .selectProjectProperties(dbSession, component.getKey())
-          .forEach(property -> settings.setProperty(property.getKey(), property.getValue()));
-        return settings.asConfiguration();
-      }));
+    ChildSettings settings = new ChildSettings(mainBranchSettings);
+    dbClient.propertiesDao()
+      .selectComponentProperties(dbSession, projectOrBranch.uuid())
+      .forEach(property -> settings.setProperty(property.getKey(), property.getValue()));
+    return settings.asConfiguration();
   }
 
-  private Map<String, ChildSettings> loadMainBranchConfigurations(DbSession dbSession, Set<String> dbKeys) {
-    return dbKeys.stream().collect(uniqueIndex(Function.identity(), dbKey -> {
-      ChildSettings settings = new ChildSettings(globalSettings);
-      List<PropertyDto> propertyDtos = dbClient.propertiesDao()
-          .selectProjectProperties(dbSession, dbKey);
-      propertyDtos
-        .forEach(property -> settings.setProperty(property.getKey(), property.getValue()));
-      return settings;
-    }));
+  private ChildSettings loadMainBranchConfiguration(DbSession dbSession, String uuid) {
+    ChildSettings settings = new ChildSettings(globalSettings);
+    List<PropertyDto> propertyDtos = dbClient.propertiesDao().selectComponentProperties(dbSession, uuid);
+    propertyDtos.forEach(property -> settings.setProperty(property.getKey(), property.getValue()));
+    return settings;
   }
 }
index c25f8b7ea0401dd4382f419e90c09de411844412..af93180a1be60916311102e7ef0be843759bcfae 100644 (file)
  */
 package org.sonar.server.setting;
 
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import java.util.Collections;
-import java.util.Map;
+import javax.annotation.Nullable;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.config.Configuration;
 import org.sonar.api.config.internal.MapSettings;
 import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
+import org.sonar.db.DbTester;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.property.PropertiesDao;
-import org.sonar.db.property.PropertyDto;
 
-import static java.util.Collections.emptyList;
-import static java.util.Collections.singleton;
-import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
 import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoInteractions;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 public class ProjectConfigurationLoaderImplTest {
-  private final DbClient dbClient = mock(DbClient.class);
-  private final DbSession dbSession = mock(DbSession.class);
-  private final PropertiesDao propertiesDao = mock(PropertiesDao.class);
+  @Rule
+  public DbTester db = DbTester.create();
+
+  private final String globalPropKey = randomAlphanumeric(9);
+  private final String globalPropValue = randomAlphanumeric(10);
+  private final String mainBranchPropKey = randomAlphanumeric(7);
+  private final String mainBranchPropValue = randomAlphanumeric(8);
+  private final String branchPropKey = randomAlphanumeric(9);
+  private final String branchPropValue = randomAlphanumeric(10);
+
+  private final String mainBranchUuid = randomAlphanumeric(6);
+  private final String branchUuid = randomAlphanumeric(6);
   private final MapSettings globalSettings = new MapSettings();
-  private final ProjectConfigurationLoaderImpl underTest = new ProjectConfigurationLoaderImpl(globalSettings, dbClient);
+  private ProjectConfigurationLoaderImpl underTest;
 
   @Before
   public void setUp() {
-    when(dbClient.openSession(anyBoolean()))
-      .thenThrow(new IllegalStateException("ProjectConfigurationLoaderImpl should not open DB session"));
-    when(dbClient.propertiesDao()).thenReturn(propertiesDao);
-  }
-
-  @Test
-  public void returns_empty_map_when_no_component() {
-    assertThat(underTest.loadProjectConfigurations(dbSession, Collections.emptySet()))
-      .isEmpty();
-
-    verifyNoInteractions(propertiesDao);
+    underTest = new ProjectConfigurationLoaderImpl(globalSettings, db.getDbClient());
   }
 
   @Test
   public void return_configuration_with_just_global_settings_when_no_component_settings() {
-    String key = randomAlphanumeric(3);
-    String value = randomAlphanumeric(4);
-    String componentDbKey = randomAlphanumeric(5);
-    String componentUuid = randomAlphanumeric(6);
-    globalSettings.setProperty(key, value);
-    when(propertiesDao.selectProjectProperties(dbSession, componentDbKey))
-      .thenReturn(emptyList());
-    ComponentDto component = newComponentDto(componentDbKey, componentUuid);
-
-    Map<String, Configuration> configurations = underTest.loadProjectConfigurations(dbSession, singleton(component));
-
-    assertThat(configurations)
-      .containsOnlyKeys(componentUuid);
-    assertThat(configurations.get(componentUuid).get(key)).contains(value);
-  }
+    globalSettings.setProperty(mainBranchPropKey, mainBranchPropValue);
+    ComponentDto component = newComponentDto(mainBranchUuid);
 
-  @Test
-  public void returns_single_configuration_for_single_project_load() {
-    String key = randomAlphanumeric(3);
-    String value = randomAlphanumeric(4);
-    String componentDbKey = randomAlphanumeric(5);
-    String componentUuid = randomAlphanumeric(6);
-    globalSettings.setProperty(key, value);
-    when(propertiesDao.selectProjectProperties(dbSession, componentDbKey))
-      .thenReturn(emptyList());
-    ComponentDto component = newComponentDto(componentDbKey, componentUuid);
-
-    Configuration configuration = underTest.loadProjectConfiguration(dbSession, component);
-    assertThat(configuration.get(key)).hasValue(value);
+    Configuration configuration = underTest.loadProjectConfiguration(db.getSession(), component);
+
+    assertThat(configuration.get(mainBranchPropKey)).contains(mainBranchPropValue);
   }
 
   @Test
   public void return_configuration_with_global_settings_and_component_settings() {
-    String globalKey = randomAlphanumeric(3);
-    String globalValue = randomAlphanumeric(4);
-    String componentDbKey = randomAlphanumeric(5);
-    String componentUuid = randomAlphanumeric(6);
     String projectPropKey1 = randomAlphanumeric(7);
     String projectPropValue1 = randomAlphanumeric(8);
     String projectPropKey2 = randomAlphanumeric(9);
     String projectPropValue2 = randomAlphanumeric(10);
-    globalSettings.setProperty(globalKey, globalValue);
-    when(propertiesDao.selectProjectProperties(dbSession, componentDbKey))
-      .thenReturn(ImmutableList.of(newPropertyDto(projectPropKey1, projectPropValue1), newPropertyDto(projectPropKey2, projectPropValue2)));
-    ComponentDto component = newComponentDto(componentDbKey, componentUuid);
-
-    Map<String, Configuration> configurations = underTest.loadProjectConfigurations(dbSession, singleton(component));
-
-    assertThat(configurations)
-      .containsOnlyKeys(componentUuid);
-    assertThat(configurations.get(componentUuid).get(globalKey)).contains(globalValue);
-    assertThat(configurations.get(componentUuid).get(projectPropKey1)).contains(projectPropValue1);
-    assertThat(configurations.get(componentUuid).get(projectPropKey2)).contains(projectPropValue2);
+    globalSettings.setProperty(globalPropKey, globalPropValue);
+    db.properties().insertProperty(projectPropKey1, projectPropValue1, mainBranchUuid);
+    db.properties().insertProperty(projectPropKey2, projectPropValue2, mainBranchUuid);
+    ComponentDto component = newComponentDto(mainBranchUuid);
+
+    Configuration configuration = underTest.loadProjectConfiguration(db.getSession(), component);
+
+    assertThat(configuration.get(globalPropKey)).contains(globalPropValue);
+    assertThat(configuration.get(projectPropKey1)).contains(projectPropValue1);
+    assertThat(configuration.get(projectPropKey2)).contains(projectPropValue2);
   }
 
   @Test
   public void return_configuration_with_global_settings_main_branch_settings_and_branch_settings() {
-    // TODO
-    String globalKey = randomAlphanumeric(3);
-    String globalValue = randomAlphanumeric(4);
-    String mainBranchDbKey = randomAlphanumeric(5);
-    String branchDbKey = mainBranchDbKey + ComponentDto.BRANCH_KEY_SEPARATOR + randomAlphabetic(5);
-    String branchUuid = randomAlphanumeric(6);
-    String mainBranchPropKey = randomAlphanumeric(7);
-    String mainBranchPropValue = randomAlphanumeric(8);
-    String branchPropKey = randomAlphanumeric(9);
-    String branchPropValue = randomAlphanumeric(10);
-    globalSettings.setProperty(globalKey, globalValue);
-    when(propertiesDao.selectProjectProperties(dbSession, mainBranchDbKey))
-      .thenReturn(ImmutableList.of(newPropertyDto(mainBranchPropKey, mainBranchPropValue)));
-    when(propertiesDao.selectProjectProperties(dbSession, branchDbKey))
-      .thenReturn(ImmutableList.of(newPropertyDto(branchPropKey, branchPropValue)));
-    ComponentDto component = newComponentDto(branchDbKey, branchUuid);
-
-    Map<String, Configuration> configurations = underTest.loadProjectConfigurations(dbSession, singleton(component));
-
-    assertThat(configurations)
-      .containsOnlyKeys(branchUuid);
-    assertThat(configurations.get(branchUuid).get(globalKey)).contains(globalValue);
-    assertThat(configurations.get(branchUuid).get(mainBranchPropKey)).contains(mainBranchPropValue);
-    assertThat(configurations.get(branchUuid).get(branchPropKey)).contains(branchPropValue);
-  }
+    globalSettings.setProperty(globalPropKey, globalPropValue);
 
-  @Test
-  public void loads_configuration_of_any_given_component_only_once() {
-    String mainBranch1DbKey = randomAlphanumeric(4);
-    String mainBranch1Uuid = randomAlphanumeric(5);
-    String branch1DbKey = mainBranch1DbKey + ComponentDto.BRANCH_KEY_SEPARATOR + randomAlphabetic(5);
-    String branch1Uuid = randomAlphanumeric(6);
-    String branch2DbKey = mainBranch1DbKey + ComponentDto.BRANCH_KEY_SEPARATOR + randomAlphabetic(7);
-    String branch2Uuid = randomAlphanumeric(8);
-    String mainBranch2DbKey = randomAlphanumeric(14);
-    String mainBranch2Uuid = randomAlphanumeric(15);
-    String branch3DbKey = mainBranch2DbKey + ComponentDto.BRANCH_KEY_SEPARATOR + randomAlphabetic(5);
-    String branch3Uuid = randomAlphanumeric(16);
-
-    ComponentDto mainBranch1 = newComponentDto(mainBranch1DbKey, mainBranch1Uuid);
-    ComponentDto branch1 = newComponentDto(branch1DbKey, branch1Uuid);
-    ComponentDto branch2 = newComponentDto(branch2DbKey, branch2Uuid);
-    ComponentDto mainBranch2 = newComponentDto(mainBranch2DbKey, mainBranch2Uuid);
-    ComponentDto branch3 = newComponentDto(branch3DbKey, branch3Uuid);
-
-    underTest.loadProjectConfigurations(dbSession, ImmutableSet.of(mainBranch1, mainBranch2, branch1, branch2, branch3));
-
-    verify(propertiesDao, times(1)).selectProjectProperties(dbSession, mainBranch1DbKey);
-    verify(propertiesDao, times(1)).selectProjectProperties(dbSession, mainBranch2DbKey);
-    verify(propertiesDao, times(1)).selectProjectProperties(dbSession, branch1DbKey);
-    verify(propertiesDao, times(1)).selectProjectProperties(dbSession, branch2DbKey);
-    verify(propertiesDao, times(1)).selectProjectProperties(dbSession, branch3DbKey);
-    verifyNoMoreInteractions(propertiesDao);
+    db.properties().insertProperty(mainBranchPropKey, mainBranchPropValue, mainBranchUuid);
+    db.properties().insertProperty(branchPropKey, branchPropValue, branchUuid);
+
+    ComponentDto component = newComponentDto(branchUuid, mainBranchUuid);
+    Configuration configuration = underTest.loadProjectConfiguration(db.getSession(), component);
+
+    assertThat(configuration.get(globalPropKey)).contains(globalPropValue);
+    assertThat(configuration.get(mainBranchPropKey)).contains(mainBranchPropValue);
+    assertThat(configuration.get(branchPropKey)).contains(branchPropValue);
   }
 
-  private ComponentDto newComponentDto(String componentDbKey, String componentUuid) {
-    return new ComponentDto().setKey(componentDbKey).setUuid(componentUuid);
+  private ComponentDto newComponentDto(String uuid) {
+    return newComponentDto(uuid, null);
   }
 
-  private PropertyDto newPropertyDto(String projectKey1, String projectValue1) {
-    return new PropertyDto()
-      .setKey(projectKey1)
-      .setValue(projectValue1);
+  private ComponentDto newComponentDto(String uuid, @Nullable String mainBranchUuid) {
+    return new ComponentDto().setUuid(uuid).setBranchUuid(uuid).setMainBranchProjectUuid(mainBranchUuid);
   }
 }
index 22d72c4b9210c07debd96ad7f27accc6454f1eb6..fc53b8934440cd7e9756ecc33aa12c2f36a7662f 100644 (file)
@@ -420,14 +420,7 @@ public class IssueQueryFactory {
   }
 
   private List<ComponentDto> getComponentsFromKeys(DbSession dbSession, Collection<String> componentKeys, @Nullable String branch, @Nullable String pullRequest) {
-    List<ComponentDto> componentDtos;
-    if (branch != null) {
-      componentDtos = dbClient.componentDao().selectByKeysAndBranch(dbSession, componentKeys, branch);
-    } else if (pullRequest != null) {
-      componentDtos = dbClient.componentDao().selectByKeysAndPullRequest(dbSession, componentKeys, pullRequest);
-    } else {
-      componentDtos = dbClient.componentDao().selectByKeys(dbSession, componentKeys);
-    }
+    List<ComponentDto> componentDtos = dbClient.componentDao().selectByKeys(dbSession, componentKeys, branch, pullRequest);
     if (!componentKeys.isEmpty() && componentDtos.isEmpty()) {
       return singletonList(UNKNOWN_COMPONENT);
     }
@@ -456,12 +449,12 @@ public class IssueQueryFactory {
 
   private void setBranch(IssueQuery.Builder builder, ComponentDto component, @Nullable String branch, @Nullable String pullRequest,
     DbSession session) {
-    BranchDto branchDto = findComponentBranch(session, component);
-    String componentBranch = branchDto.isMain() ? null : branchDto.getBranchKey();
     builder.branchUuid(branch == null && pullRequest == null ? null : component.branchUuid());
-    builder.mainBranch(UNKNOWN_COMPONENT.equals(component)
-      || (branch == null && pullRequest == null)
-      || (branch != null && !branch.equals(componentBranch))
-      || (pullRequest != null && !pullRequest.equals(branchDto.getPullRequestKey())));
+    if (UNKNOWN_COMPONENT.equals(component) || (pullRequest == null && branch == null)) {
+      builder.mainBranch(true);
+    } else {
+      BranchDto branchDto = findComponentBranch(session, component);
+      builder.mainBranch(branchDto.isMain());
+    }
   }
 }
index 8062598b86908ea713daa14f8f18bec914c2cff1..7e87e861928039f956a97b773d415eb9e500f5ea 100644 (file)
@@ -179,9 +179,6 @@ public class IssuesAction implements BatchWsAction {
   private ComponentDto loadComponent(DbSession dbSession, Request request) {
     String componentKey = request.mandatoryParam(PARAM_KEY);
     String branch = request.param(PARAM_BRANCH);
-    if (branch != null) {
-      return componentFinder.getByKeyAndBranch(dbSession, componentKey, branch);
-    }
-    return componentFinder.getByKey(dbSession, componentKey);
+    return componentFinder.getByKeyAndOptionalBranchOrPullRequest(dbSession, componentKey, branch, null);
   }
 }
index b3daf2cb87d7abab7562559ea852ce808d0c90af..b61e817fccf4f94562a21127ba920accdbb33eb5 100644 (file)
@@ -58,7 +58,7 @@ public class ComponentFinder {
     checkByUuidOrKey(componentUuid, componentKey, parameterNames);
 
     if (componentUuid != null) {
-      return getByUuid(dbSession, checkParamNotEmpty(componentUuid, parameterNames.getUuidParam()));
+      return getByUuidFromMainBranch(dbSession, checkParamNotEmpty(componentUuid, parameterNames.getUuidParam()));
     }
 
     return getByKey(dbSession, checkParamNotEmpty(componentKey, parameterNames.getKeyParam()));
@@ -100,6 +100,11 @@ public class ComponentFinder {
     return value;
   }
 
+  public BranchDto getBranchByUuid(DbSession dbSession, String branchUuid) {
+    return dbClient.branchDao().selectByUuid(dbSession, branchUuid)
+      .orElseThrow(() -> new NotFoundException(String.format("Branch uuid '%s' not found", branchUuid)));
+  }
+
   public BranchDto getBranchOrPullRequest(DbSession dbSession, ComponentDto project, @Nullable String branchKey, @Nullable String pullRequestKey) {
     return getBranchOrPullRequest(dbSession, project.uuid(), project.getKey(), branchKey, pullRequestKey);
   }
@@ -137,11 +142,14 @@ public class ComponentFinder {
     return checkComponent(dbClient.componentDao().selectByKey(dbSession, key), "%s key '%s' not found", label, key);
   }
 
-  public ComponentDto getByUuid(DbSession dbSession, String uuid) {
-    return getByUuid(dbSession, uuid, LABEL_COMPONENT);
+  /**
+   * This method only returns components in main branches.
+   */
+  public ComponentDto getByUuidFromMainBranch(DbSession dbSession, String uuid) {
+    return getByUuidFromMainBranch(dbSession, uuid, LABEL_COMPONENT);
   }
 
-  private ComponentDto getByUuid(DbSession dbSession, String uuid, String label) {
+  private ComponentDto getByUuidFromMainBranch(DbSession dbSession, String uuid, String label) {
     return checkComponent(dbClient.componentDao().selectByUuid(dbSession, uuid), "%s id '%s' not found", label, uuid);
   }
 
@@ -155,7 +163,7 @@ public class ComponentFinder {
   public ComponentDto getRootComponentByUuidOrKey(DbSession dbSession, @Nullable String projectUuid, @Nullable String projectKey) {
     ComponentDto project;
     if (projectUuid != null) {
-      project = getByUuid(dbSession, projectUuid, LABEL_PROJECT);
+      project = getByUuidFromMainBranch(dbSession, projectUuid, LABEL_PROJECT);
     } else {
       project = getByKey(dbSession, projectKey, LABEL_PROJECT);
     }
@@ -204,14 +212,22 @@ public class ComponentFinder {
     checkArgument(branch == null || pullRequest == null, "Either branch or pull request can be provided, not both");
     if (branch != null) {
       return getByKeyAndBranch(dbSession, key, branch);
-    }
-    if (pullRequest != null) {
+    } else if (pullRequest != null) {
       return getByKeyAndPullRequest(dbSession, key, pullRequest);
     }
-
     return getByKey(dbSession, key);
   }
 
+  public Optional<ComponentDto> getOptionalByKeyAndOptionalBranchOrPullRequest(DbSession dbSession, String key, @Nullable String branch, @Nullable String pullRequest) {
+    checkArgument(branch == null || pullRequest == null, "Either branch or pull request can be provided, not both");
+    if (branch != null) {
+      return dbClient.componentDao().selectByKeyAndBranch(dbSession, key, branch);
+    } else if (pullRequest != null) {
+      return dbClient.componentDao().selectByKeyAndPullRequest(dbSession, key, pullRequest);
+    }
+    return dbClient.componentDao().selectByKey(dbSession, key);
+  }
+
   public enum ParamNames {
     PROJECT_ID_AND_KEY("projectId", "projectKey"),
     PROJECT_UUID_AND_KEY("projectUuid", "projectKey"),
index a4e4746278ba41b417cdca352d5a54edb093b7da..ca42f019916b811201cbaa202781dff1e7db7eac 100644 (file)
@@ -33,6 +33,7 @@ import org.sonar.api.server.ws.WebService;
 import org.sonar.api.web.UserRole;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
+import org.sonar.db.component.BranchDto;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.component.SnapshotDto;
 import org.sonar.db.project.ProjectDto;
@@ -152,6 +153,13 @@ public class ShowAction implements ComponentsWsAction {
       Optional<ProjectDto> parentProject = dbClient.projectDao().selectByUuid(dbSession,
         ofNullable(component.getMainBranchProjectUuid()).orElse(component.branchUuid()));
       boolean needIssueSync = needIssueSync(dbSession, component, parentProject.orElse(null));
+      if (component.getCopyComponentUuid() != null) {
+        String branch = dbClient.branchDao().selectByUuid(dbSession, component.getCopyComponentUuid())
+          .map(BranchDto::getKey)
+          .orElse(null);
+        componentDtoToWsComponent(component, parentProject.orElse(null), lastAnalysis, branch, null)
+          .setNeedIssueSync(needIssueSync);
+      }
       return componentDtoToWsComponent(component, parentProject.orElse(null), lastAnalysis, request.branch, request.pullRequest)
         .setNeedIssueSync(needIssueSync);
     }
index 400e85f255733e5c023ac95442378de92a6da06d..bd5c813bf02d1758a1d26054d77f3ed385020945 100644 (file)
@@ -89,7 +89,7 @@ public class SuggestionsAction implements ComponentsWsAction {
   private final UserSession userSession;
   private final ResourceTypes resourceTypes;
 
-  private DbClient dbClient;
+  private final DbClient dbClient;
 
   public SuggestionsAction(DbClient dbClient, ComponentIndex index, FavoriteFinder favoriteFinder, UserSession userSession, ResourceTypes resourceTypes) {
     this.dbClient = dbClient;
index 246af12da7b61137c467df34f1c266eaf8573080..16635cf1c3c32931ea1ae97fe57e60cc888df118 100644 (file)
@@ -31,6 +31,7 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
+import java.util.stream.Collectors;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 import org.sonar.api.resources.Qualifiers;
@@ -45,6 +46,7 @@ import org.sonar.core.i18n.I18n;
 import org.sonar.core.util.stream.MoreCollectors;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
+import org.sonar.db.component.BranchDto;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.component.ComponentTreeQuery;
 import org.sonar.db.component.ComponentTreeQuery.Strategy;
@@ -67,8 +69,8 @@ import static org.sonar.server.component.ws.ComponentDtoToWsComponent.projectOrA
 import static org.sonar.server.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001;
 import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
 import static org.sonar.server.ws.KeyExamples.KEY_PULL_REQUEST_EXAMPLE_001;
-import static org.sonar.server.ws.WsParameterBuilder.createQualifiersParameter;
 import static org.sonar.server.ws.WsParameterBuilder.QualifierParameterContext.newQualifierParameterContext;
+import static org.sonar.server.ws.WsParameterBuilder.createQualifiersParameter;
 import static org.sonar.server.ws.WsUtils.writeProtobuf;
 import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_TREE;
 import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_BRANCH;
@@ -113,8 +115,8 @@ public class TreeAction implements ComponentsWsAction {
   public void define(WebService.NewController context) {
     WebService.NewAction action = context.createAction(ACTION_TREE)
       .setDescription(format("Navigate through components based on the chosen strategy.<br>" +
-        "Requires the following permission: 'Browse' on the specified project.<br>" +
-        "When limiting search with the %s parameter, directories are not returned.",
+          "Requires the following permission: 'Browse' on the specified project.<br>" +
+          "When limiting search with the %s parameter, directories are not returned.",
         Param.TEXT_QUERY))
       .setSince("5.4")
       .setResponseExample(getClass().getResource("tree-example.json"))
@@ -226,29 +228,38 @@ public class TreeAction implements ComponentsWsAction {
       .setTotal(paging.total())
       .build();
 
-    response.setBaseComponent(toWsComponent(dbSession, baseComponent, referenceComponentsByUuid, request));
+    Map<String, String> branchKeyByReferenceUuid = dbClient.branchDao().selectByUuids(dbSession, referenceComponentsByUuid.keySet())
+      .stream()
+      .collect(Collectors.toMap(BranchDto::getUuid, BranchDto::getBranchKey));
+
+    response.setBaseComponent(toWsComponent(dbSession, baseComponent, referenceComponentsByUuid, branchKeyByReferenceUuid, request));
     for (ComponentDto dto : components) {
-      response.addComponents(toWsComponent(dbSession, dto, referenceComponentsByUuid, request));
+      response.addComponents(toWsComponent(dbSession, dto, referenceComponentsByUuid, branchKeyByReferenceUuid, request));
     }
 
     return response.build();
   }
 
   private Components.Component.Builder toWsComponent(DbSession dbSession, ComponentDto component,
-    Map<String, ComponentDto> referenceComponentsByUuid, Request request) {
+    Map<String, ComponentDto> referenceComponentsByUuid, Map<String, String> branchKeyByReferenceUuid, Request request) {
+
+    ComponentDto referenceComponent = referenceComponentsByUuid.get(component.getCopyComponentUuid());
 
     Components.Component.Builder wsComponent;
-    if (component.getMainBranchProjectUuid() == null && component.isRootProject() &&
-      PROJECT_OR_APP_QUALIFIERS.contains(component.qualifier())) {
+    if (component.getMainBranchProjectUuid() == null && component.isRootProject() && PROJECT_OR_APP_QUALIFIERS.contains(component.qualifier())) {
       ProjectDto projectDto = componentFinder.getProjectOrApplicationByKey(dbSession, component.getKey());
       wsComponent = projectOrAppToWsComponent(projectDto, null);
     } else {
       Optional<ProjectDto> parentProject = dbClient.projectDao().selectByUuid(dbSession,
         ofNullable(component.getMainBranchProjectUuid()).orElse(component.branchUuid()));
-      wsComponent = componentDtoToWsComponent(component, parentProject.orElse(null), null, request.branch, request.pullRequest);
+
+      if (referenceComponent != null) {
+        wsComponent = componentDtoToWsComponent(component, parentProject.orElse(null), null, branchKeyByReferenceUuid.get(referenceComponent.uuid()), null);
+      } else {
+        wsComponent = componentDtoToWsComponent(component, parentProject.orElse(null), null, request.branch, request.pullRequest);
+      }
     }
 
-    ComponentDto referenceComponent = referenceComponentsByUuid.get(component.getCopyComponentUuid());
     if (referenceComponent != null) {
       wsComponent.setRefId(referenceComponent.uuid());
       wsComponent.setRefKey(referenceComponent.getKey());
index ee557d8bcc485edfa107b6f869eb68927e2f5ae6..acafbc18aa87039c3537950f248bb7a402092ae9 100644 (file)
@@ -23,6 +23,7 @@ import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.function.Predicate;
@@ -37,9 +38,9 @@ import org.sonar.api.web.UserRole;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.component.BranchDto;
-import org.sonar.db.component.ComponentDto;
 import org.sonar.db.component.SnapshotDto;
 import org.sonar.db.event.EventDto;
+import org.sonar.db.project.ProjectDto;
 import org.sonar.server.issue.index.IssueIndex;
 import org.sonar.server.issue.index.IssueIndexSyncProgressChecker;
 import org.sonar.server.issue.index.ProjectStatistics;
@@ -77,8 +78,7 @@ public class SearchEventsAction implements DevelopersWsAction {
   private final IssueIndex issueIndex;
   private final IssueIndexSyncProgressChecker issueIndexSyncProgressChecker;
 
-  public SearchEventsAction(DbClient dbClient, UserSession userSession, Server server, IssueIndex issueIndex,
-    IssueIndexSyncProgressChecker issueIndexSyncProgressChecker) {
+  public SearchEventsAction(DbClient dbClient, UserSession userSession, Server server, IssueIndex issueIndex, IssueIndexSyncProgressChecker issueIndexSyncProgressChecker) {
     this.dbClient = dbClient;
     this.userSession = userSession;
     this.server = server;
@@ -132,8 +132,8 @@ public class SearchEventsAction implements DevelopersWsAction {
     }
 
     try (DbSession dbSession = dbClient.openSession(false)) {
-      List<ComponentDto> authorizedProjects = searchProjects(dbSession, projectKeys);
-      Map<String, ComponentDto> componentsByUuid = authorizedProjects.stream().collect(uniqueIndex(ComponentDto::uuid));
+      List<ProjectDto> authorizedProjects = searchProjects(dbSession, projectKeys);
+      Map<String, ProjectDto> projectsByUuid = authorizedProjects.stream().collect(uniqueIndex(ProjectDto::getUuid));
       List<UuidFromPair> uuidFromPairs = componentUuidFromPairs(fromDates, projectKeys, authorizedProjects);
       List<SnapshotDto> analyses = dbClient.snapshotDao().selectFinishedByComponentUuidsAndFromDates(dbSession, componentUuids(uuidFromPairs), fromDates(uuidFromPairs));
 
@@ -145,12 +145,12 @@ public class SearchEventsAction implements DevelopersWsAction {
       Map<String, BranchDto> branchesByUuids = dbClient.branchDao().selectByUuids(dbSession, projectUuids).stream().collect(uniqueIndex(BranchDto::getUuid));
 
       return Stream.concat(
-        computeQualityGateChangeEvents(dbSession, componentsByUuid, branchesByUuids, analyses),
-        computeNewIssuesEvents(componentsByUuid, branchesByUuids, uuidFromPairs));
+        computeQualityGateChangeEvents(dbSession, projectsByUuid, branchesByUuids, analyses),
+        computeNewIssuesEvents(projectsByUuid, branchesByUuids, uuidFromPairs));
     }
   }
 
-  private Stream<Event> computeQualityGateChangeEvents(DbSession dbSession, Map<String, ComponentDto> projectsByUuid,
+  private Stream<Event> computeQualityGateChangeEvents(DbSession dbSession, Map<String, ProjectDto> projectsByUuid,
     Map<String, BranchDto> branchesByUuids,
     List<SnapshotDto> analyses) {
     Map<String, EventDto> eventsByComponentUuid = new HashMap<>();
@@ -167,20 +167,20 @@ public class SearchEventsAction implements DevelopersWsAction {
       .filter(branchPredicate)
       .map(e -> {
         BranchDto branch = branchesByUuids.get(e.getComponentUuid());
-        ComponentDto project = projectsByUuid.get(branch.getProjectUuid());
+        ProjectDto project = projectsByUuid.get(branch.getProjectUuid());
         checkState(project != null, "Found event '%s', for a component that we did not search for", e.getUuid());
         return Event.newBuilder()
           .setCategory(EventCategory.fromLabel(e.getCategory()).name())
           .setProject(project.getKey())
-          .setMessage(branch.isMain() ? format("Quality Gate status of project '%s' changed to '%s'", project.name(), e.getName())
-            : format("Quality Gate status of project '%s' on branch '%s' changed to '%s'", project.name(), branch.getKey(), e.getName()))
+          .setMessage(branch.isMain() ? format("Quality Gate status of project '%s' changed to '%s'", project.getName(), e.getName())
+            : format("Quality Gate status of project '%s' on branch '%s' changed to '%s'", project.getName(), branch.getKey(), e.getName()))
           .setLink(computeDashboardLink(project, branch))
           .setDate(formatDateTime(e.getDate()))
           .build();
       });
   }
 
-  private Stream<Event> computeNewIssuesEvents(Map<String, ComponentDto> projectsByUuid, Map<String, BranchDto> branchesByUuids,
+  private Stream<Event> computeNewIssuesEvents(Map<String, ProjectDto> projectsByUuid, Map<String, BranchDto> branchesByUuids,
     List<UuidFromPair> uuidFromPairs) {
     Map<String, Long> fromsByProjectUuid = uuidFromPairs.stream().collect(Collectors.toMap(
       UuidFromPair::getComponentUuid,
@@ -190,46 +190,46 @@ public class SearchEventsAction implements DevelopersWsAction {
       .stream()
       .map(e -> {
         BranchDto branch = branchesByUuids.get(e.getProjectUuid());
-        ComponentDto project = projectsByUuid.get(branch.getProjectUuid());
+        ProjectDto project = projectsByUuid.get(branch.getProjectUuid());
         long issueCount = e.getIssueCount();
         long lastIssueDate = e.getLastIssueDate();
         String branchType = branch.getBranchType().equals(PULL_REQUEST) ? "pull request" : "branch";
         return Event.newBuilder()
           .setCategory("NEW_ISSUES")
           .setMessage(format("You have %s new %s on project '%s'", issueCount, issueCount == 1 ? "issue" : "issues",
-            project.name()) + (branch.isMain() ? "" : format(" on %s '%s'", branchType, branch.getKey())))
-          .setLink(computeIssuesSearchLink(project, branch, fromsByProjectUuid.get(project.uuid()), userSession.getLogin()))
+            project.getName()) + (branch.isMain() ? "" : format(" on %s '%s'", branchType, branch.getKey())))
+          .setLink(computeIssuesSearchLink(project, branch, fromsByProjectUuid.get(project.getUuid()), userSession.getLogin()))
           .setProject(project.getKey())
           .setDate(formatDateTime(lastIssueDate))
           .build();
       });
   }
 
-  private List<ComponentDto> searchProjects(DbSession dbSession, List<String> projectKeys) {
-    List<ComponentDto> projects = dbClient.componentDao().selectByKeys(dbSession, projectKeys);
-    return userSession.keepAuthorizedComponents(UserRole.USER, projects);
+  private List<ProjectDto> searchProjects(DbSession dbSession, List<String> projectKeys) {
+    List<ProjectDto> projects = dbClient.projectDao().selectProjectsByKeys(dbSession, new HashSet<>(projectKeys));
+    return userSession.keepAuthorizedProjects(UserRole.USER, projects);
   }
 
-  private String computeIssuesSearchLink(ComponentDto component, BranchDto branch, long functionalFromDate, String login) {
+  private String computeIssuesSearchLink(ProjectDto project, BranchDto branch, long functionalFromDate, String login) {
     String branchParam = branch.getBranchType().equals(PULL_REQUEST) ? "pullRequest" : "branch";
     String link = format("%s/project/issues?id=%s&createdAfter=%s&assignees=%s&resolved=false",
-      server.getPublicRootUrl(), encode(component.getKey()), encode(formatDateTime(functionalFromDate)), encode(login));
+      server.getPublicRootUrl(), encode(project.getKey()), encode(formatDateTime(functionalFromDate)), encode(login));
     link += branch.isMain() ? "" : format("&%s=%s", branchParam, encode(branch.getKey()));
     return link;
   }
 
-  private String computeDashboardLink(ComponentDto component, BranchDto branch) {
-    String link = server.getPublicRootUrl() + "/dashboard?id=" + encode(component.getKey());
+  private String computeDashboardLink(ProjectDto project, BranchDto branch) {
+    String link = server.getPublicRootUrl() + "/dashboard?id=" + encode(project.getKey());
     link += branch.isMain() ? "" : format("&branch=%s", encode(branch.getKey()));
     return link;
   }
 
-  private static List<UuidFromPair> componentUuidFromPairs(List<Long> fromDates, List<String> projectKeys, List<ComponentDto> authorizedProjects) {
+  private static List<UuidFromPair> componentUuidFromPairs(List<Long> fromDates, List<String> projectKeys, List<ProjectDto> authorizedProjects) {
     checkRequest(projectKeys.size() == fromDates.size(), "The number of components (%s) and from dates (%s) must be the same.", projectKeys.size(), fromDates.size());
     Map<String, Long> fromDatesByProjectKey = IntStream.range(0, projectKeys.size()).boxed()
       .collect(uniqueIndex(projectKeys::get, fromDates::get));
     return authorizedProjects.stream()
-      .map(dto -> new UuidFromPair(dto.uuid(), fromDatesByProjectKey.get(dto.getKey())))
+      .map(dto -> new UuidFromPair(dto.getUuid(), fromDatesByProjectKey.get(dto.getKey())))
       .collect(toList(authorizedProjects.size()));
   }
 
index 01adf616c0ba848bc5a455730362d1029aca0af5..57db08dae40f6eebe6d15d0e38676e79b9e61b55 100644 (file)
@@ -39,14 +39,15 @@ import org.sonar.api.server.ServerSide;
 import org.sonar.db.DbSession;
 import org.sonar.db.component.ComponentDao;
 import org.sonar.db.component.ComponentDto;
+import org.sonar.server.component.ComponentFinder;
 
 @ServerSide
 public class DuplicationsParser {
   private static final BlockComparator BLOCK_COMPARATOR = new BlockComparator();
-  private final ComponentDao componentDao;
+  private final ComponentFinder componentFinder;
 
-  public DuplicationsParser(ComponentDao componentDao) {
-    this.componentDao = componentDao;
+  public DuplicationsParser(ComponentFinder componentFinder) {
+    this.componentFinder = componentFinder;
   }
 
   public List<Block> parse(DbSession session, ComponentDto component, @Nullable String branch, @Nullable String pullRequest, @Nullable String duplicationsData) {
@@ -113,13 +114,7 @@ public class DuplicationsParser {
 
   @CheckForNull
   private ComponentDto loadComponent(DbSession session, String componentKey, @Nullable String branch, @Nullable String pullRequest) {
-    if (branch != null) {
-      return componentDao.selectByKeyAndBranch(session, componentKey, branch).orElse(null);
-    } else if (pullRequest != null) {
-      return componentDao.selectByKeyAndPullRequest(session, componentKey, pullRequest).orElse(null);
-    } else {
-      return componentDao.selectByKey(session, componentKey).orElse(null);
-    }
+    return componentFinder.getOptionalByKeyAndOptionalBranchOrPullRequest(session, componentKey, branch, pullRequest).orElse(null);
   }
 
   private static String convertToKey(String dbKey) {
index 899372371a548fefe4bb70da688ef124a8126a11..037b7fc34c0a03d99de90154914d87f31b1eec81 100644 (file)
@@ -108,9 +108,8 @@ public class ShowResponseBuilder {
 
   private static Duplications.File toWsFile(String componentKey, @Nullable String branch, @Nullable String pullRequest) {
     Duplications.File.Builder wsFile = Duplications.File.newBuilder();
-    String keyWithoutBranch = ComponentDto.removeBranchAndPullRequestFromKey(componentKey);
-    wsFile.setKey(keyWithoutBranch);
-    wsFile.setName(StringUtils.substringAfterLast(keyWithoutBranch, ":"));
+    wsFile.setKey(componentKey);
+    wsFile.setName(StringUtils.substringAfterLast(componentKey, ":"));
     ofNullable(branch).ifPresent(wsFile::setBranch);
     ofNullable(pullRequest).ifPresent(wsFile::setPullRequest);
     return wsFile.build();
index f30266a6636b350b6af4a2ce3726fcfa983d1b3f..ac108f7654df7d7d39e0aa591600f0672d80a72b 100644 (file)
@@ -56,6 +56,7 @@ import org.sonar.db.issue.IssueDto;
 import org.sonar.db.project.ProjectDto;
 import org.sonar.db.protobuf.DbIssues;
 import org.sonar.db.rule.RuleDto;
+import org.sonar.server.component.ComponentFinder;
 import org.sonar.server.es.SearchOptions;
 import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.issue.TextRangeResponseFormatter;
@@ -130,9 +131,10 @@ public class SearchAction implements HotspotsWsAction {
   private final HotspotWsResponseFormatter responseFormatter;
   private final TextRangeResponseFormatter textRangeFormatter;
   private final System2 system2;
+  private final ComponentFinder componentFinder;
 
   public SearchAction(DbClient dbClient, UserSession userSession, IssueIndex issueIndex, IssueIndexSyncProgressChecker issueIndexSyncProgressChecker,
-    HotspotWsResponseFormatter responseFormatter, TextRangeResponseFormatter textRangeFormatter, System2 system2) {
+    HotspotWsResponseFormatter responseFormatter, TextRangeResponseFormatter textRangeFormatter, System2 system2, ComponentFinder componentFinder) {
     this.dbClient = dbClient;
     this.userSession = userSession;
     this.issueIndex = issueIndex;
@@ -140,6 +142,7 @@ public class SearchAction implements HotspotsWsAction {
     this.responseFormatter = responseFormatter;
     this.textRangeFormatter = textRangeFormatter;
     this.system2 = system2;
+    this.componentFinder = componentFinder;
   }
 
   private static Set<String> setFromList(@Nullable List<String> list) {
@@ -318,23 +321,18 @@ public class SearchAction implements HotspotsWsAction {
 
   private Optional<ComponentDto> getAndValidateProjectOrApplication(DbSession dbSession, WsRequest wsRequest) {
     return wsRequest.getProjectKey().map(projectKey -> {
-      ComponentDto project = getProject(dbSession, projectKey, wsRequest.getBranch().orElse(null), wsRequest.getPullRequest().orElse(null))
-        .filter(t -> Scopes.PROJECT.equals(t.scope()) && SUPPORTED_QUALIFIERS.contains(t.qualifier()))
-        .filter(ComponentDto::isEnabled)
-        .orElseThrow(() -> new NotFoundException(format("Project '%s' not found", projectKey)));
+      ComponentDto project = getProject(dbSession, projectKey, wsRequest.getBranch().orElse(null), wsRequest.getPullRequest().orElse(null));
+      if (!Scopes.PROJECT.equals(project.scope()) || !SUPPORTED_QUALIFIERS.contains(project.qualifier()) || !project.isEnabled()) {
+        throw new NotFoundException(format("Project '%s' not found", projectKey));
+      }
       userSession.checkComponentPermission(USER, project);
       userSession.checkChildProjectsPermission(USER, project);
       return project;
     });
   }
 
-  private Optional<ComponentDto> getProject(DbSession dbSession, String projectKey, @Nullable String branch, @Nullable String pullRequest) {
-    if (branch != null) {
-      return dbClient.componentDao().selectByKeyAndBranch(dbSession, projectKey, branch);
-    } else if (pullRequest != null) {
-      return dbClient.componentDao().selectByKeyAndPullRequest(dbSession, projectKey, pullRequest);
-    }
-    return dbClient.componentDao().selectByKey(dbSession, projectKey);
+  private ComponentDto getProject(DbSession dbSession, String projectKey, @Nullable String branch, @Nullable String pullRequest) {
+    return componentFinder.getByKeyAndOptionalBranchOrPullRequest(dbSession, projectKey, branch, pullRequest);
   }
 
   private SearchResponseData searchHotspots(WsRequest wsRequest, DbSession dbSession, @Nullable ComponentDto project) {
@@ -527,7 +525,7 @@ public class SearchAction implements HotspotsWsAction {
       List<ComponentDto> componentDtos = dbClient.componentDao().selectByUuids(dbSession, aggregatedComponentUuids);
       searchResponseData.addComponents(componentDtos);
 
-      Set<String> branchUuids = componentDtos.stream().map(ComponentDto::branchUuid).collect(Collectors.toSet());
+      Set<String> branchUuids = componentDtos.stream().map(c -> c.getCopyComponentUuid() != null ? c.getCopyComponentUuid() : c.branchUuid()).collect(Collectors.toSet());
       List<BranchDto> branchDtos = dbClient.branchDao().selectByUuids(dbSession, branchUuids);
       searchResponseData.addBranches(branchDtos);
     }
@@ -638,7 +636,8 @@ public class SearchAction implements HotspotsWsAction {
 
     Hotspots.Component.Builder builder = Hotspots.Component.newBuilder();
     for (ComponentDto component : components) {
-      BranchDto branchDto = searchResponseData.getBranch(component.branchUuid());
+      String branchUuid = component.getCopyComponentUuid() != null ? component.getCopyComponentUuid() : component.branchUuid();
+      BranchDto branchDto = searchResponseData.getBranch(branchUuid);
       if (branchDto == null) {
         throw new IllegalStateException("Could not find a branch for a component " + component.getKey() + " with uuid " + component.uuid());
       }
index 335aca838a5b860a05570369a3a443c35d8163da..938b6629a38361de5552f4d277d1836ad4e10de0 100644 (file)
@@ -54,7 +54,7 @@ public class SearchResponseData {
   private final ListMultimap<String, String> actionsByIssueKey = ArrayListMultimap.create();
   private final ListMultimap<String, Transition> transitionsByIssueKey = ArrayListMultimap.create();
   private final Set<String> updatableComments = new HashSet<>();
-  private final Map<String, BranchDto> branchesByBranchUuid = new HashMap<>();
+  private final Map<String, BranchDto> branchesByUuid = new HashMap<>();
 
   public SearchResponseData(IssueDto issue) {
     checkNotNull(issue);
@@ -143,12 +143,12 @@ public class SearchResponseData {
 
   public void addBranches(List<BranchDto> branchDtos) {
     for (BranchDto branch : branchDtos) {
-      branchesByBranchUuid.put(branch.getUuid(), branch);
+      branchesByUuid.put(branch.getUuid(), branch);
     }
   }
 
   public BranchDto getBranch(String branchUuid) {
-    return branchesByBranchUuid.get(branchUuid);
+    return branchesByUuid.get(branchUuid);
   }
 
   void addActions(String issueKey, Iterable<String> actions) {
index 702f183ffafbb0ed4d854251ca1e0495ae650497..541788dfe086371f068821c9a914d039b8c22f7d 100644 (file)
@@ -316,16 +316,21 @@ public class SearchResponseFormat {
   }
 
   private static void setBranchOrPr(ComponentDto componentDto, Component.Builder builder, SearchResponseData data) {
-    BranchDto branchDto = data.getBranch(componentDto.branchUuid());
+    String branchUuid = componentDto.getCopyComponentUuid() != null ? componentDto.getCopyComponentUuid() : componentDto.branchUuid();
+    BranchDto branchDto = data.getBranch(branchUuid);
     if (branchDto.isMain()) {
       return;
     }
-    builder.setBranch(branchDto.getBranchKey());
-    builder.setPullRequest(branchDto.getPullRequestKey());
+    if (branchDto.getBranchType() == BranchType.BRANCH) {
+      builder.setBranch(branchDto.getKey());
+    } else if (branchDto.getBranchType() == BranchType.PULL_REQUEST) {
+      builder.setPullRequest(branchDto.getKey());
+    }
   }
 
   private static void setBranchOrPr(ComponentDto componentDto, Issue.Builder builder, SearchResponseData data) {
-    BranchDto branchDto = data.getBranch(componentDto.branchUuid());
+    String branchUuid = componentDto.getCopyComponentUuid() != null ? componentDto.getCopyComponentUuid() : componentDto.branchUuid();
+    BranchDto branchDto = data.getBranch(branchUuid);
     if (branchDto.isMain()) {
       return;
     }
index 953ec69799c209ca7e2343b222cb078795cbe346..cca95b3d8338b6b5cbaf7b1458424e09562f30f3 100644 (file)
@@ -155,7 +155,9 @@ public class SearchResponseLoader {
   }
 
   private void loadBranches(DbSession dbSession, SearchResponseData result) {
-    Set<String> branchUuids = result.getComponents().stream().map(ComponentDto::branchUuid).collect(Collectors.toSet());
+    Set<String> branchUuids = result.getComponents().stream()
+      .map(c -> c.getCopyComponentUuid() != null ? c.getCopyComponentUuid() : c.branchUuid())
+      .collect(Collectors.toSet());
     List<BranchDto> branchDtos = dbClient.branchDao().selectByUuids(dbSession, branchUuids);
     result.addBranches(branchDtos);
   }
@@ -178,7 +180,7 @@ public class SearchResponseLoader {
     result.addRules(preloadedRules);
     Set<String> ruleUuidsToLoad = collector.getRuleUuids();
     preloadedRules.stream().map(RuleDto::getUuid).collect(toList(preloadedRules.size()))
-        .forEach(ruleUuidsToLoad::remove);
+      .forEach(ruleUuidsToLoad::remove);
 
     List<RuleDto> rules = dbClient.ruleDao().selectByUuids(dbSession, ruleUuidsToLoad);
     updateNamesOfAdHocRules(rules);
@@ -191,7 +193,6 @@ public class SearchResponseLoader {
       .forEach(r -> r.setName(r.getAdHocName()));
   }
 
-
   private void loadComments(Collector collector, DbSession dbSession, Set<SearchAdditionalField> fields, SearchResponseData result) {
     if (fields.contains(COMMENTS)) {
       List<IssueChangeDto> comments = dbClient.issueChangeDao().selectByTypeAndIssueKeys(dbSession, collector.getIssueKeys(), IssueChangeDto.TYPE_COMMENT);
index b645521e72da66ab5c6e73567852d38a681b6733..bdbbeaeb817dd35cabcdafb9dbbe24745d46ced4 100644 (file)
@@ -243,12 +243,13 @@ public class ComponentAction implements MeasuresWsAction {
   private static ComponentWsResponse buildResponse(ComponentRequest request, ComponentDto component, Optional<ComponentDto> refComponent,
     Map<MetricDto, LiveMeasureDto> measuresByMetric, Collection<MetricDto> metrics, Optional<Measures.Period> period) {
     ComponentWsResponse.Builder response = ComponentWsResponse.newBuilder();
+    boolean isMainBranch = component.getMainBranchProjectUuid() == null;
 
     if (refComponent.isPresent()) {
       response.setComponent(componentDtoToWsComponent(component, measuresByMetric, singletonMap(refComponent.get().uuid(),
-        refComponent.get()), request.getBranch(), request.getPullRequest()));
+        refComponent.get()), isMainBranch ? null : request.getBranch(), request.getPullRequest()));
     } else {
-      response.setComponent(componentDtoToWsComponent(component, measuresByMetric, emptyMap(), request.getBranch(), request.getPullRequest()));
+      response.setComponent(componentDtoToWsComponent(component, measuresByMetric, emptyMap(), isMainBranch ? null : request.getBranch(), request.getPullRequest()));
     }
 
     List<String> additionalFields = request.getAdditionalFields();
index 03a61ca8782f7f35ffc2bee61845e716588c1d20..6d822a5add5312c274fb49eec6d9e77ca7fbc943 100644 (file)
@@ -40,6 +40,7 @@ import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
 import java.util.function.Function;
+import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
@@ -58,6 +59,7 @@ import org.sonar.core.i18n.I18n;
 import org.sonar.core.util.stream.MoreCollectors;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
+import org.sonar.db.component.BranchDto;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.component.ComponentTreeQuery;
 import org.sonar.db.component.ComponentTreeQuery.Strategy;
@@ -294,10 +296,18 @@ public class ComponentTreeAction implements MeasuresWsAction {
         data.getReferenceComponentsByUuid(), request.getBranch(), request.getPullRequest()));
 
     for (ComponentDto componentDto : data.getComponents()) {
-      response.addComponents(toWsComponent(
-        componentDto,
-        data.getMeasuresByComponentUuidAndMetric().row(componentDto.uuid()),
-        data.getReferenceComponentsByUuid(), request.getBranch(), request.getPullRequest()));
+      if (componentDto.getCopyComponentUuid() != null) {
+        String branch = data.getBranchByReferenceUuid().get(componentDto.getCopyComponentUuid());
+        response.addComponents(toWsComponent(
+          componentDto,
+          data.getMeasuresByComponentUuidAndMetric().row(componentDto.uuid()),
+          data.getReferenceComponentsByUuid(), branch, null));
+      } else {
+        response.addComponents(toWsComponent(
+          componentDto,
+          data.getMeasuresByComponentUuidAndMetric().row(componentDto.uuid()),
+          data.getReferenceComponentsByUuid(), request.getBranch(), request.getPullRequest()));
+      }
     }
 
     if (areMetricsInResponse(request)) {
@@ -440,18 +450,26 @@ public class ComponentTreeAction implements MeasuresWsAction {
       int componentCount = components.size();
       components = paginateComponents(components, wsRequest);
 
+      Map<String, ComponentDto> referencesByUuid = searchReferenceComponentsById(dbSession, components);
+      Map<String, String> branchByReferenceUuid = searchReferenceBranchKeys(dbSession, referencesByUuid.keySet());
+
       return ComponentTreeData.builder()
         .setBaseComponent(baseComponent)
         .setComponentsFromDb(components)
         .setComponentCount(componentCount)
+        .setBranchByReferenceUuid(branchByReferenceUuid)
         .setMeasuresByComponentUuidAndMetric(measuresByComponentUuidAndMetric)
         .setMetrics(metrics)
         .setPeriod(snapshotToWsPeriods(baseSnapshot.get()).orElse(null))
-        .setReferenceComponentsByUuid(searchReferenceComponentsById(dbSession, components))
+        .setReferenceComponentsByUuid(referencesByUuid)
         .build();
     }
   }
 
+  private Map<String, String> searchReferenceBranchKeys(DbSession dbSession, Set<String> referenceUuids) {
+    return dbClient.branchDao().selectByUuids(dbSession, referenceUuids).stream().collect(Collectors.toMap(BranchDto::getUuid, BranchDto::getBranchKey));
+  }
+
   private static boolean isPR(@Nullable String pullRequest) {
     return pullRequest != null;
   }
@@ -460,9 +478,6 @@ public class ComponentTreeAction implements MeasuresWsAction {
     String componentKey = request.getComponent();
     String branch = request.getBranch();
     String pullRequest = request.getPullRequest();
-    if (branch == null && pullRequest == null) {
-      return componentFinder.getByKey(dbSession, componentKey);
-    }
     return componentFinder.getByKeyAndOptionalBranchOrPullRequest(dbSession, componentKey, branch, pullRequest);
   }
 
index 45fa18570d47fe2e7608e56f89fe40d15b704bf0..151c322bddfb9530bbe6af2d84d2f620ae50219e 100644 (file)
@@ -38,6 +38,7 @@ class ComponentTreeData {
   private final List<ComponentDto> components;
   private final int componentCount;
   private final Map<String, ComponentDto> referenceComponentsByUuid;
+  private final Map<String, String> branchByReferenceUuid;
   private final List<MetricDto> metrics;
   private final Measures.Period period;
   private final Table<String, MetricDto, Measure> measuresByComponentUuidAndMetric;
@@ -47,11 +48,16 @@ class ComponentTreeData {
     this.components = builder.componentsFromDb;
     this.componentCount = builder.componentCount;
     this.referenceComponentsByUuid = builder.referenceComponentsByUuid;
+    this.branchByReferenceUuid = builder.branchByReferenceUuid;
     this.metrics = builder.metrics;
     this.measuresByComponentUuidAndMetric = builder.measuresByComponentUuidAndMetric;
     this.period = builder.period;
   }
 
+  public Map<String, String> getBranchByReferenceUuid() {
+    return branchByReferenceUuid;
+  }
+
   public ComponentDto getBaseComponent() {
     return baseComponent;
   }
@@ -93,6 +99,7 @@ class ComponentTreeData {
     private ComponentDto baseComponent;
     private List<ComponentDto> componentsFromDb;
     private Map<String, ComponentDto> referenceComponentsByUuid;
+    private Map<String, String> branchByReferenceUuid;
     private int componentCount;
     private List<MetricDto> metrics;
     private Measures.Period period;
@@ -102,6 +109,11 @@ class ComponentTreeData {
       // private constructor
     }
 
+    public Builder setBranchByReferenceUuid(Map<String, String> branchByReferenceUuid) {
+      this.branchByReferenceUuid = branchByReferenceUuid;
+      return this;
+    }
+
     public Builder setBaseComponent(ComponentDto baseComponent) {
       this.baseComponent = baseComponent;
       return this;
index 12deba7ab252634be52b7b73b2846ed8ca028997..6048974fec220f8cf71436c9928acf234abb66b6 100644 (file)
@@ -49,7 +49,6 @@ import org.sonar.db.component.ComponentDto;
 import org.sonar.db.permission.GlobalPermission;
 import org.sonar.db.property.PropertyDto;
 import org.sonar.server.component.ComponentFinder;
-import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.Settings;
 import org.sonarqube.ws.Settings.ValuesWsResponse;
@@ -124,7 +123,8 @@ public class ValuesAction implements SettingsWsAction {
     try (DbSession dbSession = dbClient.openSession(true)) {
       ValuesRequest valuesRequest = ValuesRequest.from(request);
       Optional<ComponentDto> component = loadComponent(dbSession, valuesRequest);
-      BranchDto branchDto = loadBranch(dbSession, component);
+      // TODO can portfolios fail here?
+      BranchDto branchDto = component.map(c -> componentFinder.getBranchByUuid(dbSession, c.branchUuid())).orElse(null);
 
       Set<String> keys = loadKeys(valuesRequest);
       Map<String, String> keysToDisplayMap = getKeysToDisplayMap(keys);
@@ -133,14 +133,6 @@ public class ValuesAction implements SettingsWsAction {
     }
   }
 
-  private BranchDto loadBranch(DbSession dbSession, Optional<ComponentDto> component) {
-    if (component.isEmpty()) {
-      return null;
-    }
-    return dbClient.branchDao().selectByUuid(dbSession, component.get().branchUuid())
-      .orElseThrow(() -> new NotFoundException("Could not find a branch for component uuid " + component.get().branchUuid()));
-  }
-
   private Set<String> loadKeys(ValuesRequest valuesRequest) {
     List<String> keys = valuesRequest.getKeys();
     Set<String> result;
@@ -159,6 +151,7 @@ public class ValuesAction implements SettingsWsAction {
       return Optional.empty();
     }
     ComponentDto component = componentFinder.getByKey(dbSession, componentKey);
+
     if (!userSession.hasComponentPermission(USER, component) &&
       !userSession.hasComponentPermission(UserRole.SCAN, component) &&
       !userSession.hasPermission(GlobalPermission.SCAN)) {
@@ -174,7 +167,7 @@ public class ValuesAction implements SettingsWsAction {
     settings.addAll(loadGlobalSettings(dbSession, keys));
     String branch = getBranchKeySafely(branchDto);
     if (component.isPresent() && branch != null && component.get().getMainBranchProjectUuid() != null) {
-      ComponentDto project = dbClient.componentDao().selectOrFailByUuid(dbSession, component.get().getMainBranchProjectUuid());
+      ComponentDto project = componentFinder.getByUuidFromMainBranch(dbSession, component.get().getMainBranchProjectUuid());
       settings.addAll(loadComponentSettings(dbSession, keys, project).values());
     }
     component.ifPresent(componentDto -> settings.addAll(loadComponentSettings(dbSession, keys, componentDto).values()));
@@ -183,8 +176,9 @@ public class ValuesAction implements SettingsWsAction {
       .collect(Collectors.toList());
   }
 
+  @CheckForNull
   private String getBranchKeySafely(@Nullable BranchDto branchDto) {
-    if(branchDto != null) {
+    if (branchDto != null) {
       return branchDto.isMain() ? null : branchDto.getBranchKey();
     }
     return null;
index ce3b0d9ad6ebb46ca41151a6142f9d79fc5fcdf9..bb9746add894200b0aeb93ffa6e05c147cb08b55 100644 (file)
@@ -27,6 +27,7 @@ import java.util.Optional;
 import java.util.Set;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
+import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 import org.sonar.api.config.Configuration;
 import org.sonar.api.resources.Qualifiers;
@@ -43,7 +44,6 @@ import org.sonar.api.web.UserRole;
 import org.sonar.api.web.page.Page;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
-import org.sonar.db.component.BranchDto;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.component.SnapshotDto;
 import org.sonar.db.measure.LiveMeasureDto;
@@ -53,7 +53,6 @@ import org.sonar.db.property.PropertyQuery;
 import org.sonar.db.qualityprofile.QProfileDto;
 import org.sonar.server.component.ComponentFinder;
 import org.sonar.server.exceptions.BadRequestException;
-import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.project.Visibility;
 import org.sonar.server.qualitygate.QualityGateFinder;
 import org.sonar.server.qualityprofile.QPMeasureData;
@@ -153,20 +152,18 @@ public class ComponentAction implements NavigationWsAction {
       checkComponentNotAModuleAndNotADirectory(component);
       ComponentDto rootProjectOrBranch = getRootProjectOrBranch(component, session);
       ComponentDto rootProject = rootProjectOrBranch.getMainBranchProjectUuid() == null ? rootProjectOrBranch
-        : componentFinder.getByUuid(session, rootProjectOrBranch.getMainBranchProjectUuid());
+        : componentFinder.getByUuidFromMainBranch(session, rootProjectOrBranch.getMainBranchProjectUuid());
       if (!userSession.hasComponentPermission(USER, component) &&
         !userSession.hasComponentPermission(ADMIN, component) &&
         !userSession.isSystemAdministrator()) {
         throw insufficientPrivilegesException();
       }
       Optional<SnapshotDto> analysis = dbClient.snapshotDao().selectLastAnalysisByRootComponentUuid(session, component.branchUuid());
-      BranchDto branchDto = dbClient.branchDao().selectByUuid(session, component.branchUuid())
-        .orElseThrow(() -> new NotFoundException(format("Could not find a branch for component uuid " + component.uuid())));
 
       try (JsonWriter json = response.newJsonWriter()) {
         json.beginObject();
         boolean isFavourite = isFavourite(session, rootProject, component);
-        String branchKey = branchDto.isMain() ? null : branchDto.getBranchKey();
+        String branchKey = getBranchKey(session, component);
         writeComponent(json, component, analysis.orElse(null), isFavourite, branchKey);
         writeProfiles(json, session, component);
         writeQualityGate(json, session, rootProject);
@@ -181,6 +178,14 @@ public class ComponentAction implements NavigationWsAction {
     }
   }
 
+  @CheckForNull
+  private String getBranchKey(DbSession session, ComponentDto component) {
+    // TODO portfolios may have no branch, so we shouldn't faul?
+    return dbClient.branchDao().selectByUuid(session, component.branchUuid())
+      .map(b -> b.isMain() ? null : b.getBranchKey())
+      .orElse(null);
+  }
+
   private static void checkComponentNotAModuleAndNotADirectory(ComponentDto component) {
     BadRequestException.checkRequest(!MODULE_OR_DIR_QUALIFIERS.contains(component.qualifier()), "Operation not supported for module or directory components");
   }
@@ -209,7 +214,7 @@ public class ComponentAction implements NavigationWsAction {
       .endObject();
   }
 
-  private void writeComponent(JsonWriter json, ComponentDto component, @Nullable SnapshotDto analysis, boolean isFavourite, String branchKey) {
+  private void writeComponent(JsonWriter json, ComponentDto component, @Nullable SnapshotDto analysis, boolean isFavourite, @Nullable String branchKey) {
     json.prop("key", component.getKey())
       .prop("id", component.uuid())
       .prop("name", component.name())
index c4905efc0b5062e0a9c8b5b1e15bc974c58244bb..0a5376d0d4a049cea6bfb9ac7a64649e49a66760 100644 (file)
@@ -103,7 +103,7 @@ public class ComponentFinderTest {
     ComponentDto project = db.components().insertComponent(newPrivateProjectDto());
     db.components().insertComponent(newFileDto(project, null, "file-uuid").setEnabled(false));
 
-    assertThatThrownBy(() -> underTest.getByUuid(dbSession, "file-uuid"))
+    assertThatThrownBy(() -> underTest.getByUuidFromMainBranch(dbSession, "file-uuid"))
       .isInstanceOf(NotFoundException.class)
       .hasMessage("Component id 'file-uuid' not found");
   }
@@ -114,7 +114,7 @@ public class ComponentFinderTest {
     ComponentDto branch = db.components().insertProjectBranch(project);
 
     String branchUuid = branch.uuid();
-    assertThatThrownBy(() -> underTest.getByUuid(dbSession, branchUuid))
+    assertThatThrownBy(() -> underTest.getByUuidFromMainBranch(dbSession, branchUuid))
       .isInstanceOf(NotFoundException.class)
       .hasMessage(format("Component id '%s' not found", branchUuid));
   }
@@ -175,6 +175,33 @@ public class ComponentFinderTest {
     assertThat(underTest.getByKeyAndOptionalBranchOrPullRequest(dbSession, directory.getKey(), null, "pr-123").uuid()).isEqualTo(directory.uuid());
   }
 
+  @Test
+  public void get_optional_by_key_and_optional_branch_or_pull_request() {
+    ComponentDto project = db.components().insertPublicProject();
+    ComponentDto pr = db.components().insertProjectBranch(project, b -> b.setKey("pr").setBranchType(PULL_REQUEST));
+    ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("branch"));
+    ComponentDto branchFile = db.components().insertComponent(newFileDto(branch));
+
+
+    assertThat(underTest.getOptionalByKeyAndOptionalBranchOrPullRequest(dbSession, project.getKey(), null, null)).isPresent();
+    assertThat(underTest.getOptionalByKeyAndOptionalBranchOrPullRequest(dbSession, project.getKey(), null, null).get().uuid())
+      .isEqualTo(project.uuid());
+
+    assertThat(underTest.getOptionalByKeyAndOptionalBranchOrPullRequest(dbSession, branch.getKey(), "branch", null)).isPresent();
+    assertThat(underTest.getOptionalByKeyAndOptionalBranchOrPullRequest(dbSession, branch.getKey(), "branch", null).get().uuid())
+      .isEqualTo(branch.uuid());
+    assertThat(underTest.getOptionalByKeyAndOptionalBranchOrPullRequest(dbSession, branchFile.getKey(), "branch", null)).isPresent();
+    assertThat(underTest.getOptionalByKeyAndOptionalBranchOrPullRequest(dbSession, branchFile.getKey(), "branch", null).get().uuid())
+      .isEqualTo(branchFile.uuid());
+
+    assertThat(underTest.getOptionalByKeyAndOptionalBranchOrPullRequest(dbSession, pr.getKey(), null, "pr")).isPresent();
+    assertThat(underTest.getOptionalByKeyAndOptionalBranchOrPullRequest(dbSession, pr.getKey(), null, "pr").get().uuid())
+      .isEqualTo(pr.uuid());
+
+    assertThat(underTest.getOptionalByKeyAndOptionalBranchOrPullRequest(dbSession, "unknown", null, null)).isEmpty();
+
+  }
+
   @Test
   public void fail_when_pull_request_branch_provided() {
     ComponentDto project = db.components().insertPublicProject();
index fee559a446e994261ba8547bfb57d73b9fbbcd12..b761e96a01f190a902ec70c942895faadadbf323 100644 (file)
@@ -92,7 +92,7 @@ public class ComponentUpdaterTest {
     assertThat(loaded.moduleUuidPath()).isEqualTo("." + loaded.uuid() + ".");
     assertThat(loaded.isPrivate()).isEqualTo(project.isPrivate());
     assertThat(loaded.getCreatedAt()).isNotNull();
-    assertThat(db.getDbClient().componentDao().selectOrFailByKey(db.getSession(), DEFAULT_PROJECT_KEY)).isNotNull();
+    assertThat(db.getDbClient().componentDao().selectByKey(db.getSession(), DEFAULT_PROJECT_KEY)).isPresent();
 
     assertThat(projectIndexers.hasBeenCalled(loaded.uuid(), ProjectIndexer.Cause.PROJECT_CREATION)).isTrue();
 
index 2bdb91b031079e711d0488816b8209d64c97436c..88859bd69bb31fc2806496e666c7beaff6472d63 100644 (file)
@@ -280,7 +280,7 @@ public class TreeActionTest {
     ComponentDto project = db.components().insertPrivateProject(p -> p.setKey("project-key"));
     ComponentDto projectBranch = db.components().insertProjectBranch(project, b -> b.setKey(projectBranchName));
     ComponentDto techProjectBranch = db.components().insertComponent(newProjectCopy(projectBranch, applicationBranch)
-      .setKey(applicationBranch.getKey() + appBranchName + projectBranch.getKey()));
+      .setKey(applicationBranch.getKey() + project.getKey()));
     logInWithBrowsePermission(application);
 
     TreeWsResponse result = ws.newRequest()
@@ -377,19 +377,6 @@ public class TreeActionTest {
         tuple(file.getKey(), pullRequestId));
   }
 
-  @Test
-  public void fail_when_using_branch_key() {
-    ComponentDto project = db.components().insertPrivateProject();
-    userSession.addProjectPermission(UserRole.USER, project);
-    ComponentDto branch = db.components().insertProjectBranch(project);
-
-    TestRequest request = ws.newRequest()
-      .setParam(PARAM_COMPONENT, branch.getKey());
-    assertThatThrownBy(() -> request.executeProtobuf(Components.ShowWsResponse.class))
-      .isInstanceOf(NotFoundException.class)
-      .hasMessage(format("Component key '%s' not found", branch.getKey()));
-  }
-
   @Test
   public void fail_when_not_enough_privileges() {
     ComponentDto project = db.components().insertComponent(newPrivateProjectDto("project-uuid"));
index ebaa21cf718f3035f7d4583b1efe751f8109c68d..f71292b5740acf82e7d51176d4c2ea8a7b1875aa 100644 (file)
@@ -28,6 +28,7 @@ import org.junit.Test;
 import org.sonar.db.DbTester;
 import org.sonar.db.component.BranchType;
 import org.sonar.db.component.ComponentDto;
+import org.sonar.server.component.ComponentFinder;
 
 import static java.lang.String.format;
 import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
@@ -39,7 +40,7 @@ public class DuplicationsParserTest {
   @Rule
   public DbTester db = DbTester.create();
 
-  private DuplicationsParser parser = new DuplicationsParser(db.getDbClient().componentDao());
+  private final DuplicationsParser parser = new DuplicationsParser(new ComponentFinder(db.getDbClient(), null));
 
   @Test
   public void empty_list_when_no_data() {
index 2c0af116c213e1988e5bcf08908754256d16791f..a92670456cdb3d64fa4d9cc72e2f5e44c4e02442 100644 (file)
@@ -57,7 +57,8 @@ public class ShowActionTest {
 
   @Rule
   public DbTester db = DbTester.create();
-  private final DuplicationsParser parser = new DuplicationsParser(db.getDbClient().componentDao());
+  private final TestComponentFinder componentFinder = TestComponentFinder.from(db);
+  private final DuplicationsParser parser = new DuplicationsParser(componentFinder);
   private final ShowResponseBuilder showResponseBuilder = new ShowResponseBuilder(db.getDbClient());
   private final WsActionTester ws = new WsActionTester(new ShowAction(db.getDbClient(), parser, showResponseBuilder, userSessionRule,
     TestComponentFinder.from(db)));
index 54d1083cc3a14fa7c6ca36a6f4c8b971ea004663..d8a5b32a3528c05de2f0e30f63350b2425827638 100644 (file)
@@ -105,18 +105,6 @@ public class RemoveActionTest {
       .isInstanceOf(UnauthorizedException.class);
   }
 
-  @Test
-  public void fail_when_using_branch_db_key() {
-    ComponentDto project = db.components().insertPrivateProject();
-    userSession.logIn().addProjectPermission(UserRole.USER, project);
-    ComponentDto branch = db.components().insertProjectBranch(project);
-    String branchKey = branch.getKey();
-
-    assertThatThrownBy(() -> call(branchKey))
-      .isInstanceOf(NotFoundException.class)
-      .hasMessage(format("Component key '%s' not found", branchKey));
-  }
-
   @Test
   public void definition() {
     WebService.Action definition = ws.getDef();
index 06be33aaaa5d2a2a716210993707992d9810c031..4942128a7addeab34d24dd23ef795424e261089e 100644 (file)
@@ -57,6 +57,8 @@ import org.sonar.db.protobuf.DbCommons;
 import org.sonar.db.protobuf.DbIssues;
 import org.sonar.db.rule.RuleDto;
 import org.sonar.db.rule.RuleTesting;
+import org.sonar.server.component.ComponentFinder;
+import org.sonar.server.component.TestComponentFinder;
 import org.sonar.server.es.EsTester;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.exceptions.NotFoundException;
@@ -153,8 +155,9 @@ public class SearchActionTest {
   private final PermissionIndexer permissionIndexer = new PermissionIndexer(dbClient, es.client(), issueIndexer);
   private final HotspotWsResponseFormatter responseFormatter = new HotspotWsResponseFormatter();
   private final IssueIndexSyncProgressChecker issueIndexSyncProgressChecker = mock(IssueIndexSyncProgressChecker.class);
+  private final ComponentFinder componentFinder = TestComponentFinder.from(dbTester);
   private final SearchAction underTest = new SearchAction(dbClient, userSessionRule, issueIndex,
-    issueIndexSyncProgressChecker, responseFormatter, new TextRangeResponseFormatter(), system2);
+    issueIndexSyncProgressChecker, responseFormatter, new TextRangeResponseFormatter(), system2, componentFinder);
   private final WsActionTester actionTester = new WsActionTester(underTest);
 
   @Test
@@ -333,7 +336,7 @@ public class SearchActionTest {
 
     assertThatThrownBy(request::execute)
       .isInstanceOf(NotFoundException.class)
-      .hasMessage("Project '%s' not found", key);
+      .hasMessage("Component key '%s' not found", key);
   }
 
   @Test
@@ -638,7 +641,7 @@ public class SearchActionTest {
   @Test
   public void returns_hotspots_of_specified_application_branch() {
     ComponentDto application = dbTester.components().insertPublicApplication();
-    ComponentDto applicationBranch = dbTester.components().insertProjectBranch(application);
+    ComponentDto applicationBranch = dbTester.components().insertProjectBranch(application, b -> b.setKey("appBranch"));
     ComponentDto project1 = dbTester.components().insertPublicProject();
     ComponentDto project2 = dbTester.components().insertPublicProject();
     dbTester.components().insertComponent(ComponentTesting.newProjectCopy(project1, application));
@@ -667,7 +670,7 @@ public class SearchActionTest {
       .extracting(Component::getKey)
       .containsOnly(project1.getKey(), file1.getKey());
 
-    SearchWsResponse responseApplicationBranch = newRequest(applicationBranch)
+    SearchWsResponse responseApplicationBranch = newRequest(application, null, null, "appBranch", null)
       .executeProtobuf(SearchWsResponse.class);
 
     assertThat(responseApplicationBranch.getHotspotsList())
@@ -818,7 +821,7 @@ public class SearchActionTest {
       .collect(toList());
     indexIssues();
 
-    SearchWsResponse response = newRequest(project, null, null)
+    SearchWsResponse response = newRequest(project)
       .executeProtobuf(SearchWsResponse.class);
 
     assertThat(response.getHotspotsList())
@@ -837,7 +840,7 @@ public class SearchActionTest {
       .collect(toList());
     indexIssues();
 
-    SearchWsResponse response = newRequest(project, STATUS_REVIEWED, null)
+    SearchWsResponse response = newRequest(project, STATUS_REVIEWED, null, null, null)
       .executeProtobuf(SearchWsResponse.class);
 
     assertThat(response.getHotspotsList())
@@ -856,7 +859,7 @@ public class SearchActionTest {
       .collect(toList());
     indexIssues();
 
-    SearchWsResponse response = newRequest(project, STATUS_REVIEWED, RESOLUTION_SAFE)
+    SearchWsResponse response = newRequest(project, STATUS_REVIEWED, RESOLUTION_SAFE, null, null)
       .executeProtobuf(SearchWsResponse.class);
 
     assertThat(response.getHotspotsList())
@@ -875,7 +878,7 @@ public class SearchActionTest {
       .collect(toList());
     indexIssues();
 
-    SearchWsResponse response = newRequest(project, STATUS_REVIEWED, RESOLUTION_FIXED)
+    SearchWsResponse response = newRequest(project, STATUS_REVIEWED, RESOLUTION_FIXED, null, null)
       .executeProtobuf(SearchWsResponse.class);
 
     assertThat(response.getHotspotsList())
@@ -897,7 +900,7 @@ public class SearchActionTest {
     IssueDto badlyClosedHotspot = insertHotspot(rule, project, file, t -> t.setStatus(STATUS_CLOSED).setResolution(null));
     indexIssues();
 
-    SearchWsResponse response = newRequest(project, STATUS_TO_REVIEW, null)
+    SearchWsResponse response = newRequest(project, STATUS_TO_REVIEW, null, null, null)
       .executeProtobuf(SearchWsResponse.class);
 
     assertThat(response.getHotspotsList())
@@ -1136,7 +1139,7 @@ public class SearchActionTest {
     IssueDto projectHotspot = insertHotspot(pullRequest, pullRequest, rule);
     indexIssues();
 
-    SearchWsResponse response = newRequest(pullRequest, r -> r.setParam(PARAM_PULL_REQUEST, "pullRequestKey"))
+    SearchWsResponse response = newRequest(pullRequest, r -> r.setParam(PARAM_PULL_REQUEST, pullRequestKey))
       .executeProtobuf(SearchWsResponse.class);
 
     assertThat(response.getHotspotsList())
@@ -2020,21 +2023,29 @@ public class SearchActionTest {
   }
 
   private TestRequest newRequest(ComponentDto project) {
-    return newRequest(project, null, null);
+    return newRequest(project, null, null, null, null);
   }
 
   private TestRequest newRequest(ComponentDto project, Consumer<TestRequest> consumer) {
-    return newRequest(project, null, null, consumer);
+    return newRequest(project, null,
+      null, null, null, consumer);
   }
 
-  private TestRequest newRequest(ComponentDto project, @Nullable String status, @Nullable String resolution) {
-    return newRequest(project, status, resolution, t -> {
+  private TestRequest newRequest(ComponentDto project, @Nullable String status, @Nullable String resolution, @Nullable String branch, @Nullable String pullRequest) {
+    return newRequest(project, status, resolution, branch, pullRequest, t -> {
     });
   }
 
-  private TestRequest newRequest(ComponentDto project, @Nullable String status, @Nullable String resolution, Consumer<TestRequest> consumer) {
+  private TestRequest newRequest(ComponentDto project, @Nullable String status, @Nullable String resolution,
+    @Nullable String branch, @Nullable String pullRequest, Consumer<TestRequest> consumer) {
     TestRequest res = actionTester.newRequest()
       .setParam(PARAM_PROJECT_KEY, project.getKey());
+    if (branch != null) {
+      res.setParam(PARAM_BRANCH, branch);
+    }
+    if (pullRequest != null) {
+      res.setParam(PARAM_PULL_REQUEST, pullRequest);
+    }
     if (status != null) {
       res.setParam(PARAM_STATUS, status);
     }
index 8b937abf8bfc7d60bbbfdf7413bdd240e8e59300..b77b308559e69090a6e8f35efea7bd82bd865960 100644 (file)
@@ -366,12 +366,14 @@ public class SearchActionComponentsTest {
     ComponentDto application = db.components().insertPrivateProject(c -> c.setQualifier(APP).setKey("app"));
     String appBranch1 = "app-branch1";
     String appBranch2 = "app-branch2";
+    String proj1branch1 = "proj1branch1";
+    String proj1branch2 = "proj1branch2";
     ComponentDto applicationBranch1 = db.components().insertProjectBranch(application, a -> a.setKey(appBranch1));
     ComponentDto applicationBranch2 = db.components().insertProjectBranch(application, a -> a.setKey(appBranch2));
     ComponentDto project1 = db.components().insertPrivateProject(p -> p.setKey("prj1"));
-    ComponentDto project1Branch1 = db.components().insertProjectBranch(project1);
+    ComponentDto project1Branch1 = db.components().insertProjectBranch(project1, b -> b.setKey(proj1branch1));
     ComponentDto fileOnProject1Branch1 = db.components().insertComponent(newFileDto(project1Branch1));
-    ComponentDto project1Branch2 = db.components().insertProjectBranch(project1);
+    ComponentDto project1Branch2 = db.components().insertProjectBranch(project1, b -> b.setKey(proj1branch2));
     ComponentDto project2 = db.components().insertPrivateProject(p -> p.setKey("prj2"));
     db.components().insertComponents(newProjectCopy(project1Branch1, applicationBranch1));
     db.components().insertComponents(newProjectCopy(project2, applicationBranch1));
@@ -397,8 +399,8 @@ public class SearchActionComponentsTest {
       .executeProtobuf(SearchWsResponse.class).getIssuesList())
         .extracting(Issue::getKey, Issue::getComponent, Issue::getProject, Issue::getBranch, Issue::hasBranch)
         .containsExactlyInAnyOrder(
-          tuple(issueOnProject1Branch1.getKey(), project1Branch1.getKey(), project1Branch1.getKey(), appBranch1, true),
-          tuple(issueOnFileOnProject1Branch1.getKey(), fileOnProject1Branch1.getKey(), project1Branch1.getKey(), appBranch1, true),
+          tuple(issueOnProject1Branch1.getKey(), project1Branch1.getKey(), project1Branch1.getKey(), proj1branch1, true),
+          tuple(issueOnFileOnProject1Branch1.getKey(), fileOnProject1Branch1.getKey(), project1Branch1.getKey(), proj1branch1, true),
           tuple(issueOnProject2.getKey(), project2.getKey(), project2.getKey(), "", false));
 
     // Issues on project1Branch1
@@ -409,8 +411,8 @@ public class SearchActionComponentsTest {
       .executeProtobuf(SearchWsResponse.class).getIssuesList())
         .extracting(Issue::getKey, Issue::getComponent, Issue::getBranch)
         .containsExactlyInAnyOrder(
-          tuple(issueOnProject1Branch1.getKey(), project1Branch1.getKey(), appBranch1),
-          tuple(issueOnFileOnProject1Branch1.getKey(), fileOnProject1Branch1.getKey(), appBranch1));
+          tuple(issueOnProject1Branch1.getKey(), project1Branch1.getKey(), proj1branch1),
+          tuple(issueOnFileOnProject1Branch1.getKey(), fileOnProject1Branch1.getKey(), proj1branch1));
   }
 
   @Test
index 54fb534fbf83744dc23a73150c706bfd40e16c7c..49cfd31ec09fa7573a6b5aa89943d829c78779cb 100644 (file)
@@ -451,7 +451,7 @@ public class SearchActionTest {
     UserDto simon = db.users().insertUser(u -> u.setLogin("simon").setName("Simon").setEmail("simon@email.com"));
     UserDto fabrice = db.users().insertUser(u -> u.setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com"));
 
-    ComponentDto project = db.components().insertComponent(ComponentTesting.newPublicProjectDto("PROJECT_ID").setKey("PROJECT_KEY").setLanguage("java"));
+    ComponentDto project = db.components().insertPublicProject("PROJECT_ID", c -> c.setKey("PROJECT_KEY").setLanguage("java"));
     grantPermissionToAnyone(project, ISSUE_ADMIN);
     indexPermissions();
     ComponentDto file = db.components().insertComponent(newFileDto(project, null, "FILE_ID").setKey("FILE_KEY").setLanguage("js"));
@@ -475,7 +475,7 @@ public class SearchActionTest {
   @Test
   public void search_by_rule_key() {
     RuleDto rule = newIssueRule();
-    ComponentDto project = db.components().insertComponent(ComponentTesting.newPublicProjectDto("PROJECT_ID").setKey("PROJECT_KEY").setLanguage("java"));
+    ComponentDto project = db.components().insertPublicProject("PROJECT_ID", c -> c.setKey("PROJECT_KEY").setLanguage("java"));
     ComponentDto file = db.components().insertComponent(newFileDto(project, null, "FILE_ID").setKey("FILE_KEY").setLanguage("java"));
 
     db.issues().insertIssue(rule, project, file);
@@ -496,7 +496,7 @@ public class SearchActionTest {
   @Test
   public void search_by_non_existing_rule_key() {
     RuleDto rule = newIssueRule();
-    ComponentDto project = db.components().insertComponent(ComponentTesting.newPublicProjectDto("PROJECT_ID").setKey("PROJECT_KEY").setLanguage("java"));
+    ComponentDto project = db.components().insertPublicProject("PROJECT_ID", c -> c.setKey("PROJECT_KEY").setLanguage("java"));
     ComponentDto file = db.components().insertComponent(newFileDto(project, null, "FILE_ID").setKey("FILE_KEY").setLanguage("java"));
 
     db.issues().insertIssue(rule, project, file);
@@ -517,7 +517,7 @@ public class SearchActionTest {
   @Test
   public void issue_on_removed_file() {
     RuleDto rule = newIssueRule();
-    ComponentDto project = db.components().insertComponent(ComponentTesting.newPublicProjectDto("PROJECT_ID").setKey("PROJECT_KEY"));
+    ComponentDto project = db.components().insertPublicProject("PROJECT_ID", c -> c.setKey("PROJECT_KEY").setKey("PROJECT_KEY"));
     indexPermissions();
     ComponentDto removedFile = db.components().insertComponent(newFileDto(project, null).setUuid("REMOVED_FILE_ID")
       .setKey("REMOVED_FILE_KEY")
@@ -542,7 +542,7 @@ public class SearchActionTest {
   @Test
   public void apply_paging_with_one_component() {
     RuleDto rule = newIssueRule();
-    ComponentDto project = db.components().insertComponent(ComponentTesting.newPublicProjectDto("PROJECT_ID").setKey("PROJECT_KEY"));
+    ComponentDto project = db.components().insertPublicProject("PROJECT_ID", c -> c.setKey("PROJECT_KEY").setKey("PROJECT_KEY"));
     indexPermissions();
     ComponentDto file = db.components().insertComponent(newFileDto(project, null, "FILE_ID").setKey("FILE_KEY"));
     for (int i = 0; i < SearchOptions.MAX_PAGE_SIZE + 1; i++) {
@@ -558,7 +558,7 @@ public class SearchActionTest {
 
   @Test
   public void components_contains_sub_projects() {
-    ComponentDto project = db.components().insertComponent(ComponentTesting.newPublicProjectDto("PROJECT_ID").setKey("ProjectHavingModule"));
+    ComponentDto project = db.components().insertPublicProject("PROJECT_ID", c -> c.setKey("PROJECT_KEY").setKey("ProjectHavingModule"));
     indexPermissions();
     ComponentDto module = db.components().insertComponent(ComponentTesting.newModuleDto(project).setKey("ModuleHavingFile"));
     ComponentDto file = db.components().insertComponent(newFileDto(module, null, "BCDE").setKey("FileLinkedToModule"));
@@ -575,7 +575,7 @@ public class SearchActionTest {
   public void filter_by_assigned_to_me() {
     UserDto john = db.users().insertUser(u -> u.setLogin("john").setName("John").setEmail("john@email.com"));
     UserDto alice = db.users().insertUser(u -> u.setLogin("alice").setName("Alice").setEmail("alice@email.com"));
-    ComponentDto project = db.components().insertComponent(ComponentTesting.newPublicProjectDto("PROJECT_ID").setKey("PROJECT_KEY"));
+    ComponentDto project = db.components().insertPublicProject(c -> c.setUuid("PROJECT_ID").setKey("PROJECT_KEY").setBranchUuid("PROJECT_ID"));
     indexPermissions();
     ComponentDto file = db.components().insertComponent(newFileDto(project, null, "FILE_ID").setKey("FILE_KEY"));
     RuleDto rule = newIssueRule();
@@ -621,7 +621,7 @@ public class SearchActionTest {
   public void filter_by_new_code_period() {
     UserDto john = db.users().insertUser(u -> u.setLogin("john").setName("John").setEmail("john@email.com"));
     UserDto alice = db.users().insertUser(u -> u.setLogin("alice").setName("Alice").setEmail("alice@email.com"));
-    ComponentDto project = db.components().insertComponent(ComponentTesting.newPublicProjectDto("PROJECT_ID").setKey("PROJECT_KEY"));
+    ComponentDto project = db.components().insertPublicProject("PROJECT_ID", c -> c.setKey("PROJECT_KEY"));
     SnapshotDto snapshotDto = db.components().insertSnapshot(project, s -> s.setLast(true).setPeriodDate(parseDateTime("2014-09-05T00:00:00+0100").getTime()));
     indexPermissions();
 
@@ -692,7 +692,7 @@ public class SearchActionTest {
   public void filter_by_leak_period_without_a_period() {
     UserDto john = db.users().insertUser(u -> u.setLogin("john").setName("John").setEmail("john@email.com"));
     UserDto alice = db.users().insertUser(u -> u.setLogin("alice").setName("Alice").setEmail("alice@email.com"));
-    ComponentDto project = db.components().insertComponent(ComponentTesting.newPublicProjectDto("PROJECT_ID").setKey("PROJECT_KEY"));
+    ComponentDto project = db.components().insertPublicProject("PROJECT_ID", c -> c.setKey("PROJECT_KEY"));
     SnapshotDto snapshotDto = db.components().insertSnapshot(project);
     indexPermissions();
     ComponentDto file = db.components().insertComponent(newFileDto(project, null, "FILE_ID").setKey("FILE_KEY"));
@@ -743,7 +743,7 @@ public class SearchActionTest {
   public void filter_by_leak_period_has_no_effect_on_prs() {
     UserDto john = db.users().insertUser(u -> u.setLogin("john").setName("John").setEmail("john@email.com"));
     UserDto alice = db.users().insertUser(u -> u.setLogin("alice").setName("Alice").setEmail("alice@email.com"));
-    ComponentDto project = db.components().insertPublicProject(c -> c.setUuid("PROJECT_ID").setKey("PROJECT_KEY"));
+    ComponentDto project = db.components().insertPublicProject("PROJECT_ID", c -> c.setKey("PROJECT_KEY"));
     ComponentDto pr = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.PULL_REQUEST).setKey("pr"));
     SnapshotDto snapshotDto = db.components().insertSnapshot(pr);
     indexPermissions();
@@ -798,7 +798,7 @@ public class SearchActionTest {
   public void return_empty_when_login_is_unknown() {
     UserDto john = db.users().insertUser(u -> u.setLogin("john").setName("John").setEmail("john@email.com"));
     UserDto alice = db.users().insertUser(u -> u.setLogin("alice").setName("Alice").setEmail("alice@email.com"));
-    ComponentDto project = db.components().insertComponent(ComponentTesting.newPublicProjectDto("PROJECT_ID").setKey("PROJECT_KEY"));
+    ComponentDto project = db.components().insertPublicProject("PROJECT_ID", c -> c.setKey("PROJECT_KEY"));
     indexPermissions();
     ComponentDto file = db.components().insertComponent(newFileDto(project, null, "FILE_ID").setKey("FILE_KEY"));
     RuleDto rule = newIssueRule();
@@ -847,7 +847,7 @@ public class SearchActionTest {
     userSession.logIn(poy);
     UserDto alice = db.users().insertUser(u -> u.setLogin("alice").setName("Alice").setEmail("alice@email.com"));
     UserDto john = db.users().insertUser(u -> u.setLogin("john").setName("John").setEmail("john@email.com"));
-    ComponentDto project = db.components().insertComponent(ComponentTesting.newPublicProjectDto("PROJECT_ID").setKey("PROJECT_KEY"));
+    ComponentDto project = db.components().insertPublicProject("PROJECT_ID", c -> c.setKey("PROJECT_KEY"));
     indexPermissions();
     ComponentDto file = db.components().insertComponent(newFileDto(project, null, "FILE_ID").setKey("FILE_KEY"));
     RuleDto rule = newIssueRule();
@@ -908,7 +908,7 @@ public class SearchActionTest {
 
   @Test
   public void filter_by_test_scope() {
-    ComponentDto project = db.components().insertComponent(ComponentTesting.newPublicProjectDto("PROJECT_ID").setKey("PROJECT_KEY"));
+    ComponentDto project = db.components().insertPublicProject("PROJECT_ID", c -> c.setKey("PROJECT_KEY"));
     indexPermissions();
     ComponentDto mainCodeFile = db.components().insertComponent(
       newFileDto(project, null, "FILE_ID").setKey("FILE_KEY"));
@@ -949,7 +949,7 @@ public class SearchActionTest {
 
   @Test
   public void filter_by_main_scope() {
-    ComponentDto project = db.components().insertComponent(ComponentTesting.newPublicProjectDto("PROJECT_ID").setKey("PROJECT_KEY"));
+    ComponentDto project = db.components().insertPublicProject("PROJECT_ID", c -> c.setKey("PROJECT_KEY"));
     indexPermissions();
     ComponentDto mainCodeFile = db.components().insertComponent(
       newFileDto(project, null, "FILE_ID").setKey("FILE_KEY"));
@@ -993,7 +993,7 @@ public class SearchActionTest {
 
   @Test
   public void filter_by_scope_always_returns_all_scope_facet_values() {
-    ComponentDto project = db.components().insertComponent(ComponentTesting.newPublicProjectDto("PROJECT_ID").setKey("PROJECT_KEY"));
+    ComponentDto project = db.components().insertPublicProject("PROJECT_ID", c -> c.setKey("PROJECT_KEY"));
     indexPermissions();
     ComponentDto mainCodeFile = db.components().insertComponent(
       newFileDto(project, null, "FILE_ID").setKey("FILE_KEY"));
@@ -1028,7 +1028,7 @@ public class SearchActionTest {
   @Test
   public void sort_by_updated_at() {
     RuleDto rule = newIssueRule();
-    ComponentDto project = db.components().insertComponent(ComponentTesting.newPublicProjectDto("PROJECT_ID").setKey("PROJECT_KEY"));
+    ComponentDto project = db.components().insertPublicProject("PROJECT_ID", c -> c.setKey("PROJECT_KEY"));
     indexPermissions();
     ComponentDto file = db.components().insertComponent(newFileDto(project, null, "FILE_ID").setKey("FILE_KEY"));
     dbClient.issueDao().insert(session, newDto(rule, file, project)
@@ -1693,7 +1693,7 @@ public class SearchActionTest {
   @Test
   public void paging() {
     RuleDto rule = newIssueRule();
-    ComponentDto project = db.components().insertComponent(ComponentTesting.newPublicProjectDto("PROJECT_ID").setKey("PROJECT_KEY"));
+    ComponentDto project = db.components().insertPublicProject("PROJECT_ID", c -> c.setKey("PROJECT_KEY"));
     indexPermissions();
     ComponentDto file = db.components().insertComponent(newFileDto(project, null, "FILE_ID").setKey("FILE_KEY"));
     for (int i = 0; i < 12; i++) {
@@ -1712,7 +1712,6 @@ public class SearchActionTest {
 
   @Test
   public void paging_with_page_size_to_minus_one() {
-
     TestRequest requestWithNegativePageSize = ws.newRequest()
       .setParam(WebService.Param.PAGE, "1")
       .setParam(WebService.Param.PAGE_SIZE, "-1");
index 2aefccfc0fae0edef8084003885ce7928e8d48d4..002afa2044996c6025de62f624357e89bd0b1454 100644 (file)
@@ -25,16 +25,20 @@ import java.util.Date;
 import java.util.List;
 import java.util.Set;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnitRunner;
 import org.sonar.api.resources.Languages;
 import org.sonar.api.utils.Duration;
 import org.sonar.api.utils.Durations;
+import org.sonar.db.DbTester;
+import org.sonar.db.component.BranchDto;
+import org.sonar.db.component.BranchType;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.issue.IssueChangeDto;
 import org.sonar.db.issue.IssueDto;
+import org.sonar.db.project.ProjectDto;
 import org.sonar.db.rule.RuleDto;
 import org.sonar.db.user.UserDto;
 import org.sonar.server.issue.TextRangeResponseFormatter;
@@ -49,14 +53,13 @@ import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 import static org.sonar.api.resources.Qualifiers.UNIT_TEST_FILE;
 import static org.sonar.api.rule.RuleKey.EXTERNAL_RULE_REPO_PREFIX;
 import static org.sonar.api.rules.RuleType.CODE_SMELL;
 import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT;
 import static org.sonar.api.utils.DateUtils.formatDateTime;
-import static org.sonar.db.component.ComponentDto.BRANCH_KEY_SEPARATOR;
-import static org.sonar.db.component.ComponentDto.PULL_REQUEST_SEPARATOR;
 import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
 import static org.sonar.db.issue.IssueTesting.newIssue;
 import static org.sonar.db.issue.IssueTesting.newIssuechangeDto;
@@ -67,33 +70,23 @@ import static org.sonar.server.issue.index.IssueScope.TEST;
 
 @RunWith(MockitoJUnitRunner.class)
 public class SearchResponseFormatFormatOperationTest {
-
-  private SearchResponseFormat searchResponseFormat;
-
+  @Rule
+  public DbTester db = DbTester.create();
   private final Durations durations = new Durations();
-  @Mock
-  private Languages languages;
-  @Mock
-  private TextRangeResponseFormatter textRangeResponseFormatter;
-  @Mock
-  private UserResponseFormatter userResponseFormatter;
-  @Mock
-  private Common.User user;
+  private final Languages languages = mock(Languages.class);
+  private final TextRangeResponseFormatter textRangeResponseFormatter = mock(TextRangeResponseFormatter.class);
+  private final UserResponseFormatter userResponseFormatter = mock(UserResponseFormatter.class);
+  private final Common.User user = mock(Common.User.class);
+  private final SearchResponseFormat searchResponseFormat = new SearchResponseFormat(durations, languages, textRangeResponseFormatter, userResponseFormatter);
 
   private SearchResponseData searchResponseData;
   private IssueDto issueDto;
   private ComponentDto componentDto;
   private UserDto userDto;
 
-
   @Before
   public void setUp() {
-    searchResponseFormat = new SearchResponseFormat(durations, languages, textRangeResponseFormatter, userResponseFormatter);
-    searchResponseData = newSearchResponseData();
-    issueDto = searchResponseData.getIssues().get(0);
-    componentDto = searchResponseData.getComponents().iterator().next();
-    userDto = searchResponseData.getUsers().get(0);
-    when(userResponseFormatter.formatUser(any(Common.User.Builder.class), eq(userDto))).thenReturn(user);
+    searchResponseData = newSearchResponseDataMainBranch();
   }
 
   @Test
@@ -168,21 +161,16 @@ public class SearchResponseFormatFormatOperationTest {
   @Test
   public void formatOperation_should_add_branch_on_issue() {
     String branchName = randomAlphanumeric(5);
-    componentDto.setKey(randomAlphanumeric(5) + BRANCH_KEY_SEPARATOR + branchName);
-
+    searchResponseData = newSearchResponseDataBranch(branchName);
     Operation result = searchResponseFormat.formatOperation(searchResponseData);
-
     assertThat(result.getIssue().getBranch()).isEqualTo(branchName);
   }
 
   @Test
   public void formatOperation_should_add_pullrequest_on_issue() {
-    String pullRequestKey = randomAlphanumeric(5);
-    componentDto.setKey(randomAlphanumeric(5) + PULL_REQUEST_SEPARATOR + pullRequestKey);
-
+    searchResponseData = newSearchResponseDataPr("pr1");
     Operation result = searchResponseFormat.formatOperation(searchResponseData);
-
-    assertThat(result.getIssue().getPullRequest()).isEqualTo(pullRequestKey);
+    assertThat(result.getIssue().getPullRequest()).isEqualTo("pr1");
   }
 
   @Test
@@ -280,16 +268,31 @@ public class SearchResponseFormatFormatOperationTest {
     assertThat(result.getIssue().hasSeverity()).isFalse();
   }
 
-  private static SearchResponseData newSearchResponseData() {
-    RuleDto ruleDto = newRule();
+  private SearchResponseData newSearchResponseDataMainBranch() {
+    ComponentDto projectDto = db.components().insertPublicProject();
+    BranchDto branchDto = db.getDbClient().branchDao().selectByUuid(db.getSession(), projectDto.uuid()).get();
+    return newSearchResponseData(projectDto, branchDto);
+  }
 
-    String projectUuid = "project_uuid_" + randomAlphanumeric(5);
-    ComponentDto projectDto = newPrivateProjectDto();
-    projectDto.setBranchUuid(projectUuid);
+  private SearchResponseData newSearchResponseDataBranch(String name) {
+    ProjectDto projectDto = db.components().insertPublicProjectDto();
+    BranchDto branch = db.components().insertProjectBranch(projectDto, b -> b.setKey(name));
+    ComponentDto branchComponent = db.components().getComponentDto(branch);
+    return newSearchResponseData(branchComponent, branch);
+  }
 
-    UserDto userDto = newUserDto();
+  private SearchResponseData newSearchResponseDataPr(String name) {
+    ProjectDto projectDto = db.components().insertPublicProjectDto();
+    BranchDto branch = db.components().insertProjectBranch(projectDto, b -> b.setKey(name).setBranchType(BranchType.PULL_REQUEST));
+    ComponentDto branchComponent = db.components().getComponentDto(branch);
+    return newSearchResponseData(branchComponent, branch);
+  }
 
-    IssueDto issueDto = newIssue(ruleDto, projectUuid, "project_key_" + randomAlphanumeric(5), projectDto)
+  private SearchResponseData newSearchResponseData(ComponentDto component, BranchDto branch) {
+    RuleDto ruleDto = newRule();
+    userDto = newUserDto();
+    componentDto = component;
+    issueDto = newIssue(ruleDto, component.branchUuid(), component.getKey(), component)
       .setType(CODE_SMELL)
       .setRuleDescriptionContextKey("context_key_" + randomAlphanumeric(5))
       .setAssigneeUuid(userDto.getUuid())
@@ -299,10 +302,13 @@ public class SearchResponseFormatFormatOperationTest {
       .setIssueCloseDate(new Date(currentTimeMillis()));
 
     SearchResponseData searchResponseData = new SearchResponseData(issueDto);
-    searchResponseData.addComponents(List.of(projectDto));
+    searchResponseData.addComponents(List.of(component));
     searchResponseData.addRules(List.of(ruleDto));
     searchResponseData.addUsers(List.of(userDto));
+    searchResponseData.addBranches(List.of(branch));
+
+    when(userResponseFormatter.formatUser(any(Common.User.Builder.class), eq(userDto))).thenReturn(user);
+
     return searchResponseData;
   }
-
 }
index 0a9738731fa0ade82951040d84b6ca15a3ca6a4c..b2e489198fced019faff100332a98ea3958979a4 100644 (file)
@@ -745,7 +745,7 @@ public class ComponentTreeActionTest {
       .containsExactlyInAnyOrder(applicationBranch.getKey(), branchName);
     assertThat(result.getComponentsList())
       .extracting(Component::getKey, Component::getBranch, Component::getRefKey)
-      .containsExactlyInAnyOrder(tuple(techProjectBranch.getKey(), branchName, project.getKey()));
+      .containsExactlyInAnyOrder(tuple(techProjectBranch.getKey(), "project-branch", project.getKey()));
   }
 
   @Test
index 99f68726f7e41d5e9a0d79cde5a003a73f9ebb82..980b52eab32983957050b56692a95e3f9d73a5d4 100644 (file)
@@ -19,9 +19,6 @@
  */
 package org.sonar.server.setting;
 
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
 import org.sonar.api.config.Configuration;
 import org.sonar.db.DbSession;
 import org.sonar.db.component.ComponentDto;
@@ -35,11 +32,7 @@ public class TestProjectConfigurationLoader implements ProjectConfigurationLoade
   }
 
   @Override
-  public Map<String, Configuration> loadProjectConfigurations(DbSession dbSession, Set<ComponentDto> projects) {
-    Map<String, Configuration> map = new HashMap<>();
-    for (ComponentDto project : projects) {
-      map.put(project.uuid(), config);
-    }
-    return map;
+  public Configuration loadProjectConfiguration(DbSession dbSession, ComponentDto project) {
+    return config;
   }
 }
index 3588b5464717c13372cc8774653d65c47b36167f..fa0793b972b28b1b9ea10136af8fed85b9234a6a 100644 (file)
@@ -320,7 +320,7 @@ public class SetActionTest {
       project.getKey());
 
     assertThat(dbClient.propertiesDao().selectGlobalProperties(dbSession)).hasSize(3);
-    assertThat(dbClient.propertiesDao().selectProjectProperties(dbSession, project.getKey())).hasSize(5);
+    assertThat(dbClient.propertiesDao().selectComponentProperties(dbSession, project.uuid())).hasSize(5);
     assertGlobalSetting("my.key", "1");
     assertGlobalSetting("my.key.1.firstField", "oldFirstValue");
     assertGlobalSetting("my.key.1.secondField", "oldSecondValue");
index e6b399e429509bd12e10cc0db34bbe9c68aacbba..51210fe4b8e4c3c36677f7f78728ece09a81ce1e 100644 (file)
@@ -32,17 +32,14 @@ import org.sonar.api.PropertyType;
 import org.sonar.api.config.PropertyDefinition;
 import org.sonar.api.config.PropertyDefinitions;
 import org.sonar.api.config.PropertyFieldDefinition;
-import org.sonar.api.config.internal.MapSettings;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.utils.System2;
 import org.sonar.api.web.UserRole;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbTester;
-import org.sonar.db.component.ComponentDbTester;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.component.ComponentTesting;
 import org.sonar.db.permission.GlobalPermission;
-import org.sonar.db.property.PropertyDbTester;
 import org.sonar.process.ProcessProperties;
 import org.sonar.server.component.TestComponentFinder;
 import org.sonar.server.exceptions.ForbiddenException;
@@ -75,23 +72,22 @@ import static org.sonarqube.ws.Settings.Setting.ParentValueOneOfCase.PARENTVALUE
 
 public class ValuesActionTest {
 
-  private static Joiner COMMA_JOINER = Joiner.on(",");
+  private static final Joiner COMMA_JOINER = Joiner.on(",");
 
   @Rule
   public UserSessionRule userSession = UserSessionRule.standalone();
   @Rule
   public DbTester db = DbTester.create(System2.INSTANCE);
 
-  private DbClient dbClient = db.getDbClient();
-  private PropertyDbTester propertyDb = new PropertyDbTester(db);
-  private ComponentDbTester componentDb = new ComponentDbTester(db);
-  private PropertyDefinitions definitions = new PropertyDefinitions(System2.INSTANCE);
-  private SettingsWsSupport support = new SettingsWsSupport(userSession);
+  private final DbClient dbClient = db.getDbClient();
+  private final PropertyDefinitions definitions = new PropertyDefinitions(System2.INSTANCE);
+  private final SettingsWsSupport support = new SettingsWsSupport(userSession);
+  private final WsActionTester wsActionTester = new WsActionTester(new ValuesAction(dbClient, TestComponentFinder.from(db), userSession, definitions, support));
   private ComponentDto project;
 
   @Before
   public void setUp() {
-    project = componentDb.insertComponent(ComponentTesting.newPrivateProjectDto());
+    project = db.components().insertPrivateProject();
   }
 
   @Test
@@ -100,7 +96,7 @@ public class ValuesActionTest {
     definitions.addComponent(PropertyDefinition
       .builder("foo")
       .build());
-    propertyDb.insertProperties(null, null, null, null, newGlobalPropertyDto().setKey("foo").setValue("one"));
+    db.properties().insertProperties(null, null, null, null, newGlobalPropertyDto().setKey("foo").setValue("one"));
 
     ValuesWsResponse result = executeRequestForGlobalProperties("foo");
 
@@ -123,7 +119,7 @@ public class ValuesActionTest {
     definitions.addComponent(PropertyDefinition.builder("global")
       .multiValues(true)
       .build());
-    propertyDb.insertProperties(null, null, null, null, newGlobalPropertyDto().setKey("global").setValue("three,four"));
+    db.properties().insertProperties(null, null, null, null, newGlobalPropertyDto().setKey("global").setValue("three,four"));
 
     ValuesWsResponse result = executeRequestForGlobalProperties("default", "global");
     assertThat(result.getSettingsList()).hasSize(2);
@@ -141,7 +137,7 @@ public class ValuesActionTest {
   public void return_multi_value_with_coma() {
     logIn();
     definitions.addComponent(PropertyDefinition.builder("global").multiValues(true).build());
-    propertyDb.insertProperties(null, null, null, null, newGlobalPropertyDto().setKey("global").setValue("three,four%2Cfive"));
+    db.properties().insertProperties(null, null, null, null, newGlobalPropertyDto().setKey("global").setValue("three,four%2Cfive"));
 
     ValuesWsResponse result = executeRequestForGlobalProperties("global");
 
@@ -161,7 +157,7 @@ public class ValuesActionTest {
         PropertyFieldDefinition.build("key").name("Key").build(),
         PropertyFieldDefinition.build("size").name("Size").build()))
       .build());
-    propertyDb.insertPropertySet("foo", null, ImmutableMap.of("key", "key1", "size", "size1"), ImmutableMap.of("key", "key2"));
+    db.properties().insertPropertySet("foo", null, ImmutableMap.of("key", "key1", "size", "size1"), ImmutableMap.of("key", "key2"));
 
     ValuesWsResponse result = executeRequestForGlobalProperties("foo");
 
@@ -182,7 +178,7 @@ public class ValuesActionTest {
         PropertyFieldDefinition.build("key").name("Key").build(),
         PropertyFieldDefinition.build("size").name("Size").build()))
       .build());
-    propertyDb.insertPropertySet("foo", project, ImmutableMap.of("key", "key1", "size", "size1"), ImmutableMap.of("key", "key2"));
+    db.properties().insertPropertySet("foo", project, ImmutableMap.of("key", "key1", "size", "size1"), ImmutableMap.of("key", "key2"));
 
     ValuesWsResponse result = executeRequestForProjectProperties("foo");
 
@@ -210,7 +206,7 @@ public class ValuesActionTest {
   public void return_global_values() {
     logIn();
     definitions.addComponent(PropertyDefinition.builder("property").defaultValue("default").build());
-    propertyDb.insertProperties(null, null, null,
+    db.properties().insertProperties(null, null, null,
       // The property is overriding default value
       null, newGlobalPropertyDto().setKey("property").setValue("one"));
 
@@ -225,9 +221,9 @@ public class ValuesActionTest {
     logInAsProjectUser();
     definitions.addComponent(
       PropertyDefinition.builder("property").defaultValue("default").onQualifiers(PROJECT).build());
-    propertyDb.insertProperties(null, null, null,
+    db.properties().insertProperties(null, null, null,
       null, newGlobalPropertyDto().setKey("property").setValue("one"));
-    propertyDb.insertProperties(null, project.getKey(), project.name(), project.qualifier(),
+    db.properties().insertProperties(null, project.getKey(), project.name(), project.qualifier(),
       // The property is overriding global value
       newComponentPropertyDto(project).setKey("property").setValue("two"));
 
@@ -244,9 +240,9 @@ public class ValuesActionTest {
       PropertyDefinition.builder("global").build(),
       PropertyDefinition.builder("global.default").defaultValue("default").build(),
       PropertyDefinition.builder("project").onQualifiers(PROJECT).build()));
-    propertyDb.insertProperties(null, null, null,
+    db.properties().insertProperties(null, null, null,
       null, newGlobalPropertyDto().setKey("global").setValue("one"));
-    propertyDb.insertProperties(null, project.getKey(), project.name(), project.qualifier(),
+    db.properties().insertProperties(null, project.getKey(), project.name(), project.qualifier(),
       newComponentPropertyDto(project).setKey("project").setValue("two"));
 
     ValuesWsResponse result = executeRequestForProjectProperties();
@@ -260,7 +256,7 @@ public class ValuesActionTest {
     logInAsProjectUser();
     definitions.addComponent(PropertyDefinition.builder("property").defaultValue("default").onQualifiers(PROJECT).build());
     // The property is not defined on project
-    propertyDb.insertProperties(null, null, null, null,
+    db.properties().insertProperties(null, null, null, null,
       newGlobalPropertyDto().setKey("property").setValue("one"));
 
     ValuesWsResponse result = executeRequestForProjectProperties("property");
@@ -272,7 +268,7 @@ public class ValuesActionTest {
   @Test
   public void return_values_even_if_no_property_definition() {
     logIn();
-    propertyDb.insertProperties(null, null, null, null,
+    db.properties().insertProperties(null, null, null, null,
       newGlobalPropertyDto().setKey("globalPropertyWithoutDefinition").setValue("value"));
 
     ValuesWsResponse result = executeRequestForGlobalProperties("globalPropertyWithoutDefinition");
@@ -286,7 +282,7 @@ public class ValuesActionTest {
   @Test
   public void return_values_of_component_even_if_no_property_definition() {
     logInAsProjectUser();
-    propertyDb.insertProperties(null, project.getKey(), project.name(), project.qualifier(),
+    db.properties().insertProperties(null, project.getKey(), project.name(), project.qualifier(),
       newComponentPropertyDto(project).setKey("property").setValue("foo"));
 
     ValuesWsResponse response = executeRequestForComponentProperties(project, "property");
@@ -313,7 +309,7 @@ public class ValuesActionTest {
       .builder("foo")
       .defaultValue("default")
       .build());
-    propertyDb.insertProperties(null, null, null, null,
+    db.properties().insertProperties(null, null, null, null,
       newGlobalPropertyDto().setKey("bar").setValue(""));
 
     ValuesWsResponse result = executeRequestForGlobalProperties("unknown");
@@ -324,11 +320,11 @@ public class ValuesActionTest {
   @Test
   public void return_module_values() {
     logInAsProjectUser();
-    ComponentDto module = componentDb.insertComponent(newModuleDto(project));
+    ComponentDto module = db.components().insertComponent(newModuleDto(project));
     definitions.addComponent(PropertyDefinition.builder("property").defaultValue("default").onQualifiers(PROJECT, MODULE).build());
-    propertyDb.insertProperties(null, null, null, null,
+    db.properties().insertProperties(null, null, null, null,
       newGlobalPropertyDto().setKey("property").setValue("one"));
-    propertyDb.insertProperties(null, module.getKey(), module.name(), module.qualifier(),
+    db.properties().insertProperties(null, module.getKey(), module.name(), module.qualifier(),
       // The property is overriding global value
       newComponentPropertyDto(module).setKey("property").setValue("two"));
 
@@ -341,17 +337,17 @@ public class ValuesActionTest {
   @Test
   public void return_inherited_values_on_module() {
     logInAsProjectUser();
-    ComponentDto module = componentDb.insertComponent(newModuleDto(project));
+    ComponentDto module = db.components().insertComponent(newModuleDto(project));
     definitions.addComponents(asList(
       PropertyDefinition.builder("defaultProperty").defaultValue("default").onQualifiers(PROJECT, MODULE).build(),
       PropertyDefinition.builder("globalProperty").onQualifiers(PROJECT, MODULE).build(),
       PropertyDefinition.builder("projectProperty").onQualifiers(PROJECT, MODULE).build(),
       PropertyDefinition.builder("moduleProperty").onQualifiers(PROJECT, MODULE).build()));
-    propertyDb.insertProperties(null, null, null, null,
+    db.properties().insertProperties(null, null, null, null,
       newGlobalPropertyDto().setKey("globalProperty").setValue("global"));
-    propertyDb.insertProperties(null, project.getKey(), project.name(), project.qualifier(),
+    db.properties().insertProperties(null, project.getKey(), project.name(), project.qualifier(),
       newComponentPropertyDto(project).setKey("projectProperty").setValue("project"));
-    propertyDb.insertProperties(null, module.getKey(), module.name(), module.qualifier(),
+    db.properties().insertProperties(null, module.getKey(), module.name(), module.qualifier(),
       newComponentPropertyDto(module).setKey("moduleProperty").setValue("module"));
 
     ValuesWsResponse result = executeRequestForComponentProperties(module, "defaultProperty", "globalProperty", "projectProperty", "moduleProperty");
@@ -369,7 +365,7 @@ public class ValuesActionTest {
     definitions.addComponents(asList(
       PropertyDefinition.builder("defaultProperty").defaultValue("default").build(),
       PropertyDefinition.builder("globalProperty").build()));
-    propertyDb.insertProperties(null, null, null, null,
+    db.properties().insertProperties(null, null, null, null,
       newGlobalPropertyDto().setKey("globalProperty").setValue("global"));
 
     ValuesWsResponse result = executeRequestForGlobalProperties("defaultProperty", "globalProperty");
@@ -382,15 +378,15 @@ public class ValuesActionTest {
   @Test
   public void return_parent_value() {
     logInAsProjectUser();
-    ComponentDto module = componentDb.insertComponent(newModuleDto(project));
-    ComponentDto subModule = componentDb.insertComponent(newModuleDto(module));
+    ComponentDto module = db.components().insertComponent(newModuleDto(project));
+    ComponentDto subModule = db.components().insertComponent(newModuleDto(module));
     definitions.addComponents(asList(
       PropertyDefinition.builder("foo").defaultValue("default").onQualifiers(PROJECT, MODULE).build()));
-    propertyDb.insertProperties(null, null, null, null,
+    db.properties().insertProperties(null, null, null, null,
       newGlobalPropertyDto().setKey("foo").setValue("global"));
-    propertyDb.insertProperties(null, project.getKey(), project.name(), project.qualifier(),
+    db.properties().insertProperties(null, project.getKey(), project.name(), project.qualifier(),
       newComponentPropertyDto(project).setKey("foo").setValue("project"));
-    propertyDb.insertProperties(null, module.getKey(), module.name(), module.qualifier(),
+    db.properties().insertProperties(null, module.getKey(), module.name(), module.qualifier(),
       newComponentPropertyDto(module).setKey("foo").setValue("module"));
 
     assertParentValue(executeRequestForComponentProperties(subModule, "foo").getSettings(0), "module");
@@ -402,15 +398,15 @@ public class ValuesActionTest {
   @Test
   public void return_parent_values() {
     logInAsProjectUser();
-    ComponentDto module = componentDb.insertComponent(newModuleDto(project));
-    ComponentDto subModule = componentDb.insertComponent(newModuleDto(module));
+    ComponentDto module = db.components().insertComponent(newModuleDto(project));
+    ComponentDto subModule = db.components().insertComponent(newModuleDto(module));
     definitions.addComponents(asList(
       PropertyDefinition.builder("foo").defaultValue("default1,default2").multiValues(true).onQualifiers(PROJECT, MODULE).build()));
-    propertyDb.insertProperties(null, null, null, null,
+    db.properties().insertProperties(null, null, null, null,
       newGlobalPropertyDto().setKey("foo").setValue("global1,global2"));
-    propertyDb.insertProperties(null, project.getKey(), project.name(), project.qualifier(),
+    db.properties().insertProperties(null, project.getKey(), project.name(), project.qualifier(),
       newComponentPropertyDto(project).setKey("foo").setValue("project1,project2"));
-    propertyDb.insertProperties(null, module.getKey(), module.name(), module.qualifier(),
+    db.properties().insertProperties(null, module.getKey(), module.name(), module.qualifier(),
       newComponentPropertyDto(module).setKey("foo").setValue("module1,module2"));
 
     assertParentValues(executeRequestForComponentProperties(subModule, "foo").getSettings(0), "module1", "module2");
@@ -422,8 +418,8 @@ public class ValuesActionTest {
   @Test
   public void return_parent_field_values() {
     logInAsProjectUser();
-    ComponentDto module = componentDb.insertComponent(newModuleDto(project));
-    ComponentDto subModule = componentDb.insertComponent(newModuleDto(module));
+    ComponentDto module = db.components().insertComponent(newModuleDto(project));
+    ComponentDto subModule = db.components().insertComponent(newModuleDto(module));
     definitions.addComponent(PropertyDefinition
       .builder("foo")
       .onQualifiers(PROJECT, MODULE)
@@ -432,9 +428,9 @@ public class ValuesActionTest {
         PropertyFieldDefinition.build("key").name("Key").build(),
         PropertyFieldDefinition.build("size").name("Size").build()))
       .build());
-    propertyDb.insertPropertySet("foo", null, ImmutableMap.of("key", "keyG1", "size", "sizeG1"));
-    propertyDb.insertPropertySet("foo", project, ImmutableMap.of("key", "keyP1", "size", "sizeP1"));
-    propertyDb.insertPropertySet("foo", module, ImmutableMap.of("key", "keyM1", "size", "sizeM1"));
+    db.properties().insertPropertySet("foo", null, ImmutableMap.of("key", "keyG1", "size", "sizeG1"));
+    db.properties().insertPropertySet("foo", project, ImmutableMap.of("key", "keyP1", "size", "sizeP1"));
+    db.properties().insertPropertySet("foo", module, ImmutableMap.of("key", "keyM1", "size", "sizeM1"));
 
     assertParentFieldValues(executeRequestForComponentProperties(subModule, "foo").getSettings(0), ImmutableMap.of("key", "keyM1", "size", "sizeM1"));
     assertParentFieldValues(executeRequestForComponentProperties(module, "foo").getSettings(0), ImmutableMap.of("key", "keyP1", "size", "sizeP1"));
@@ -445,8 +441,8 @@ public class ValuesActionTest {
   @Test
   public void return_no_parent_value() {
     logInAsProjectUser();
-    ComponentDto module = componentDb.insertComponent(newModuleDto(project));
-    ComponentDto subModule = componentDb.insertComponent(newModuleDto(module));
+    ComponentDto module = db.components().insertComponent(newModuleDto(project));
+    ComponentDto subModule = db.components().insertComponent(newModuleDto(module));
     definitions.addComponents(asList(
       PropertyDefinition.builder("simple").onQualifiers(PROJECT, MODULE).build(),
       PropertyDefinition.builder("multi").multiValues(true).onQualifiers(PROJECT, MODULE).build(),
@@ -457,10 +453,10 @@ public class ValuesActionTest {
           PropertyFieldDefinition.build("key").name("Key").build(),
           PropertyFieldDefinition.build("size").name("Size").build()))
         .build()));
-    propertyDb.insertProperties(null, module.getKey(), module.name(), module.qualifier(),
+    db.properties().insertProperties(null, module.getKey(), module.name(), module.qualifier(),
       newComponentPropertyDto(module).setKey("simple").setValue("module"),
       newComponentPropertyDto(module).setKey("multi").setValue("module1,module2"));
-    propertyDb.insertPropertySet("set", module, ImmutableMap.of("key", "keyM1", "size", "sizeM1"));
+    db.properties().insertPropertySet("set", module, ImmutableMap.of("key", "keyM1", "size", "sizeM1"));
 
     assertParentValue(executeRequestForComponentProperties(subModule, "simple").getSettings(0), null);
     assertParentValues(executeRequestForComponentProperties(subModule, "multi").getSettings(0));
@@ -470,10 +466,10 @@ public class ValuesActionTest {
   @Test
   public void return_parent_value_when_no_definition() {
     logInAsProjectUser();
-    ComponentDto module = componentDb.insertComponent(newModuleDto(project));
-    propertyDb.insertProperties(null, null, null, null,
+    ComponentDto module = db.components().insertComponent(newModuleDto(project));
+    db.properties().insertProperties(null, null, null, null,
       newGlobalPropertyDto().setKey("foo").setValue("global"));
-    propertyDb.insertProperties(null, project.getKey(), project.name(), project.qualifier(),
+    db.properties().insertProperties(null, project.getKey(), project.name(), project.qualifier(),
       newComponentPropertyDto(project).setKey("foo").setValue("project"));
 
     assertParentValue(executeRequestForComponentProperties(module, "foo").getSettings(0), "project");
@@ -488,7 +484,7 @@ public class ValuesActionTest {
       .builder("foo")
       .deprecatedKey("deprecated")
       .build());
-    propertyDb.insertProperties(null, null, null, null,
+    db.properties().insertProperties(null, null, null, null,
       newGlobalPropertyDto().setKey("foo").setValue("one"));
 
     ValuesWsResponse result = executeRequestForGlobalProperties("deprecated");
@@ -504,7 +500,7 @@ public class ValuesActionTest {
     definitions.addComponents(asList(
       PropertyDefinition.builder("foo").build(),
       PropertyDefinition.builder("secret.secured").build()));
-    propertyDb.insertProperties(null, null, null, null,
+    db.properties().insertProperties(null, null, null, null,
       newGlobalPropertyDto().setKey("foo").setValue("one"),
       newGlobalPropertyDto().setKey("secret.secured").setValue("password"));
 
@@ -522,7 +518,7 @@ public class ValuesActionTest {
         PropertyFieldDefinition.build("key").name("Key").build(),
         PropertyFieldDefinition.build("secret.secured").name("Secured").build()))
       .build());
-    propertyDb.insertPropertySet("foo", null, ImmutableMap.of("key", "key1", "secret.secured", "123456"));
+    db.properties().insertPropertySet("foo", null, ImmutableMap.of("key", "key1", "secret.secured", "123456"));
 
     ValuesWsResponse result = executeRequestForGlobalProperties();
 
@@ -535,7 +531,7 @@ public class ValuesActionTest {
     definitions.addComponents(asList(
       PropertyDefinition.builder("foo").build(),
       PropertyDefinition.builder("secret.secured").build()));
-    propertyDb.insertProperties(null, null, null, null,
+    db.properties().insertProperties(null, null, null, null,
       newGlobalPropertyDto().setKey("foo").setValue("one"),
       newGlobalPropertyDto().setKey("secret.secured").setValue("password"));
 
@@ -554,9 +550,9 @@ public class ValuesActionTest {
       PropertyDefinition.builder("foo").onQualifiers(PROJECT).build(),
       PropertyDefinition.builder("global.secret.secured").build(),
       PropertyDefinition.builder("secret.secured").onQualifiers(PROJECT).build()));
-    propertyDb.insertProperties(null, null, null, null,
+    db.properties().insertProperties(null, null, null, null,
       newGlobalPropertyDto().setKey("global.secret.secured").setValue("very secret"));
-    propertyDb.insertProperties(null, project.getKey(), project.name(), project.qualifier(),
+    db.properties().insertProperties(null, project.getKey(), project.name(), project.qualifier(),
       newComponentPropertyDto(project).setKey("foo").setValue("one"),
       newComponentPropertyDto(project).setKey("secret.secured").setValue("password"));
 
@@ -571,7 +567,7 @@ public class ValuesActionTest {
     userSession
       .addProjectPermission(USER, project)
       .addProjectPermission(SCAN_EXECUTION, project);
-    propertyDb.insertProperties(null, project.getKey(), project.name(), project.qualifier(),
+    db.properties().insertProperties(null, project.getKey(), project.name(), project.qualifier(),
       newComponentPropertyDto(project).setKey("not-defined.secured").setValue("123"));
 
     ValuesWsResponse result = executeRequestForProjectProperties("not-defined.secured");
@@ -585,7 +581,7 @@ public class ValuesActionTest {
     definitions.addComponents(asList(
       PropertyDefinition.builder("foo").build(),
       PropertyDefinition.builder("secret.secured").build()));
-    propertyDb.insertProperties(null, null, null, null,
+    db.properties().insertProperties(null, null, null, null,
       newGlobalPropertyDto().setKey("foo").setValue("one"),
       newGlobalPropertyDto().setKey("secret.secured").setValue("password"));
 
@@ -602,9 +598,9 @@ public class ValuesActionTest {
       PropertyDefinition.builder("foo").onQualifiers(PROJECT).build(),
       PropertyDefinition.builder("global.secret.secured").build(),
       PropertyDefinition.builder("secret.secured").onQualifiers(PROJECT).build()));
-    propertyDb.insertProperties(null, null, null, null,
+    db.properties().insertProperties(null, null, null, null,
       newGlobalPropertyDto().setKey("global.secret.secured").setValue("very secret"));
-    propertyDb.insertProperties(null, project.getKey(), project.name(), project.qualifier(),
+    db.properties().insertProperties(null, project.getKey(), project.name(), project.qualifier(),
       newComponentPropertyDto(project).setKey("foo").setValue("one"),
       newComponentPropertyDto(project).setKey("secret.secured").setValue("password"));
 
@@ -619,7 +615,7 @@ public class ValuesActionTest {
   @Test
   public void return_secured_settings_even_if_not_defined_when_project_admin() {
     logInAsProjectAdmin();
-    propertyDb.insertProperties(null, project.getKey(), project.name(), project.qualifier(),
+    db.properties().insertProperties(null, project.getKey(), project.name(), project.qualifier(),
       newComponentPropertyDto(project).setKey("not-defined.secured").setValue("123"));
 
     ValuesWsResponse result = executeRequestForProjectProperties("not-defined.secured");
@@ -638,7 +634,7 @@ public class ValuesActionTest {
         PropertyFieldDefinition.build("key").name("Key").build(),
         PropertyFieldDefinition.build("secret.secured").name("Secured").build()))
       .build());
-    propertyDb.insertPropertySet("foo", null, ImmutableMap.of("key", "key1", "secret.secured", "123456"));
+    db.properties().insertPropertySet("foo", null, ImmutableMap.of("key", "key1", "secret.secured", "123456"));
 
     ValuesWsResponse result = executeRequestForGlobalProperties();
 
@@ -657,7 +653,7 @@ public class ValuesActionTest {
         PropertyFieldDefinition.build(anyAdminOnlySettingKey).name("Value admin only").build()))
       .build());
     ImmutableMap<String, String> keyValuePairs = ImmutableMap.of(anyAdminOnlySettingKey, "test_val");
-    propertyDb.insertPropertySet(anyAdminOnlySettingKey, null, keyValuePairs);
+    db.properties().insertPropertySet(anyAdminOnlySettingKey, null, keyValuePairs);
 
     ValuesWsResponse result = executeRequestForGlobalProperties();
 
@@ -676,7 +672,7 @@ public class ValuesActionTest {
         PropertyFieldDefinition.build(anyAdminOnlySettingKey).name("Value admin only").build()))
       .build());
     ImmutableMap<String, String> keyValuePairs = ImmutableMap.of(anyAdminOnlySettingKey, "test_val");
-    propertyDb.insertPropertySet(anyAdminOnlySettingKey, null, keyValuePairs);
+    db.properties().insertPropertySet(anyAdminOnlySettingKey, null, keyValuePairs);
 
     ValuesWsResponse result = executeRequestForGlobalProperties();
 
@@ -689,7 +685,7 @@ public class ValuesActionTest {
     definitions.addComponents(asList(
       PropertyDefinition.builder("foo").build(),
       PropertyDefinition.builder("secret.secured").build()));
-    propertyDb.insertProperties(null, null, null, null,
+    db.properties().insertProperties(null, null, null, null,
       newGlobalPropertyDto().setKey("foo").setValue("one"),
       newGlobalPropertyDto().setKey("secret.secured").setValue("password"));
 
@@ -705,7 +701,7 @@ public class ValuesActionTest {
     definitions.addComponents(asList(
       PropertyDefinition.builder("foo").onQualifiers(PROJECT).build(),
       PropertyDefinition.builder("secret.secured").onQualifiers(PROJECT).build()));
-    propertyDb.insertProperties(null, project.getKey(), project.name(), project.qualifier(),
+    db.properties().insertProperties(null, project.getKey(), project.name(), project.qualifier(),
       newComponentPropertyDto(project).setKey("foo").setValue("one"),
       newComponentPropertyDto(project).setKey("secret.secured").setValue("password"));
 
@@ -719,7 +715,7 @@ public class ValuesActionTest {
   public void return_additional_settings_specific_for_scanner_when_no_keys() {
     logInAsAdmin();
     definitions.addComponent(PropertyDefinition.builder("secret.secured").build());
-    propertyDb.insertProperties(null, null, null, null,
+    db.properties().insertProperties(null, null, null, null,
       newGlobalPropertyDto().setKey("sonar.core.id").setValue("ID"),
       newGlobalPropertyDto().setKey("sonar.core.startTime").setValue("2017-01-01"));
 
@@ -734,7 +730,7 @@ public class ValuesActionTest {
     definitions.addComponent(PropertyDefinition
       .builder("foo")
       .build());
-    propertyDb.insertProperties(null, null, null, null,
+    db.properties().insertProperties(null, null, null, null,
       newGlobalPropertyDto().setKey("foo").setValue("fi±∞…"));
 
     ValuesWsResponse result = executeRequestForGlobalProperties("foo");
@@ -760,7 +756,7 @@ public class ValuesActionTest {
       .builder("foo")
       .deprecatedKey("deprecated")
       .build());
-    propertyDb.insertProperties(null, null, null, null,
+    db.properties().insertProperties(null, null, null, null,
       newGlobalPropertyDto().setKey("foo").setValue("one"));
 
     assertThatThrownBy(() -> {
@@ -773,7 +769,7 @@ public class ValuesActionTest {
   @Test
   public void fail_when_component_not_found() {
     assertThatThrownBy(() -> {
-      newTester().newRequest()
+      wsActionTester.newRequest()
         .setParam("keys", "foo")
         .setParam("component", "unknown")
         .execute();
@@ -793,7 +789,7 @@ public class ValuesActionTest {
       .builder("sonar.autogenerated")
       .multiValues(true)
       .build());
-    propertyDb.insertProperties(null, null, null, null,
+    db.properties().insertProperties(null, null, null, null,
       newGlobalPropertyDto().setKey("sonar.autogenerated").setValue("val1,val2,val3"));
     definitions.addComponent(PropertyDefinition
       .builder("sonar.demo")
@@ -801,22 +797,22 @@ public class ValuesActionTest {
       .fields(PropertyFieldDefinition.build("text").name("Text").build(),
         PropertyFieldDefinition.build("boolean").name("Boolean").build())
       .build());
-    propertyDb.insertPropertySet("sonar.demo", null, ImmutableMap.of("text", "foo", "boolean", "true"), ImmutableMap.of("text", "bar", "boolean", "false"));
+    db.properties().insertPropertySet("sonar.demo", null, ImmutableMap.of("text", "foo", "boolean", "true"), ImmutableMap.of("text", "bar", "boolean", "false"));
 
     definitions.addComponent(PropertyDefinition
       .builder("email.smtp_port.secured")
       .defaultValue("25")
       .build());
-    propertyDb.insertProperties(null, null, null, null,
+    db.properties().insertProperties(null, null, null, null,
       newGlobalPropertyDto().setKey("email.smtp_port.secured").setValue("25"));
 
-    String result = newTester().newRequest()
+    String result = wsActionTester.newRequest()
       .setParam("keys", "sonar.test.jira,sonar.autogenerated,sonar.demo,email.smtp_port.secured")
       .setMediaType(JSON)
       .execute()
       .getInput();
 
-    JsonAssert.assertJson(newTester().getDef().responseExampleAsString()).isSimilarTo(result);
+    JsonAssert.assertJson(wsActionTester.getDef().responseExampleAsString()).isSimilarTo(result);
   }
 
   @Test
@@ -826,7 +822,7 @@ public class ValuesActionTest {
     String settingKey = ProcessProperties.Property.JDBC_URL.getKey();
 
     assertThatThrownBy(() -> {
-      newTester().newRequest()
+      wsActionTester.newRequest()
         .setParam("keys", settingKey)
         .setParam("component", project.getKey())
         .execute();
@@ -837,7 +833,7 @@ public class ValuesActionTest {
 
   @Test
   public void test_ws_definition() {
-    WebService.Action action = newTester().getDef();
+    WebService.Action action = wsActionTester.getDef();
     assertThat(action).isNotNull();
     assertThat(action.isInternal()).isFalse();
     assertThat(action.isPost()).isFalse();
@@ -850,30 +846,29 @@ public class ValuesActionTest {
     PropertyDefinition securedDef = PropertyDefinition.builder("my.password.secured").build();
     PropertyDefinition standardDef = PropertyDefinition.builder("my.property").build();
     definitions.addComponents(asList(securedDef, standardDef));
-    propertyDb.insertProperties(null, null, null, null,
+    db.properties().insertProperties(null, null, null, null,
       newGlobalPropertyDto().setKey(securedDef.key()).setValue("securedValue"),
       newGlobalPropertyDto().setKey(standardDef.key()).setValue("standardValue"));
 
     // anonymous
-    WsActionTester tester = newTester();
-    ValuesWsResponse response = executeRequest(tester, null, securedDef.key(), standardDef.key());
+    ValuesWsResponse response = executeRequest(null, securedDef.key(), standardDef.key());
     assertThat(response.getSettingsList()).extracting(Settings.Setting::getKey).containsExactly("my.property");
 
     // only scan global permission
     userSession.logIn()
       .addPermission(GlobalPermission.SCAN);
-    response = executeRequest(tester, null, securedDef.key(), standardDef.key());
+    response = executeRequest(null, securedDef.key(), standardDef.key());
     assertThat(response.getSetSecuredSettingsList()).contains("my.password.secured");
 
     // global administrator
     userSession.logIn()
       .addPermission(GlobalPermission.ADMINISTER);
-    response = executeRequest(tester, null, securedDef.key(), standardDef.key());
+    response = executeRequest(null, securedDef.key(), standardDef.key());
     assertThat(response.getSetSecuredSettingsList()).contains("my.password.secured");
 
     // system administrator
     userSession.logIn().setSystemAdministrator();
-    response = executeRequest(tester, null, securedDef.key(), standardDef.key());
+    response = executeRequest(null, securedDef.key(), standardDef.key());
     assertThat(response.getSetSecuredSettingsList()).contains("my.password.secured");
   }
 
@@ -890,11 +885,7 @@ public class ValuesActionTest {
   }
 
   private ValuesWsResponse executeRequest(@Nullable String componentKey, String... keys) {
-    return executeRequest(newTester(), componentKey, keys);
-  }
-
-  private ValuesWsResponse executeRequest(WsActionTester tester, @Nullable String componentKey, String... keys) {
-    TestRequest request = tester.newRequest();
+    TestRequest request = wsActionTester.newRequest();
     if (keys.length > 0) {
       request.setParam("keys", COMMA_JOINER.join(keys));
     }
@@ -965,10 +956,4 @@ public class ValuesActionTest {
       }
     }
   }
-
-  private WsActionTester newTester() {
-    MapSettings settings = new MapSettings();
-    return new WsActionTester(new ValuesAction(dbClient, TestComponentFinder.from(db), userSession, definitions, support));
-  }
-
 }