瀏覽代碼

SONAR-13903 Remove use of organizations in Quality Profiles and Active Rules

tags/8.6.0.39681
Pierre 3 年之前
父節點
當前提交
13d76f2a2c
共有 100 個文件被更改,包括 1035 次插入1905 次删除
  1. 4
    6
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/AdHocRuleCreator.java
  2. 3
    6
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/RuleRepositoryImpl.java
  3. 2
    27
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStep.java
  4. 7
    14
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/AdHocRuleCreatorTest.java
  5. 7
    10
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/RuleRepositoryImplTest.java
  6. 2
    44
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStepTest.java
  7. 1
    6
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/PersistAdHocRulesStepTest.java
  8. 1
    4
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/PersistIssuesStepTest.java
  9. 0
    1
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ViewsPersistComponentsStepTest.java
  10. 0
    80
      server/sonar-db-dao/src/main/java/org/sonar/db/es/RuleExtensionId.java
  11. 0
    14
      server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ActiveRuleCountQuery.java
  12. 9
    10
      server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ActiveRuleDao.java
  13. 4
    4
      server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ActiveRuleMapper.java
  14. 7
    6
      server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/DefaultQProfileDao.java
  15. 0
    13
      server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/DefaultQProfileDto.java
  16. 3
    5
      server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/DefaultQProfileMapper.java
  17. 0
    11
      server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/OrgActiveRuleDto.java
  18. 0
    15
      server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/OrgQProfileDto.java
  19. 0
    18
      server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileDto.java
  20. 2
    3
      server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditGroupsDao.java
  21. 1
    1
      server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditGroupsMapper.java
  22. 2
    7
      server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditUsersDao.java
  23. 1
    3
      server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditUsersMapper.java
  24. 24
    25
      server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QualityProfileDao.java
  25. 6
    20
      server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QualityProfileMapper.java
  26. 0
    13
      server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/SearchGroupsQuery.java
  27. 0
    14
      server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/SearchUsersQuery.java
  28. 19
    60
      server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDao.java
  29. 3
    3
      server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDefinitionDto.java
  30. 0
    9
      server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java
  31. 0
    10
      server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleExtensionForIndexingDto.java
  32. 5
    0
      server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleForIndexingDto.java
  33. 9
    12
      server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleMapper.java
  34. 0
    11
      server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleMetadataDto.java
  35. 3
    7
      server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/ActiveRuleMapper.xml
  36. 4
    10
      server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/DefaultQProfileMapper.xml
  37. 1
    3
      server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/QProfileEditGroupsMapper.xml
  38. 1
    15
      server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/QProfileEditUsersMapper.xml
  39. 2
    23
      server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/QualityProfileMapper.xml
  40. 4
    16
      server/sonar-db-dao/src/main/resources/org/sonar/db/rule/RuleMapper.xml
  41. 2
    6
      server/sonar-db-dao/src/schema/schema-sq.ddl
  42. 0
    6
      server/sonar-db-dao/src/test/java/org/sonar/db/permission/AuthorizationDaoTest.java
  43. 17
    32
      server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/ActiveRuleDaoTest.java
  44. 22
    50
      server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/DefaultQProfileDaoTest.java
  45. 12
    12
      server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/QProfileChangeDaoTest.java
  46. 45
    78
      server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/QProfileEditGroupsDaoTest.java
  47. 28
    77
      server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/QProfileEditUsersDaoTest.java
  48. 95
    174
      server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/QualityProfileDaoTest.java
  49. 2
    5
      server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/QualityProfileExportDaoTest.java
  50. 77
    283
      server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDaoTest.java
  51. 0
    1
      server/sonar-db-dao/src/test/java/org/sonar/db/webhook/WebhookDaoTest.java
  52. 6
    0
      server/sonar-db-dao/src/testFixtures/java/org/sonar/db/component/ComponentDbTester.java
  53. 4
    0
      server/sonar-db-dao/src/testFixtures/java/org/sonar/db/organization/OrganizationDbTester.java
  54. 9
    8
      server/sonar-db-dao/src/testFixtures/java/org/sonar/db/qualityprofile/QualityProfileDbTester.java
  55. 0
    1
      server/sonar-db-dao/src/testFixtures/java/org/sonar/db/qualityprofile/QualityProfileTesting.java
  56. 8
    10
      server/sonar-db-dao/src/testFixtures/java/org/sonar/db/rule/RuleDbTester.java
  57. 9
    64
      server/sonar-db-dao/src/testFixtures/java/org/sonar/db/rule/RuleTesting.java
  58. 5
    0
      server/sonar-db-dao/src/testFixtures/java/org/sonar/db/user/UserDbTester.java
  59. 36
    0
      server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v85/AddPrimaryKeyToDefaultQProfiles.java
  60. 5
    1
      server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v85/DbVersion85.java
  61. 36
    0
      server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v85/DropDefaultQProfilesPk.java
  62. 36
    0
      server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v85/DropOrganizationFromDefaultQProfiles.java
  63. 37
    0
      server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v85/DropOrganizationFromQualityProfileTable.java
  64. 42
    0
      server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v85/DropOrganizationInRulesMetadata.java
  65. 40
    0
      server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v85/AddPrimaryKeyToDefaultQProfilesTest.java
  66. 41
    0
      server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v85/DropDefaultQProfilesPkTest.java
  67. 41
    0
      server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v85/DropOrganizationFromDefaultQProfilesTest.java
  68. 40
    0
      server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v85/DropOrganizationFromQualityProfileTableTest.java
  69. 40
    0
      server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v85/DropOrganizationInRulesMetadataTest.java
  70. 7
    0
      server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v85/AddPrimaryKeyToDefaultQProfilesTest/schema.sql
  71. 9
    0
      server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v85/DropDefaultQProfilesPkTest/schema.sql
  72. 8
    0
      server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v85/DropOrganizationFromDefaultQProfilesTest/schema.sql
  73. 14
    0
      server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v85/DropOrganizationFromQualityProfileTableTest/schema.sql
  74. 19
    0
      server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v85/DropOrganizationInRulesMetadataTest/schema.sql
  75. 3
    11
      server/sonar-server-common/src/main/java/org/sonar/server/es/BulkIndexer.java
  76. 2
    1
      server/sonar-server-common/src/main/java/org/sonar/server/es/EsClient.java
  77. 1
    1
      server/sonar-server-common/src/main/java/org/sonar/server/organization/DefaultOrganizationProviderImpl.java
  78. 4
    9
      server/sonar-server-common/src/main/java/org/sonar/server/rule/DefaultRuleFinder.java
  79. 12
    0
      server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleDoc.java
  80. 0
    102
      server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleExtensionDoc.java
  81. 0
    61
      server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleExtensionScope.java
  82. 20
    55
      server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndex.java
  83. 2
    13
      server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndexDefinition.java
  84. 6
    67
      server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndexer.java
  85. 0
    10
      server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleQuery.java
  86. 2
    4
      server/sonar-server-common/src/test/java/org/sonar/server/qualityprofile/index/ActiveRuleIndexerTest.java
  87. 2
    5
      server/sonar-server-common/src/test/java/org/sonar/server/rule/DefaultRuleFinderTest.java
  88. 1
    1
      server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexDefinitionTest.java
  89. 28
    98
      server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java
  90. 6
    54
      server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexerTest.java
  91. 2
    2
      server/sonar-server-common/src/testFixtures/java/org/sonar/server/organization/TestDefaultOrganizationProvider.java
  92. 1
    6
      server/sonar-web/src/main/js/api/quality-profiles.ts
  93. 6
    6
      server/sonar-web/src/main/js/api/rules.ts
  94. 0
    1
      server/sonar-web/src/main/js/app/components/nav/component/projectInformation/meta/MetaQualityProfiles.tsx
  95. 1
    1
      server/sonar-web/src/main/js/apps/about/components/AboutApp.tsx
  96. 6
    12
      server/sonar-web/src/main/js/apps/about/components/AboutStandards.tsx
  97. 1
    14
      server/sonar-web/src/main/js/apps/about/components/__tests__/__snapshots__/AboutApp-test.tsx.snap
  98. 0
    2
      server/sonar-web/src/main/js/apps/coding-rules/components/ActivationButton.tsx
  99. 0
    2
      server/sonar-web/src/main/js/apps/coding-rules/components/ActivationFormModal.tsx
  100. 0
    0
      server/sonar-web/src/main/js/apps/coding-rules/components/App.tsx

+ 4
- 6
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/AdHocRuleCreator.java 查看文件

@@ -59,9 +59,9 @@ public class AdHocRuleCreator {
* Persists a new add hoc rule in the DB and indexes it.
* @return the rule that was inserted in the DB, which <b>includes the generated ID</b>.
*/
public RuleDto persistAndIndex(DbSession dbSession, NewAdHocRule adHoc, OrganizationDto organizationDto) {
public RuleDto persistAndIndex(DbSession dbSession, NewAdHocRule adHoc) {
RuleDao dao = dbClient.ruleDao();
Optional<RuleDto> existingRuleDtoOpt = dao.selectByKey(dbSession, organizationDto.getUuid(), adHoc.getKey());
Optional<RuleDto> existingRuleDtoOpt = dao.selectByKey(dbSession, adHoc.getKey());
RuleMetadataDto metadata;
long now = system2.now();
if (!existingRuleDtoOpt.isPresent()) {
@@ -76,9 +76,7 @@ public class AdHocRuleCreator {
.setCreatedAt(now)
.setUpdatedAt(now);
dao.insert(dbSession, dto);
metadata = new RuleMetadataDto()
.setRuleUuid(dto.getUuid())
.setOrganizationUuid(organizationDto.getUuid());
metadata = new RuleMetadataDto().setRuleUuid(dto.getUuid());
} else {
// No need to update the rule, only org specific metadata
RuleDto ruleDto = existingRuleDtoOpt.get();
@@ -113,7 +111,7 @@ public class AdHocRuleCreator {

}

RuleDto ruleDto = dao.selectOrFailByKey(dbSession, organizationDto, adHoc.getKey());
RuleDto ruleDto = dao.selectOrFailByKey(dbSession, adHoc.getKey());
ruleIndexer.commitAndIndex(dbSession, ruleDto.getUuid());
return ruleDto;
}

+ 3
- 6
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/RuleRepositoryImpl.java 查看文件

@@ -50,14 +50,12 @@ public class RuleRepositoryImpl implements RuleRepository {

private final AdHocRuleCreator creator;
private final DbClient dbClient;
private final AnalysisMetadataHolder analysisMetadataHolder;

private Map<RuleKey, NewAdHocRule> adHocRulesPersist = new HashMap<>();

public RuleRepositoryImpl(AdHocRuleCreator creator, DbClient dbClient, AnalysisMetadataHolder analysisMetadataHolder) {
public RuleRepositoryImpl(AdHocRuleCreator creator, DbClient dbClient) {
this.creator = creator;
this.dbClient = dbClient;
this.analysisMetadataHolder = analysisMetadataHolder;
}

public void addOrUpdateAddHocRuleIfNeeded(RuleKey ruleKey, Supplier<NewAdHocRule> ruleSupplier) {
@@ -79,7 +77,7 @@ public class RuleRepositoryImpl implements RuleRepository {
}

private void persistAndIndex(DbSession dbSession, NewAdHocRule adHocRule) {
Rule rule = new RuleImpl(creator.persistAndIndex(dbSession, adHocRule, analysisMetadataHolder.getOrganization().toDto()));
Rule rule = new RuleImpl(creator.persistAndIndex(dbSession, adHocRule));
rulesByUuid.put(rule.getUuid(), rule);
rulesByKey.put(adHocRule.getKey(), rule);
}
@@ -135,10 +133,9 @@ public class RuleRepositoryImpl implements RuleRepository {
private void loadRulesFromDb(DbSession dbSession) {
this.rulesByKey = new HashMap<>();
this.rulesByUuid = new HashMap<>();
String organizationUuid = analysisMetadataHolder.getOrganization().getUuid();
Multimap<String, DeprecatedRuleKeyDto> deprecatedRuleKeysByRuleUuid = dbClient.ruleDao().selectAllDeprecatedRuleKeys(dbSession).stream()
.collect(MoreCollectors.index(DeprecatedRuleKeyDto::getRuleUuid));
for (RuleDto ruleDto : dbClient.ruleDao().selectAll(dbSession, organizationUuid)) {
for (RuleDto ruleDto : dbClient.ruleDao().selectAll(dbSession)) {
Rule rule = new RuleImpl(ruleDto);
rulesByKey.put(ruleDto.getKey(), rule);
rulesByUuid.put(ruleDto.getUuid(), rule);

+ 2
- 27
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStep.java 查看文件

@@ -19,9 +19,7 @@
*/
package org.sonar.ce.task.projectanalysis.step;

import com.google.common.base.Joiner;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
@@ -34,12 +32,10 @@ import org.sonar.ce.task.projectanalysis.batch.BatchReportReader;
import org.sonar.ce.task.projectanalysis.component.BranchLoader;
import org.sonar.ce.task.step.ComputationStep;
import org.sonar.core.platform.PluginRepository;
import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.project.ProjectDto;
import org.sonar.db.qualityprofile.QProfileDto;
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.scanner.protocol.output.ScannerReport.Metadata.Plugin;
import org.sonar.scanner.protocol.output.ScannerReport.Metadata.QProfile;
@@ -51,7 +47,6 @@ import org.sonar.server.qualityprofile.QualityProfile;
import static com.google.common.base.Preconditions.checkState;
import static java.lang.String.format;
import static java.util.stream.Collectors.toMap;
import static org.sonar.core.util.stream.MoreCollectors.toList;

/**
* Feed analysis metadata holder with metadata from the analysis report.
@@ -86,7 +81,7 @@ public class LoadReportAnalysisMetadataHolderStep implements ComputationStep {
loadMetadata(reportMetadata);
Organization organization = loadOrganization(reportMetadata);
Runnable projectValidation = loadProject(reportMetadata, organization);
loadQualityProfiles(reportMetadata, organization);
loadQualityProfiles(reportMetadata);
branchLoader.load(reportMetadata);
projectValidation.run();
}
@@ -145,8 +140,7 @@ public class LoadReportAnalysisMetadataHolderStep implements ComputationStep {
}
}

private void loadQualityProfiles(ScannerReport.Metadata reportMetadata, Organization organization) {
checkQualityProfilesConsistency(reportMetadata, organization);
private void loadQualityProfiles(ScannerReport.Metadata reportMetadata) {
analysisMetadata.setQProfilesByLanguage(reportMetadata.getQprofilesPerLanguageMap().values().stream()
.collect(toMap(
QProfile::getLanguage,
@@ -167,25 +161,6 @@ public class LoadReportAnalysisMetadataHolderStep implements ComputationStep {
return pluginRepository.getPluginInfo(p.getKey()).getBasePlugin();
}

/**
* Check that the Quality profiles sent by scanner correctly relate to the project organization.
*/
private void checkQualityProfilesConsistency(ScannerReport.Metadata metadata, Organization organization) {
List<String> profileKeys = metadata.getQprofilesPerLanguageMap().values().stream()
.map(QProfile::getKey)
.collect(toList(metadata.getQprofilesPerLanguageMap().size()));
try (DbSession dbSession = dbClient.openSession(false)) {
List<QProfileDto> profiles = dbClient.qualityProfileDao().selectByUuids(dbSession, profileKeys);
String badKeys = profiles.stream()
.filter(p -> !p.getOrganizationUuid().equals(organization.getUuid()))
.map(QProfileDto::getKee)
.collect(MoreCollectors.join(Joiner.on(", ")));
if (!badKeys.isEmpty()) {
throw MessageException.of(format("Quality profiles with following keys don't exist in organization [%s]: %s", organization.getKey(), badKeys));
}
}
}

private void checkOrganizationKeyConsistency(ScannerReport.Metadata reportMetadata, Organization organization) {
String organizationKey = reportMetadata.getOrganizationKey();
String resolveReportOrganizationKey = resolveReportOrganizationKey(organizationKey);

+ 7
- 14
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/AdHocRuleCreatorTest.java 查看文件

@@ -27,7 +27,6 @@ import org.sonar.api.utils.System2;
import org.sonar.core.util.SequenceUuidFactory;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.db.rule.RuleDto;
import org.sonar.db.rule.RuleMetadataDto;
@@ -52,10 +51,9 @@ public class AdHocRuleCreatorTest {

@Test
public void create_ad_hoc_rule_from_issue() {
OrganizationDto organization = db.organizations().insert();
NewAdHocRule addHocRule = new NewAdHocRule(ScannerReport.ExternalIssue.newBuilder().setEngineId("eslint").setRuleId("no-cond-assign").build());

RuleDto rule = underTest.persistAndIndex(dbSession, addHocRule, organization);
RuleDto rule = underTest.persistAndIndex(dbSession, addHocRule);

assertThat(rule).isNotNull();
assertThat(rule.isExternal()).isTrue();
@@ -74,7 +72,6 @@ public class AdHocRuleCreatorTest {

@Test
public void create_ad_hoc_rule_from_scanner_report() {
OrganizationDto organization = db.organizations().insert();
NewAdHocRule addHocRule = new NewAdHocRule(ScannerReport.AdHocRule.newBuilder()
.setEngineId("eslint")
.setRuleId("no-cond-assign")
@@ -84,7 +81,7 @@ public class AdHocRuleCreatorTest {
.setType(ScannerReport.IssueType.BUG)
.build());

RuleDto rule = underTest.persistAndIndex(dbSession, addHocRule, organization);
RuleDto rule = underTest.persistAndIndex(dbSession, addHocRule);

assertThat(rule).isNotNull();
assertThat(rule.isExternal()).isTrue();
@@ -103,7 +100,6 @@ public class AdHocRuleCreatorTest {

@Test
public void truncate_metadata_name_and_desc_if_longer_than_max_value() {
OrganizationDto organization = db.organizations().insert();
NewAdHocRule addHocRule = new NewAdHocRule(ScannerReport.AdHocRule.newBuilder()
.setEngineId("eslint")
.setRuleId("no-cond-assign")
@@ -113,7 +109,7 @@ public class AdHocRuleCreatorTest {
.setType(ScannerReport.IssueType.BUG)
.build());

RuleDto rule = underTest.persistAndIndex(dbSession, addHocRule, organization);
RuleDto rule = underTest.persistAndIndex(dbSession, addHocRule);

assertThat(rule.getMetadata().getAdHocName()).isEqualTo(repeat("a", 200));
assertThat(rule.getMetadata().getAdHocDescription()).isEqualTo(repeat("a", 16_777_215));
@@ -121,7 +117,6 @@ public class AdHocRuleCreatorTest {

@Test
public void update_metadata_only() {
OrganizationDto organization = db.organizations().insert();
NewAdHocRule addHocRule = new NewAdHocRule(ScannerReport.AdHocRule.newBuilder()
.setEngineId("eslint")
.setRuleId("no-cond-assign")
@@ -130,7 +125,7 @@ public class AdHocRuleCreatorTest {
.setSeverity(Constants.Severity.BLOCKER)
.setType(ScannerReport.IssueType.BUG)
.build());
RuleDto rule = underTest.persistAndIndex(dbSession, addHocRule, organization);
RuleDto rule = underTest.persistAndIndex(dbSession, addHocRule);
long creationDate = rule.getCreatedAt();
NewAdHocRule addHocRuleUpdated = new NewAdHocRule(ScannerReport.AdHocRule.newBuilder()
.setEngineId("eslint")
@@ -141,7 +136,7 @@ public class AdHocRuleCreatorTest {
.setType(ScannerReport.IssueType.CODE_SMELL)
.build());

RuleDto ruleUpdated = underTest.persistAndIndex(dbSession, addHocRuleUpdated, organization);
RuleDto ruleUpdated = underTest.persistAndIndex(dbSession, addHocRuleUpdated);

assertThat(ruleUpdated).isNotNull();
assertThat(ruleUpdated.isExternal()).isTrue();
@@ -163,9 +158,8 @@ public class AdHocRuleCreatorTest {

@Test
public void does_not_update_rule_when_no_change() {
OrganizationDto organization = db.organizations().insert();
RuleDefinitionDto rule = db.rules().insert(r -> r.setRepositoryKey("external_eslint").setIsExternal(true).setIsAdHoc(true));
RuleMetadataDto ruleMetadata = db.rules().insertOrUpdateMetadata(rule, organization);
RuleMetadataDto ruleMetadata = db.rules().insertOrUpdateMetadata(rule);

RuleDto ruleUpdated = underTest.persistAndIndex(dbSession, new NewAdHocRule(ScannerReport.AdHocRule.newBuilder()
.setEngineId("eslint")
@@ -174,8 +168,7 @@ public class AdHocRuleCreatorTest {
.setDescription(ruleMetadata.getAdHocDescription())
.setSeverity(Constants.Severity.valueOf(ruleMetadata.getAdHocSeverity()))
.setType(ScannerReport.IssueType.forNumber(ruleMetadata.getAdHocType()))
.build()),
organization);
.build()));

assertThat(ruleUpdated).isNotNull();
assertThat(ruleUpdated.isExternal()).isTrue();

+ 7
- 10
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/RuleRepositoryImplTest.java 查看文件

@@ -64,9 +64,6 @@ public class RuleRepositoryImplTest {

@org.junit.Rule
public ExpectedException expectedException = ExpectedException.none();
@org.junit.Rule
public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule()
.setOrganizationUuid(ORGANIZATION_UUID, QUALITY_GATE_UUID);

@org.junit.Rule
public DbTester db = DbTester.create(System2.INSTANCE);
@@ -77,13 +74,13 @@ public class RuleRepositoryImplTest {

private RuleIndexer ruleIndexer = mock(RuleIndexer.class);
private AdHocRuleCreator adHocRuleCreator = new AdHocRuleCreator(db.getDbClient(), System2.INSTANCE, ruleIndexer, new SequenceUuidFactory());
private RuleRepositoryImpl underTest = new RuleRepositoryImpl(adHocRuleCreator, dbClient, analysisMetadataHolder);
private RuleRepositoryImpl underTest = new RuleRepositoryImpl(adHocRuleCreator, dbClient);

@Before
public void setUp() {
when(dbClient.openSession(anyBoolean())).thenReturn(dbSession);
when(dbClient.ruleDao()).thenReturn(ruleDao);
when(ruleDao.selectAll(any(DbSession.class), eq(ORGANIZATION_UUID))).thenReturn(ImmutableList.of(AB_RULE));
when(ruleDao.selectAll(any(DbSession.class))).thenReturn(ImmutableList.of(AB_RULE));
DeprecatedRuleKeyDto abDeprecatedRuleKey1 = deprecatedRuleKeyOf(AB_RULE, AB_RULE_DEPRECATED_KEY_1);
DeprecatedRuleKeyDto abDeprecatedRuleKey2 = deprecatedRuleKeyOf(AB_RULE, AB_RULE_DEPRECATED_KEY_2);
DeprecatedRuleKeyDto deprecatedRuleOfNonExistingRule = deprecatedRuleKeyOf("unknown-rule-uuid", DEPRECATED_KEY_OF_NON_EXITING_RULE);
@@ -110,7 +107,7 @@ public class RuleRepositoryImplTest {
public void first_call_to_getByKey_triggers_call_to_db_and_any_subsequent_get_or_find_call_does_not() {
underTest.getByKey(AB_RULE.getKey());

verify(ruleDao, times(1)).selectAll(any(DbSession.class), eq(ORGANIZATION_UUID));
verify(ruleDao, times(1)).selectAll(any(DbSession.class));

verifyNoMethodCallTriggersCallToDB();
}
@@ -119,7 +116,7 @@ public class RuleRepositoryImplTest {
public void first_call_to_findByKey_triggers_call_to_db_and_any_subsequent_get_or_find_call_does_not() {
underTest.findByKey(AB_RULE.getKey());

verify(ruleDao, times(1)).selectAll(any(DbSession.class), eq(ORGANIZATION_UUID));
verify(ruleDao, times(1)).selectAll(any(DbSession.class));

verifyNoMethodCallTriggersCallToDB();
}
@@ -128,7 +125,7 @@ public class RuleRepositoryImplTest {
public void first_call_to_getById_triggers_call_to_db_and_any_subsequent_get_or_find_call_does_not() {
underTest.getByUuid(AB_RULE.getUuid());

verify(ruleDao, times(1)).selectAll(any(DbSession.class), eq(ORGANIZATION_UUID));
verify(ruleDao, times(1)).selectAll(any(DbSession.class));

verifyNoMethodCallTriggersCallToDB();
}
@@ -137,7 +134,7 @@ public class RuleRepositoryImplTest {
public void first_call_to_findById_triggers_call_to_db_and_any_subsequent_get_or_find_call_does_not() {
underTest.findByUuid(AB_RULE.getUuid());

verify(ruleDao, times(1)).selectAll(any(DbSession.class), eq(ORGANIZATION_UUID));
verify(ruleDao, times(1)).selectAll(any(DbSession.class));

verifyNoMethodCallTriggersCallToDB();
}
@@ -280,7 +277,7 @@ public class RuleRepositoryImplTest {

@Test
public void persist_new_externally_defined_Rules() {
underTest = new RuleRepositoryImpl(adHocRuleCreator, db.getDbClient(), analysisMetadataHolder);
underTest = new RuleRepositoryImpl(adHocRuleCreator, db.getDbClient());

RuleKey ruleKey = RuleKey.of("external_eslint", "no-cond-assign");
underTest.addOrUpdateAddHocRuleIfNeeded(ruleKey, () -> new NewAdHocRule(ScannerReport.ExternalIssue.newBuilder().setEngineId("eslint").setRuleId("no-cond-assign").build()));

+ 2
- 44
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStepTest.java 查看文件

@@ -205,7 +205,8 @@ public class LoadReportAnalysisMetadataHolderStepTest {
ComputationStep underTest = createStep(res);

expectedException.expect(MessageException.class);
expectedException.expectMessage("Compute Engine task main component key is null. Project with UUID main_prj_uuid must have been deleted since report was uploaded. Can not proceed.");
expectedException
.expectMessage("Compute Engine task main component key is null. Project with UUID main_prj_uuid must have been deleted since report was uploaded. Can not proceed.");

underTest.execute(new TestComputationStepContext());
}
@@ -357,49 +358,6 @@ public class LoadReportAnalysisMetadataHolderStepTest {
};
}

@Test
public void execute_ensures_that_report_has_quality_profiles_matching_the_project_organization() {
OrganizationDto organization = db.organizations().insert();
ComponentDto project = db.components().insertPublicProject(organization);
ScannerReport.Metadata.Builder metadataBuilder = newBatchReportBuilder();
metadataBuilder
.setOrganizationKey(organization.getKey())
.setProjectKey(project.getDbKey());
metadataBuilder.getMutableQprofilesPerLanguage().put("js", ScannerReport.Metadata.QProfile.newBuilder().setKey("p1").setName("Sonar way").setLanguage("js").build());
reportReader.setMetadata(metadataBuilder.build());

db.qualityProfiles().insert(organization, p -> p.setLanguage("js").setKee("p1"));

ComputationStep underTest = createStep(createCeTask(project.getDbKey(), organization.getUuid()));

// no errors
underTest.execute(new TestComputationStepContext());
}

@Test
public void execute_fails_with_MessageException_when_report_has_quality_profiles_on_other_organizations() {
OrganizationDto organization1 = db.organizations().insert();
OrganizationDto organization2 = db.organizations().insert();
ComponentDto projectInOrg1 = db.components().insertPublicProject(organization1);
ScannerReport.Metadata.Builder metadataBuilder = newBatchReportBuilder();
metadataBuilder
.setOrganizationKey(organization1.getKey())
.setProjectKey(projectInOrg1.getDbKey());
metadataBuilder.putQprofilesPerLanguage("js", ScannerReport.Metadata.QProfile.newBuilder().setKey("jsInOrg1").setName("Sonar way").setLanguage("js").build());
metadataBuilder.putQprofilesPerLanguage("php", ScannerReport.Metadata.QProfile.newBuilder().setKey("phpInOrg2").setName("PHP way").setLanguage("php").build());
reportReader.setMetadata(metadataBuilder.build());

db.qualityProfiles().insert(organization1, p -> p.setLanguage("js").setKee("jsInOrg1"));
db.qualityProfiles().insert(organization2, p -> p.setLanguage("php").setKee("phpInOrg2"));

ComputationStep underTest = createStep(createCeTask(projectInOrg1.getDbKey(), organization1.getUuid()));

expectedException.expect(MessageException.class);
expectedException.expectMessage("Quality profiles with following keys don't exist in organization [" + organization1.getKey() + "]: phpInOrg2");

underTest.execute(new TestComputationStepContext());
}

@Test
public void execute_does_not_fail_when_report_has_a_quality_profile_that_does_not_exist_anymore() {
OrganizationDto organization = db.organizations().insert();

+ 1
- 6
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/PersistAdHocRulesStepTest.java 查看文件

@@ -48,10 +48,6 @@ public class PersistAdHocRulesStepTest extends BaseStepTest {
@Rule
public DbTester db = DbTester.create(System2.INSTANCE);

@Rule
public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule()
.setOrganizationUuid("org-1", "qg-uuid-1");

private DbClient dbClient = db.getDbClient();

private ComputationStep underTest;
@@ -70,13 +66,12 @@ public class PersistAdHocRulesStepTest extends BaseStepTest {

@Before
public void setup() {
ruleRepository = new RuleRepositoryImpl(adHocRuleCreator, dbClient, analysisMetadataHolder);
ruleRepository = new RuleRepositoryImpl(adHocRuleCreator, dbClient);
underTest = new PersistAdHocRulesStep(dbClient, ruleRepository);
}

@Test
public void persist_and_index_new_ad_hoc_rules() {

RuleKey ruleKey = RuleKey.of("external_eslint", "no-cond-assign");
ruleRepository.addOrUpdateAddHocRuleIfNeeded(ruleKey,
() -> new NewAdHocRule(ScannerReport.ExternalIssue.newBuilder().setEngineId("eslint").setRuleId("no-cond-assign").build()));

+ 1
- 4
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/PersistIssuesStepTest.java 查看文件

@@ -81,9 +81,6 @@ public class PersistIssuesStepTest extends BaseStepTest {
public DbTester db = DbTester.create(System2.INSTANCE);
@Rule
public BatchReportReaderRule reportReader = new BatchReportReaderRule();
@Rule
public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule()
.setOrganizationUuid("org-1", "qg-uuid-1");

private System2 system2 = mock(System2.class);
private DbSession session = db.getSession();
@@ -104,7 +101,7 @@ public class PersistIssuesStepTest extends BaseStepTest {
protoIssueCache = new ProtoIssueCache(temp.newFile(), System2.INSTANCE);
reportReader.setMetadata(ScannerReport.Metadata.getDefaultInstance());

underTest = new PersistIssuesStep(dbClient, system2, conflictResolver, new RuleRepositoryImpl(adHocRuleCreator, dbClient, analysisMetadataHolder), protoIssueCache,
underTest = new PersistIssuesStep(dbClient, system2, conflictResolver, new RuleRepositoryImpl(adHocRuleCreator, dbClient), protoIssueCache,
new IssueStorage(), new SequenceUuidFactory());
}


+ 0
- 1
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ViewsPersistComponentsStepTest.java 查看文件

@@ -99,7 +99,6 @@ public class ViewsPersistComponentsStepTest extends BaseStepTest {
now = DATE_FORMAT.parse("2015-06-02");
when(system2.now()).thenReturn(now.getTime());

dbTester.organizations().insertForUuid(ORGANIZATION_UUID);
analysisMetadataHolder.setBranch(new DefaultBranchImpl());
BranchPersister branchPersister = mock(BranchPersister.class);
ProjectPersister projectPersister = mock(ProjectPersister.class);

+ 0
- 80
server/sonar-db-dao/src/main/java/org/sonar/db/es/RuleExtensionId.java 查看文件

@@ -1,80 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2020 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.db.es;

import com.google.common.base.CharMatcher;
import com.google.common.base.Splitter;
import java.util.List;

import static com.google.common.base.Preconditions.checkArgument;
import static java.lang.String.format;

public class RuleExtensionId {
private final String ruleUuid;
private final String organizationUuid;
private final String id;

private static final Splitter ID_SPLITTER = Splitter.on(CharMatcher.anyOf("|"));

public RuleExtensionId(String organizationUuid, String ruleUuid) {
this.organizationUuid = organizationUuid;
this.ruleUuid = ruleUuid;
this.id = format("%s|%s", ruleUuid, organizationUuid);
}

public RuleExtensionId(String ruleExtensionId) {
List<String> splittedId = ID_SPLITTER.splitToList(ruleExtensionId);
checkArgument(splittedId.size() == 2, "Incorrect Id %s", ruleExtensionId);
this.id = ruleExtensionId;
this.ruleUuid = splittedId.get(0);
this.organizationUuid = splittedId.get(1);
}

public String getRuleUuid() {
return this.ruleUuid;
}

public String getOrganizationUuid() {
return organizationUuid;
}

public String getId() {
return id;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof RuleExtensionId)) {
return false;
}

RuleExtensionId that = (RuleExtensionId) o;

return id.equals(that.id);
}

@Override
public int hashCode() {
return id.hashCode();
}
}

+ 0
- 14
server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ActiveRuleCountQuery.java 查看文件

@@ -24,13 +24,11 @@ import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.sonar.api.rule.RuleStatus;
import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.organization.OrganizationDto;

import static com.google.common.base.Preconditions.checkState;

public class ActiveRuleCountQuery {

private final OrganizationDto organization;
private final List<String> profileUuids;
private final RuleStatus ruleStatus;
private final String inheritance;
@@ -39,11 +37,6 @@ public class ActiveRuleCountQuery {
this.profileUuids = builder.profiles.stream().map(QProfileDto::getKee).collect(MoreCollectors.toList());
this.ruleStatus = builder.ruleStatus;
this.inheritance = builder.inheritance;
this.organization = builder.organization;
}

public OrganizationDto getOrganization() {
return organization;
}

public List<String> getProfileUuids() {
@@ -68,16 +61,10 @@ public class ActiveRuleCountQuery {
}

public static class Builder {
private OrganizationDto organization;
private List<QProfileDto> profiles;
private RuleStatus ruleStatus;
private String inheritance;

public Builder setOrganization(OrganizationDto organization) {
this.organization = organization;
return this;
}

public Builder setProfiles(List<QProfileDto> profiles) {
this.profiles = profiles;
return this;
@@ -94,7 +81,6 @@ public class ActiveRuleCountQuery {
}

public ActiveRuleCountQuery build() {
checkState(organization != null, "Organization cannot be null");
checkState(profiles != null, "Profiles cannot be null");
return new ActiveRuleCountQuery(this);
}

+ 9
- 10
server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ActiveRuleDao.java 查看文件

@@ -29,7 +29,6 @@ import org.sonar.core.util.UuidFactory;
import org.sonar.db.Dao;
import org.sonar.db.DatabaseUtils;
import org.sonar.db.DbSession;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.rule.RuleParamDto;

import static com.google.common.base.Preconditions.checkArgument;
@@ -58,16 +57,16 @@ public class ActiveRuleDao implements Dao {
return Optional.ofNullable(mapper(dbSession).selectByKey(key.getRuleProfileUuid(), key.getRuleKey().repository(), key.getRuleKey().rule()));
}

public List<OrgActiveRuleDto> selectByRuleUuid(DbSession dbSession, OrganizationDto organization, String ruleUuid) {
return mapper(dbSession).selectByRuleUuid(organization.getUuid(), ruleUuid);
public List<OrgActiveRuleDto> selectByOrgRuleUuid(DbSession dbSession, String ruleUuid) {
return mapper(dbSession).selectOrgByRuleUuid(ruleUuid);
}

public List<ActiveRuleDto> selectByRuleUuidOfAllOrganizations(DbSession dbSession, String ruleUuid) {
return mapper(dbSession).selectByRuleUuidOfAllOrganizations(ruleUuid);
public List<ActiveRuleDto> selectByRuleUuid(DbSession dbSession, String ruleUuid) {
return mapper(dbSession).selectByRuleUuid(ruleUuid);
}

public List<OrgActiveRuleDto> selectByRuleUuids(DbSession dbSession, OrganizationDto organization, List<String> uuids) {
return executeLargeInputs(uuids, chunk -> mapper(dbSession).selectByRuleUuids(organization.getUuid(), chunk));
public List<OrgActiveRuleDto> selectByRuleUuids(DbSession dbSession, List<String> uuids) {
return executeLargeInputs(uuids, chunk -> mapper(dbSession).selectByRuleUuids(chunk));
}

/**
@@ -176,8 +175,8 @@ public class ActiveRuleDao implements Dao {
mapper(dbSession).deleteParameter(uuid);
}

public void deleteParamsByRuleParamOfAllOrganizations(DbSession dbSession, RuleParamDto param) {
List<ActiveRuleDto> activeRules = selectByRuleUuidOfAllOrganizations(dbSession, param.getRuleUuid());
public void deleteParamsByRuleParam(DbSession dbSession, RuleParamDto param) {
List<ActiveRuleDto> activeRules = selectByRuleUuid(dbSession, param.getRuleUuid());
for (ActiveRuleDto activeRule : activeRules) {
for (ActiveRuleParamDto activeParam : selectParamsByActiveRuleUuid(dbSession, activeRule.getUuid())) {
if (activeParam.getKey().equals(param.getName())) {
@@ -194,7 +193,7 @@ public class ActiveRuleDao implements Dao {

public Map<String, Long> countActiveRulesByQuery(DbSession dbSession, ActiveRuleCountQuery query) {
return toMap(executeLargeInputs(query.getProfileUuids(),
partition -> mapper(dbSession).countActiveRulesByQuery(query.getOrganization().getUuid(), partition, query.getRuleStatus(), query.getInheritance())));
partition -> mapper(dbSession).countActiveRulesByQuery(partition, query.getRuleStatus(), query.getInheritance())));
}

public void scrollAllForIndexing(DbSession dbSession, Consumer<IndexedActiveRuleDto> consumer) {

+ 4
- 4
server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ActiveRuleMapper.java 查看文件

@@ -45,11 +45,11 @@ public interface ActiveRuleMapper {

List<ActiveRuleDto> selectByKeys(@Param("keys") List<ActiveRuleKey> keys);

List<OrgActiveRuleDto> selectByRuleUuid(@Param("organizationUuid") String organizationUuid, @Param("ruleUuid") String ruleUuid);
List<OrgActiveRuleDto> selectOrgByRuleUuid(@Param("ruleUuid") String ruleUuid);

List<ActiveRuleDto> selectByRuleUuidOfAllOrganizations(String ruleUuid);
List<ActiveRuleDto> selectByRuleUuid(String ruleUuid);

List<OrgActiveRuleDto> selectByRuleUuids(@Param("organizationUuid") String organizationUuid, @Param("ruleUuids") List<String> partitionOfRuleUuids);
List<OrgActiveRuleDto> selectByRuleUuids(@Param("ruleUuids") List<String> partitionOfRuleUuids);

List<OrgActiveRuleDto> selectByProfileUuid(String uuid);

@@ -77,7 +77,7 @@ public interface ActiveRuleMapper {

List<ActiveRuleParamDto> selectParamsByActiveRuleUuids(@Param("uuids") List<String> uuids);

List<KeyLongValue> countActiveRulesByQuery(@Param("organizationUuid") String organizationUuid, @Param("profileUuids") List<String> profileUuids,
List<KeyLongValue> countActiveRulesByQuery(@Param("profileUuids") List<String> profileUuids,
@Nullable @Param("ruleStatus") RuleStatus ruleStatus, @Param("inheritance") String inheritance);

void scrollAllForIndexing(ResultHandler<IndexedActiveRuleDto> handler);

+ 7
- 6
server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/DefaultQProfileDao.java 查看文件

@@ -21,6 +21,7 @@ package org.sonar.db.qualityprofile;

import java.util.Collection;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import org.sonar.api.utils.System2;
import org.sonar.db.Dao;
@@ -50,16 +51,16 @@ public class DefaultQProfileDao implements Dao {
DatabaseUtils.executeLargeUpdates(qProfileUuids, mapper::deleteByQProfileUuids);
}

public Set<String> selectExistingQProfileUuids(DbSession dbSession, String organizationUuid, Collection<String> qProfileUuids) {
return new HashSet<>(DatabaseUtils.executeLargeInputs(qProfileUuids, uuids -> mapper(dbSession).selectExistingQProfileUuids(organizationUuid, uuids)));
public Set<String> selectExistingQProfileUuids(DbSession dbSession, Collection<String> qProfileUuids) {
return new HashSet<>(DatabaseUtils.executeLargeInputs(qProfileUuids, uuids -> mapper(dbSession).selectExistingQProfileUuids(uuids)));
}

public boolean isDefault(DbSession dbSession, String organizationUuid, String qProfileUuid) {
return selectExistingQProfileUuids(dbSession, organizationUuid, singletonList(qProfileUuid)).contains(qProfileUuid);
public boolean isDefault(DbSession dbSession, String qProfileUuid) {
return selectExistingQProfileUuids(dbSession, singletonList(qProfileUuid)).contains(qProfileUuid);
}

public Set<String> selectUuidsOfOrganizationsWithoutDefaultProfile(DbSession dbSession, String language) {
return mapper(dbSession).selectUuidsOfOrganizationsWithoutDefaultProfile(language);
public Optional<String> selectDefaultQProfileUuid(DbSession dbSession, String language) {
return mapper(dbSession).selectDefaultQProfileUuid(language);
}

private static DefaultQProfileMapper mapper(DbSession dbSession) {

+ 0
- 13
server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/DefaultQProfileDto.java 查看文件

@@ -20,20 +20,9 @@
package org.sonar.db.qualityprofile;

public class DefaultQProfileDto {

private String organizationUuid;
private String language;
private String qProfileUuid;

public String getOrganizationUuid() {
return organizationUuid;
}

public DefaultQProfileDto setOrganizationUuid(String s) {
this.organizationUuid = s;
return this;
}

public String getLanguage() {
return language;
}
@@ -54,7 +43,6 @@ public class DefaultQProfileDto {

public static DefaultQProfileDto from(QProfileDto profile) {
return new DefaultQProfileDto()
.setOrganizationUuid(profile.getOrganizationUuid())
.setLanguage(profile.getLanguage())
.setQProfileUuid(profile.getKee());
}
@@ -62,7 +50,6 @@ public class DefaultQProfileDto {
@Override
public String toString() {
StringBuilder sb = new StringBuilder("DefaultQProfileDto{");
sb.append("organizationUuid='").append(organizationUuid).append('\'');
sb.append(", language='").append(language).append('\'');
sb.append(", qProfileUuid='").append(qProfileUuid).append('\'');
sb.append('}');

+ 3
- 5
server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/DefaultQProfileMapper.java 查看文件

@@ -21,7 +21,7 @@ package org.sonar.db.qualityprofile;

import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.Optional;
import org.apache.ibatis.annotations.Param;

public interface DefaultQProfileMapper {
@@ -31,9 +31,7 @@ public interface DefaultQProfileMapper {

void deleteByQProfileUuids(@Param("qProfileUuids") Collection<String> qProfileUuids);

List<String> selectExistingQProfileUuids(
@Param("organizationUuid") String organizationUuid,
@Param("qProfileUuids") Collection<String> qProfileUuids);
List<String> selectExistingQProfileUuids(@Param("qProfileUuids") Collection<String> qProfileUuids);

Set<String> selectUuidsOfOrganizationsWithoutDefaultProfile(@Param("language") String language);
Optional<String> selectDefaultQProfileUuid(@Param("language") String language);
}

+ 0
- 11
server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/OrgActiveRuleDto.java 查看文件

@@ -20,19 +20,8 @@
package org.sonar.db.qualityprofile;

public class OrgActiveRuleDto extends ActiveRuleDto {

private String organizationUuid;
private String orgProfileUuid;

public String getOrganizationUuid() {
return organizationUuid;
}

public OrgActiveRuleDto setOrganizationUuid(String s) {
this.organizationUuid = s;
return this;
}

public String getOrgProfileUuid() {
return orgProfileUuid;
}

+ 0
- 15
server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/OrgQProfileDto.java 查看文件

@@ -39,11 +39,6 @@ public class OrgQProfileDto {

private String uuid;

/**
* UUID of organization. Not null.
*/
private String organizationUuid;

/**
* UUID of referenced row in table "rules_profiles". Not null.
*/
@@ -53,15 +48,6 @@ public class OrgQProfileDto {
private Long lastUsed;
private Long userUpdatedAt;

public String getOrganizationUuid() {
return organizationUuid;
}

public OrgQProfileDto setOrganizationUuid(String organizationUuid) {
this.organizationUuid = organizationUuid;
return this;
}

public String getUuid() {
return uuid;
}
@@ -113,7 +99,6 @@ public class OrgQProfileDto {
public static OrgQProfileDto from(QProfileDto qProfileDto) {
return new OrgQProfileDto()
.setUuid(qProfileDto.getKee())
.setOrganizationUuid(qProfileDto.getOrganizationUuid())
.setRulesProfileUuid(qProfileDto.getRulesProfileUuid())
.setParentUuid(qProfileDto.getParentKee())
.setLastUsed(qProfileDto.getLastUsed())

+ 0
- 18
server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileDto.java 查看文件

@@ -23,19 +23,11 @@ import java.util.Date;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.sonar.core.util.UtcDateUtils;
import org.sonar.db.organization.OrganizationDto;

/**
* Represents the join of "org_qprofiles" and "rules_profiles"
*/
public class QProfileDto {

/**
* The organization, that this quality profile belongs to.
* Must not be null, but can be the default organization's uuid.
* Refers to {@link OrganizationDto#getUuid()}.
*/
private String organizationUuid;
private String kee;
private String name;
private String language;
@@ -46,15 +38,6 @@ public class QProfileDto {
private boolean isBuiltIn;
private String rulesProfileUuid;

public String getOrganizationUuid() {
return organizationUuid;
}

public QProfileDto setOrganizationUuid(String s) {
this.organizationUuid = s;
return this;
}

public String getKee() {
return kee;
}
@@ -149,7 +132,6 @@ public class QProfileDto {
.setIsBuiltIn(rules.isBuiltIn())
.setKee(org.getUuid())
.setParentKee(org.getParentUuid())
.setOrganizationUuid(org.getOrganizationUuid())
.setRulesProfileUuid(rules.getUuid())
.setLanguage(rules.getLanguage())
.setName(rules.getName())

+ 2
- 3
server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditGroupsDao.java 查看文件

@@ -27,7 +27,6 @@ import org.sonar.db.Dao;
import org.sonar.db.DatabaseUtils;
import org.sonar.db.DbSession;
import org.sonar.db.Pagination;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.user.GroupDto;

import static org.sonar.core.util.stream.MoreCollectors.toList;
@@ -59,9 +58,9 @@ public class QProfileEditGroupsDao implements Dao {
return mapper(dbSession).selectByQuery(query, pagination);
}

public List<String> selectQProfileUuidsByOrganizationAndGroups(DbSession dbSession, OrganizationDto organization, Collection<GroupDto> groups) {
public List<String> selectQProfileUuidsByGroups(DbSession dbSession, Collection<GroupDto> groups) {
return DatabaseUtils.executeLargeInputs(groups.stream().map(GroupDto::getUuid).collect(toList()),
g -> mapper(dbSession).selectQProfileUuidsByOrganizationAndGroups(organization.getUuid(), g));
g -> mapper(dbSession).selectQProfileUuidsByGroups(g));
}

public void insert(DbSession dbSession, QProfileEditGroupsDto dto) {

+ 1
- 1
server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditGroupsMapper.java 查看文件

@@ -32,7 +32,7 @@ public interface QProfileEditGroupsMapper {

List<GroupMembershipDto> selectByQuery(@Param("query") SearchGroupsQuery query, @Param("pagination") Pagination pagination);

List<String> selectQProfileUuidsByOrganizationAndGroups(@Param("organizationUuid") String organizationUuid, @Param("groupUuids") List<String> groupUuids);
List<String> selectQProfileUuidsByGroups(@Param("groupUuids") List<String> groupUuids);

void insert(@Param("dto") QProfileEditGroupsDto dto, @Param("now") long now);


+ 2
- 7
server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditUsersDao.java 查看文件

@@ -24,7 +24,6 @@ import org.sonar.api.utils.System2;
import org.sonar.db.Dao;
import org.sonar.db.DbSession;
import org.sonar.db.Pagination;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.user.UserDto;

import static org.sonar.core.util.stream.MoreCollectors.toList;
@@ -50,8 +49,8 @@ public class QProfileEditUsersDao implements Dao {
return mapper(dbSession).selectByQuery(query, pagination);
}

public List<String> selectQProfileUuidsByOrganizationAndUser(DbSession dbSession, OrganizationDto organization, UserDto userDto) {
return mapper(dbSession).selectQProfileUuidsByOrganizationAndUser(organization.getUuid(), userDto.getUuid());
public List<String> selectQProfileUuidsByUser(DbSession dbSession,UserDto userDto) {
return mapper(dbSession).selectQProfileUuidsByUser(userDto.getUuid());
}

public void insert(DbSession dbSession, QProfileEditUsersDto dto) {
@@ -70,10 +69,6 @@ public class QProfileEditUsersDao implements Dao {
mapper(dbSession).deleteByUser(user.getUuid());
}

public void deleteByOrganizationAndUser(DbSession dbSession, OrganizationDto organization, UserDto user) {
mapper(dbSession).deleteByOrganizationAndUser(organization.getUuid(), user.getUuid());
}

private static QProfileEditUsersMapper mapper(DbSession dbSession) {
return dbSession.getMapper(QProfileEditUsersMapper.class);
}

+ 1
- 3
server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditUsersMapper.java 查看文件

@@ -32,7 +32,7 @@ public interface QProfileEditUsersMapper {

List<UserMembershipDto> selectByQuery(@Param("query") SearchUsersQuery query, @Param("pagination") Pagination pagination);

List<String> selectQProfileUuidsByOrganizationAndUser(@Param("organizationUuid") String organizationUuid, @Param("userUuid") String userUuid);
List<String> selectQProfileUuidsByUser(@Param("userUuid") String userUuid);

void insert(@Param("dto") QProfileEditUsersDto dto, @Param("now") long now);

@@ -41,6 +41,4 @@ public interface QProfileEditUsersMapper {
void deleteByQProfiles(@Param("qProfileUuids") Collection<String> qProfileUuids);

void deleteByUser(@Param("userUuid") String userUuid);

void deleteByOrganizationAndUser(@Param("organizationUuid") String organizationUuid, @Param("userUuid") String userUuid);
}

+ 24
- 25
server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QualityProfileDao.java 查看文件

@@ -36,7 +36,6 @@ import org.sonar.db.DatabaseUtils;
import org.sonar.db.DbSession;
import org.sonar.db.KeyLongValue;
import org.sonar.db.RowNotFoundException;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.project.ProjectDto;

import static java.util.Collections.emptyList;
@@ -70,8 +69,8 @@ public class QualityProfileDao implements Dao {
return executeLargeInputs(uuids, mapper(dbSession)::selectByUuids);
}

public List<QProfileDto> selectOrderedByOrganizationUuid(DbSession dbSession, OrganizationDto organization) {
return mapper(dbSession).selectOrderedByOrganizationUuid(organization.getUuid());
public List<QProfileDto> selectAll(DbSession dbSession) {
return mapper(dbSession).selectAll();
}

public List<RulesProfileDto> selectBuiltInRuleProfiles(DbSession dbSession) {
@@ -142,8 +141,8 @@ public class QualityProfileDao implements Dao {
mapper.updateOrgQProfile(OrgQProfileDto.from(profile), now);
}

public List<QProfileDto> selectDefaultProfiles(DbSession dbSession, OrganizationDto organization, Collection<String> languages) {
return executeLargeInputs(languages, partition -> mapper(dbSession).selectDefaultProfiles(organization.getUuid(), partition));
public List<QProfileDto> selectDefaultProfiles(DbSession dbSession, Collection<String> languages) {
return executeLargeInputs(languages, partition -> mapper(dbSession).selectDefaultProfiles(partition));
}

public List<QProfileDto> selectDefaultBuiltInProfilesWithoutActiveRules(DbSession dbSession, Set<String> languages) {
@@ -151,21 +150,21 @@ public class QualityProfileDao implements Dao {
}

@CheckForNull
public QProfileDto selectDefaultProfile(DbSession dbSession, OrganizationDto organization, String language) {
return mapper(dbSession).selectDefaultProfile(organization.getUuid(), language);
public QProfileDto selectDefaultProfile(DbSession dbSession, String language) {
return mapper(dbSession).selectDefaultProfile(language);
}

@CheckForNull
public QProfileDto selectAssociatedToProjectAndLanguage(DbSession dbSession, ProjectDto project, String language) {
return mapper(dbSession).selectAssociatedToProjectUuidAndLanguage(project.getOrganizationUuid(), project.getUuid(), language);
return mapper(dbSession).selectAssociatedToProjectUuidAndLanguage(project.getUuid(), language);
}

public List<QProfileDto> selectAssociatedToProjectUuidAndLanguages(DbSession dbSession, ProjectDto project, Collection<String> languages) {
return executeLargeInputs(languages, partition -> mapper(dbSession).selectAssociatedToProjectUuidAndLanguages(project.getOrganizationUuid(), project.getUuid(), partition));
return executeLargeInputs(languages, partition -> mapper(dbSession).selectAssociatedToProjectUuidAndLanguages(project.getUuid(), partition));
}

public List<QProfileDto> selectByLanguage(DbSession dbSession, OrganizationDto organization, String language) {
return mapper(dbSession).selectByLanguage(organization.getUuid(), language);
public List<QProfileDto> selectByLanguage(DbSession dbSession, String language) {
return mapper(dbSession).selectByLanguage(language);
}

public List<QProfileDto> selectChildren(DbSession dbSession, Collection<QProfileDto> profiles) {
@@ -187,22 +186,22 @@ public class QualityProfileDao implements Dao {
}

@CheckForNull
public QProfileDto selectByNameAndLanguage(DbSession dbSession, OrganizationDto organization, String name, String language) {
return mapper(dbSession).selectByNameAndLanguage(organization.getUuid(), name, language);
public QProfileDto selectByNameAndLanguage(DbSession dbSession, String name, String language) {
return mapper(dbSession).selectByNameAndLanguage(name, language);
}

@CheckForNull
public QProfileDto selectByRuleProfileUuid(DbSession dbSession, String organizationUuid, String ruleProfileKee) {
return mapper(dbSession).selectByRuleProfileUuid(organizationUuid, ruleProfileKee);
public QProfileDto selectByRuleProfileUuid(DbSession dbSession, String ruleProfileKee) {
return mapper(dbSession).selectByRuleProfileUuid(ruleProfileKee);
}

public List<QProfileDto> selectByNameAndLanguages(DbSession dbSession, OrganizationDto organization, String name, Collection<String> languages) {
return mapper(dbSession).selectByNameAndLanguages(organization.getUuid(), name, languages);
public List<QProfileDto> selectByNameAndLanguages(DbSession dbSession, String name, Collection<String> languages) {
return mapper(dbSession).selectByNameAndLanguages(name, languages);
}

public Map<String, Long> countProjectsByOrganizationAndProfiles(DbSession dbSession, OrganizationDto organization, List<QProfileDto> profiles) {
public Map<String, Long> countProjectsByProfiles(DbSession dbSession, List<QProfileDto> profiles) {
List<String> profileUuids = profiles.stream().map(QProfileDto::getKee).collect(MoreCollectors.toList());
return KeyLongValue.toMap(executeLargeInputs(profileUuids, partition -> mapper(dbSession).countProjectsByOrganizationAndProfiles(organization.getUuid(), partition)));
return KeyLongValue.toMap(executeLargeInputs(profileUuids, partition -> mapper(dbSession).countProjectsByProfiles(partition)));
}

public void insertProjectProfileAssociation(DbSession dbSession, ProjectDto project, QProfileDto profile) {
@@ -222,19 +221,19 @@ public class QualityProfileDao implements Dao {
DatabaseUtils.executeLargeUpdates(profileUuids, mapper::deleteProjectAssociationByProfileUuids);
}

public List<ProjectQprofileAssociationDto> selectSelectedProjects(DbSession dbSession, OrganizationDto organization, QProfileDto profile, @Nullable String query) {
public List<ProjectQprofileAssociationDto> selectSelectedProjects(DbSession dbSession, QProfileDto profile, @Nullable String query) {
String nameQuery = sqlQueryString(query);
return mapper(dbSession).selectSelectedProjects(organization.getUuid(), profile.getKee(), nameQuery);
return mapper(dbSession).selectSelectedProjects(profile.getKee(), nameQuery);
}

public List<ProjectQprofileAssociationDto> selectDeselectedProjects(DbSession dbSession, OrganizationDto organization, QProfileDto profile, @Nullable String query) {
public List<ProjectQprofileAssociationDto> selectDeselectedProjects(DbSession dbSession, QProfileDto profile, @Nullable String query) {
String nameQuery = sqlQueryString(query);
return mapper(dbSession).selectDeselectedProjects(organization.getUuid(), profile.getKee(), nameQuery);
return mapper(dbSession).selectDeselectedProjects(profile.getKee(), nameQuery);
}

public List<ProjectQprofileAssociationDto> selectProjectAssociations(DbSession dbSession, OrganizationDto organization, QProfileDto profile, @Nullable String query) {
public List<ProjectQprofileAssociationDto> selectProjectAssociations(DbSession dbSession, QProfileDto profile, @Nullable String query) {
String nameQuery = sqlQueryString(query);
return mapper(dbSession).selectProjectAssociations(organization.getUuid(), profile.getKee(), nameQuery);
return mapper(dbSession).selectProjectAssociations(profile.getKee(), nameQuery);
}

public Collection<String> selectUuidsOfCustomRulesProfiles(DbSession dbSession, String language, String name) {

+ 6
- 20
server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QualityProfileMapper.java 查看文件

@@ -47,41 +47,32 @@ public interface QualityProfileMapper {
@CheckForNull
RulesProfileDto selectRuleProfile(@Param("uuid") String ruleProfileUuid);

List<QProfileDto> selectOrderedByOrganizationUuid(@Param("organizationUuid") String organizationUuid);
List<QProfileDto> selectAll();

@CheckForNull
QProfileDto selectDefaultProfile(@Param("organizationUuid") String organizationUuid, @Param("language") String language);
QProfileDto selectDefaultProfile(@Param("language") String language);

List<QProfileDto> selectDefaultBuiltInProfilesWithoutActiveRules(@Param("languages") List<String> languages);

List<QProfileDto> selectDefaultProfiles(
@Param("organizationUuid") String organizationUuid,
@Param("languages") Collection<String> languages);

@CheckForNull
QProfileDto selectByNameAndLanguage(
@Param("organizationUuid") String organizationUuid,
@Param("name") String name,
@Param("language") String language);

@CheckForNull
QProfileDto selectByRuleProfileUuid(
@Param("organizationUuid") String organizationUuid,
@Param("ruleProfileUuid") String ruleProfileKee);
QProfileDto selectByRuleProfileUuid(@Param("ruleProfileUuid") String ruleProfileKee);

List<QProfileDto> selectByNameAndLanguages(
@Param("organizationUuid") String organizationUuid,
@Param("name") String name,
@Param("languages") Collection<String> languages);
List<QProfileDto> selectByNameAndLanguages(@Param("name") String name, @Param("languages") Collection<String> languages);

@CheckForNull
QProfileDto selectByUuid(String uuid);

List<QProfileDto> selectByUuids(@Param("uuids") Collection<String> uuids);

List<QProfileDto> selectByLanguage(
@Param("organizationUuid") String organizationUuid,
@Param("language") String language);
List<QProfileDto> selectByLanguage(@Param("language") String language);

// INHERITANCE

@@ -89,16 +80,14 @@ public interface QualityProfileMapper {

// PROJECTS

List<KeyLongValue> countProjectsByOrganizationAndProfiles(@Param("organizationUuid") String organizationUuid, @Param("profileUuids") List<String> profiles);
List<KeyLongValue> countProjectsByProfiles(@Param("profileUuids") List<String> profiles);

@CheckForNull
QProfileDto selectAssociatedToProjectUuidAndLanguage(
@Param("organizationUuid") String organizationUuid,
@Param("projectUuid") String projectUuid,
@Param("language") String language);

List<QProfileDto> selectAssociatedToProjectUuidAndLanguages(
@Param("organizationUuid") String organizationUuid,
@Param("projectUuid") String projectUuid,
@Param("languages") Collection<String> languages);

@@ -117,17 +106,14 @@ public interface QualityProfileMapper {
void deleteProjectAssociationByProfileUuids(@Param("profileUuids") Collection<String> profileUuids);

List<ProjectQprofileAssociationDto> selectSelectedProjects(
@Param("organizationUuid") String organizationUuid,
@Param("profileUuid") String profileUuid,
@Param("nameQuery") String nameQuery);

List<ProjectQprofileAssociationDto> selectDeselectedProjects(
@Param("organizationUuid") String organizationUuid,
@Param("profileUuid") String profileUuid,
@Param("nameQuery") String nameQuery);

List<ProjectQprofileAssociationDto> selectProjectAssociations(
@Param("organizationUuid") String organizationUuid,
@Param("profileUuid") String profileUuid,
@Param("nameQuery") String nameQuery);


+ 0
- 13
server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/SearchGroupsQuery.java 查看文件

@@ -25,7 +25,6 @@ import java.util.Set;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
import org.sonar.db.organization.OrganizationDto;

import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Preconditions.checkArgument;
@@ -39,7 +38,6 @@ public class SearchGroupsQuery {
public static final String OUT = "OUT";
public static final Set<String> AVAILABLE_MEMBERSHIPS = ImmutableSet.of(ANY, IN, OUT);

private final String organizationUuid;
private final String qProfileUuid;
private final String query;
private final String membership;
@@ -48,17 +46,12 @@ public class SearchGroupsQuery {
final String querySqlLowercase;

private SearchGroupsQuery(Builder builder) {
this.organizationUuid = builder.organization.getUuid();
this.qProfileUuid = builder.profile.getKee();
this.query = builder.query;
this.membership = builder.membership;
this.querySqlLowercase = query == null ? null : buildLikeValue(query, BEFORE_AND_AFTER).toLowerCase(Locale.ENGLISH);
}

public String getOrganizationUuid() {
return organizationUuid;
}

public String getQProfileUuid() {
return qProfileUuid;
}
@@ -77,7 +70,6 @@ public class SearchGroupsQuery {
}

public static class Builder {
private OrganizationDto organization;
private QProfileDto profile;
private String query;
private String membership;
@@ -85,11 +77,6 @@ public class SearchGroupsQuery {
private Builder() {
}

public Builder setOrganization(OrganizationDto organization) {
this.organization = organization;
return this;
}

public Builder setProfile(QProfileDto profile) {
this.profile = profile;
return this;

+ 0
- 14
server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/SearchUsersQuery.java 查看文件

@@ -25,7 +25,6 @@ import java.util.Set;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
import org.sonar.db.organization.OrganizationDto;

import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Preconditions.checkArgument;
@@ -40,7 +39,6 @@ public class SearchUsersQuery {
public static final String OUT = "OUT";
public static final Set<String> AVAILABLE_MEMBERSHIPS = ImmutableSet.of(ANY, IN, OUT);

private final String organizationUuid;
private final String qProfileUuid;
private final String query;
private final String membership;
@@ -50,7 +48,6 @@ public class SearchUsersQuery {
final String querySqlLowercase;

private SearchUsersQuery(Builder builder) {
this.organizationUuid = builder.organization.getUuid();
this.qProfileUuid = builder.profile.getKee();
this.query = builder.query;
this.membership = builder.membership;
@@ -58,10 +55,6 @@ public class SearchUsersQuery {
this.querySqlLowercase = querySql == null ? null : querySql.toLowerCase(Locale.ENGLISH);
}

public String getOrganizationUuid() {
return organizationUuid;
}

public String getQProfileUuid() {
return qProfileUuid;
}
@@ -80,7 +73,6 @@ public class SearchUsersQuery {
}

public static class Builder {
private OrganizationDto organization;
private QProfileDto profile;
private String query;
private String membership;
@@ -88,11 +80,6 @@ public class SearchUsersQuery {
private Builder() {
}

public Builder setOrganization(OrganizationDto organization) {
this.organization = organization;
return this;
}

public Builder setProfile(QProfileDto profile) {
this.profile = profile;
return this;
@@ -115,7 +102,6 @@ public class SearchUsersQuery {
}

public SearchUsersQuery build() {
requireNonNull(organization, "Organization cannot be null");
requireNonNull(profile, "Quality profile cant be null.");
initMembership();
return new SearchUsersQuery(this);

+ 19
- 60
server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDao.java 查看文件

@@ -24,7 +24,6 @@ import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
import javax.annotation.Nullable;
import org.apache.ibatis.session.ResultHandler;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rules.RuleQuery;
@@ -32,8 +31,6 @@ import org.sonar.core.util.UuidFactory;
import org.sonar.db.Dao;
import org.sonar.db.DbSession;
import org.sonar.db.RowNotFoundException;
import org.sonar.db.es.RuleExtensionId;
import org.sonar.db.organization.OrganizationDto;

import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.Collections.emptyList;
@@ -50,31 +47,24 @@ public class RuleDao implements Dao {
this.uuidFactory = uuidFactory;
}

public Optional<RuleDto> selectByKey(DbSession session, String organizationUuid, RuleKey key) {
RuleDto res = mapper(session).selectByKey(organizationUuid, key);
ensureOrganizationIsSet(organizationUuid, res);
public Optional<RuleDto> selectByKey(DbSession session, RuleKey key) {
RuleDto res = mapper(session).selectByKey(key);
return ofNullable(res);
}

public RuleDto selectOrFailByKey(DbSession session, RuleKey key) {
RuleDefinitionDto ruleDefinitionDto = selectOrFailDefinitionByKey(session, key);
return new RuleDto(ruleDefinitionDto, new RuleMetadataDto());
}

public Optional<RuleDefinitionDto> selectDefinitionByKey(DbSession session, RuleKey key) {
return ofNullable(mapper(session).selectDefinitionByKey(key));
}

public Optional<RuleMetadataDto> selectMetadataByKey(DbSession session, RuleKey key, String organizationUuid) {
return ofNullable(mapper(session).selectMetadataByKey(key, organizationUuid));
public Optional<RuleMetadataDto> selectMetadataByKey(DbSession session, RuleKey key) {
return ofNullable(mapper(session).selectMetadataByKey(key));
}

public RuleDto selectOrFailByKey(DbSession session, OrganizationDto organization, RuleKey key) {
RuleDto rule = mapper(session).selectByKey(organization.getUuid(), key);
public RuleDto selectOrFailByKey(DbSession session, RuleKey key) {
RuleDto rule = mapper(session).selectByKey(key);
if (rule == null) {
throw new RowNotFoundException(String.format("Rule with key '%s' does not exist", key));
}
ensureOrganizationIsSet(organization.getUuid(), rule);
return rule;
}

@@ -86,9 +76,8 @@ public class RuleDao implements Dao {
return rule;
}

public Optional<RuleDto> selectByUuid(String uuid, String organizationUuid, DbSession session) {
RuleDto res = mapper(session).selectByUuid(organizationUuid, uuid);
ensureOrganizationIsSet(organizationUuid, res);
public Optional<RuleDto> selectByUuid(String uuid, DbSession session) {
RuleDto res = mapper(session).selectByUuid(uuid);
return ofNullable(res);
}

@@ -96,13 +85,11 @@ public class RuleDao implements Dao {
return ofNullable(mapper(session).selectDefinitionByUuid(uuid));
}

public List<RuleDto> selectByUuids(DbSession session, String organizationUuid, List<String> uuids) {
public List<RuleDto> selectByUuids(DbSession session, List<String> uuids) {
if (uuids.isEmpty()) {
return emptyList();
}
return ensureOrganizationIsSet(
organizationUuid,
executeLargeInputs(uuids, chunk -> mapper(session).selectByUuids(organizationUuid, chunk)));
return executeLargeInputs(uuids, chunk -> mapper(session).selectByUuids(chunk));
}

public List<RuleDefinitionDto> selectDefinitionByUuids(DbSession session, Collection<String> uuids) {
@@ -112,20 +99,11 @@ public class RuleDao implements Dao {
return executeLargeInputs(uuids, mapper(session)::selectDefinitionByUuids);
}

public List<RuleDto> selectByKeys(DbSession session, OrganizationDto organization, Collection<RuleKey> keys) {
if (keys.isEmpty()) {
return emptyList();
}
return ensureOrganizationIsSet(organization.getUuid(),
executeLargeInputs(keys, chunk -> mapper(session).selectByKeys(organization.getUuid(), chunk)));
}

public List<RuleDto> selectByKeys(DbSession session, String organizationUuid, Collection<RuleKey> keys) {
public List<RuleDto> selectByKeys(DbSession session, Collection<RuleKey> keys) {
if (keys.isEmpty()) {
return emptyList();
}
return ensureOrganizationIsSet(organizationUuid,
executeLargeInputs(keys, chunk -> mapper(session).selectByKeys(organizationUuid, chunk)));
return executeLargeInputs(keys, chunk -> mapper(session).selectByKeys(chunk));
}

public List<RuleDefinitionDto> selectDefinitionByKeys(DbSession session, Collection<RuleKey> keys) {
@@ -139,32 +117,20 @@ public class RuleDao implements Dao {
mapper(session).selectEnabled(resultHandler);
}

public List<RuleDto> selectAll(DbSession session, String organizationUuid) {
return ensureOrganizationIsSet(organizationUuid, mapper(session).selectAll(organizationUuid));
public List<RuleDto> selectAll(DbSession session) {
return mapper(session).selectAll();
}

public List<RuleDefinitionDto> selectAllDefinitions(DbSession session) {
return mapper(session).selectAllDefinitions();
}

public List<RuleDto> selectByTypeAndLanguages(DbSession session, String organizationUuid, List<Integer> types, List<String> languages) {
return ensureOrganizationIsSet(organizationUuid,
executeLargeInputs(languages, chunk -> mapper(session).selectByTypeAndLanguages(organizationUuid, types, chunk)));
public List<RuleDto> selectByTypeAndLanguages(DbSession session, List<Integer> types, List<String> languages) {
return executeLargeInputs(languages, chunk -> mapper(session).selectByTypeAndLanguages(types, chunk));
}

public List<RuleDto> selectByQuery(DbSession session, String organizationUuid, RuleQuery ruleQuery) {
return ensureOrganizationIsSet(organizationUuid, mapper(session).selectByQuery(organizationUuid, ruleQuery));
}

private static void ensureOrganizationIsSet(String organizationUuid, @Nullable RuleDto res) {
if (res != null) {
res.setOrganizationUuid(organizationUuid);
}
}

private static List<RuleDto> ensureOrganizationIsSet(String organizationUuid, List<RuleDto> res) {
res.forEach(dto -> ensureOrganizationIsSet(organizationUuid, dto));
return res;
public List<RuleDto> selectByQuery(DbSession session, RuleQuery ruleQuery) {
return mapper(session).selectByQuery(ruleQuery);
}

public void insert(DbSession session, RuleDefinitionDto dto) {
@@ -189,7 +155,7 @@ public class RuleDao implements Dao {
}
}

public void scrollIndexingRuleExtensionsByIds(DbSession dbSession, Collection<RuleExtensionId> ruleExtensionIds, Consumer<RuleExtensionForIndexingDto> consumer) {
public void scrollIndexingRuleExtensionsByIds(DbSession dbSession, Collection<String> ruleExtensionIds, Consumer<RuleExtensionForIndexingDto> consumer) {
RuleMapper mapper = mapper(dbSession);

executeLargeInputsWithoutOutput(ruleExtensionIds,
@@ -198,13 +164,6 @@ public class RuleDao implements Dao {
.forEach(consumer));
}

public void scrollIndexingRuleExtensions(DbSession dbSession, Consumer<RuleExtensionForIndexingDto> consumer) {
mapper(dbSession).scrollIndexingRuleExtensions(context -> {
RuleExtensionForIndexingDto dto = context.getResultObject();
consumer.accept(dto);
});
}

public void scrollIndexingRulesByKeys(DbSession dbSession, Collection<String> ruleUuids, Consumer<RuleForIndexingDto> consumer) {
RuleMapper mapper = mapper(dbSession);


+ 3
- 3
server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDefinitionDto.java 查看文件

@@ -104,12 +104,12 @@ public class RuleDefinitionDto {
return deserializeStringSet(securityStandards);
}

private static Set<String> deserializeStringSet(@Nullable String securityStandards) {
if (securityStandards == null || securityStandards.isEmpty()) {
private static Set<String> deserializeStringSet(@Nullable String str) {
if (str == null || str.isEmpty()) {
return ImmutableSet.of();
}

return ImmutableSet.copyOf(SPLITTER.split(securityStandards));
return ImmutableSet.copyOf(SPLITTER.split(str));
}

private static String serializeStringSet(@Nullable Set<String> strings) {

+ 0
- 9
server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java 查看文件

@@ -408,15 +408,6 @@ public class RuleDto {
}
}

public String getOrganizationUuid() {
return metadata.getOrganizationUuid();
}

public RuleDto setOrganizationUuid(String organizationUuid) {
metadata.setOrganizationUuid(organizationUuid);
return this;
}

@CheckForNull
public String getNoteData() {
return metadata.getNoteData();

+ 0
- 10
server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleExtensionForIndexingDto.java 查看文件

@@ -31,7 +31,6 @@ public class RuleExtensionForIndexingDto {
private String ruleUuid;
private String pluginName;
private String pluginRuleKey;
private String organizationUuid;
private String tags;

public String getPluginName() {
@@ -60,15 +59,6 @@ public class RuleExtensionForIndexingDto {
this.ruleUuid = ruleUuid;
}

public String getOrganizationUuid() {
return organizationUuid;
}

public RuleExtensionForIndexingDto setOrganizationUuid(String organizationUuid) {
this.organizationUuid = organizationUuid;
return this;
}

public String getTags() {
return tags;
}

+ 5
- 0
server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleForIndexingDto.java 查看文件

@@ -37,6 +37,7 @@ public class RuleForIndexingDto {
private RuleStatus status;
private boolean isTemplate;
private String systemTags;
private String tags;
private String securityStandards;
private String templateRuleKey;
private String templateRepository;
@@ -91,6 +92,10 @@ public class RuleForIndexingDto {
return RuleDefinitionDto.deserializeTagsString(systemTags);
}

public Set<String> getTags() {
return RuleDefinitionDto.deserializeTagsString(tags);
}

public Set<String> getSecurityStandards() {
return RuleDefinitionDto.deserializeSecurityStandardsString(securityStandards);
}

+ 9
- 12
server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleMapper.java 查看文件

@@ -25,31 +25,30 @@ import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.session.ResultHandler;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rules.RuleQuery;
import org.sonar.db.es.RuleExtensionId;

public interface RuleMapper {

List<RuleDto> selectAll(@Param("organizationUuid") String organizationUuid);
List<RuleDto> selectAll();

List<RuleDefinitionDto> selectAllDefinitions();

void selectEnabled(ResultHandler<RuleDefinitionDto> resultHandler);

RuleDto selectByUuid(@Param("organizationUuid") String organizationUuid, @Param("uuid") String uuid);
RuleDto selectByUuid(@Param("uuid") String uuid);

RuleDefinitionDto selectDefinitionByUuid(String uuid);

List<RuleDto> selectByUuids(@Param("organizationUuid") String organizationUuid, @Param("uuids") List<String> uuids);
List<RuleDto> selectByUuids(@Param("uuids") List<String> uuids);

List<RuleDefinitionDto> selectDefinitionByUuids(@Param("uuids") List<String> uuids);

RuleDto selectByKey(@Param("organizationUuid") String organizationUuid, @Param("ruleKey") RuleKey ruleKey);
RuleDto selectByKey(@Param("ruleKey") RuleKey ruleKey);

RuleDefinitionDto selectDefinitionByKey(RuleKey ruleKey);

RuleMetadataDto selectMetadataByKey(@Param("ruleKey") RuleKey ruleKey, @Param("organizationUuid") String organizationUuid);
RuleMetadataDto selectMetadataByKey(@Param("ruleKey") RuleKey ruleKey);

List<RuleDto> selectByKeys(@Param("organizationUuid") String organizationUuid, @Param("ruleKeys") List<RuleKey> keys);
List<RuleDto> selectByKeys(@Param("ruleKeys") List<RuleKey> keys);

List<RuleDefinitionDto> selectDefinitionByKeys(@Param("ruleKeys") List<RuleKey> keys);

@@ -57,13 +56,11 @@ public interface RuleMapper {

List<RuleForIndexingDto> selectIndexingRulesByUuids(@Param("ruleUuids") List<String> ruleUuids);

void scrollIndexingRuleExtensions(ResultHandler<RuleExtensionForIndexingDto> handler);
List<RuleExtensionForIndexingDto> selectIndexingRuleExtensionsByIds(@Param("ruleExtensionIds") List<String> ruleExtensionIds);

List<RuleExtensionForIndexingDto> selectIndexingRuleExtensionsByIds(@Param("ruleExtensionIds") List<RuleExtensionId> ruleExtensionIds);
List<RuleDto> selectByQuery(@Param("query") RuleQuery ruleQuery);

List<RuleDto> selectByQuery(@Param("organizationUuid") String organizationUuid, @Param("query") RuleQuery ruleQuery);

List<RuleDto> selectByTypeAndLanguages(@Param("organizationUuid") String organizationUuid, @Param("types") List<Integer> types, @Param("languages") List<String> languages);
List<RuleDto> selectByTypeAndLanguages(@Param("types") List<Integer> types, @Param("languages") List<String> languages);

void insertDefinition(RuleDefinitionDto ruleDefinitionDto);


+ 0
- 11
server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleMetadataDto.java 查看文件

@@ -32,7 +32,6 @@ import static com.google.common.base.Preconditions.checkArgument;

public class RuleMetadataDto {
private String ruleUuid;
private String organizationUuid;
private String noteData;
private String noteUserUuid;
private Long noteCreatedAt;
@@ -81,15 +80,6 @@ public class RuleMetadataDto {
return this;
}

public String getOrganizationUuid() {
return organizationUuid;
}

public RuleMetadataDto setOrganizationUuid(String organizationUuid) {
this.organizationUuid = organizationUuid;
return this;
}

@CheckForNull
public String getNoteData() {
return noteData;
@@ -250,7 +240,6 @@ public class RuleMetadataDto {
public String toString() {
return "RuleMetadataDto{" +
"ruleUuid=" + ruleUuid +
", organizationUuid='" + organizationUuid + '\'' +
", noteData='" + noteData + '\'' +
", noteUserUuid='" + noteUserUuid + '\'' +
", noteCreatedAt=" + noteCreatedAt +

+ 3
- 7
server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/ActiveRuleMapper.xml 查看文件

@@ -28,7 +28,6 @@
rp.uuid as "ruleProfileUuid",
a.created_at as "createdAt",
a.updated_at as "updatedAt",
oqp.organization_uuid as "organizationUuid",
oqp.uuid as "orgProfileUuid"
</sql>

@@ -157,7 +156,7 @@
and rp.uuid in <foreach collection="ruleProfileUuids" item="ruleProfileUuid" separator="," open="(" close=")">#{ruleProfileUuid, jdbcType=VARCHAR}</foreach>
</select>

<select id="selectByRuleUuid" parameterType="map" resultType="org.sonar.db.qualityprofile.OrgActiveRuleDto">
<select id="selectOrgByRuleUuid" parameterType="map" resultType="org.sonar.db.qualityprofile.OrgActiveRuleDto">
select
<include refid="orgActiveRuleColumns"/>
from active_rules a
@@ -166,10 +165,9 @@
inner join rules r on r.uuid = a.rule_uuid
where
a.rule_uuid = #{ruleUuid, jdbcType=VARCHAR}
and oqp.organization_uuid = #{organizationUuid, jdbcType=VARCHAR}
</select>

<select id="selectByRuleUuidOfAllOrganizations" parameterType="String" resultType="ActiveRule">
<select id="selectByRuleUuid" parameterType="String" resultType="ActiveRule">
select
<include refid="activeRuleColumns"/>
from active_rules a
@@ -190,7 +188,6 @@
<foreach collection="ruleUuids" item="ruleUuid" separator="," open="(" close=")">
#{ruleUuid, jdbcType=VARCHAR}
</foreach>
and oqp.organization_uuid = #{organizationUuid, jdbcType=VARCHAR}
</select>

<!-- Parameters -->
@@ -280,8 +277,7 @@
inner join org_qprofiles oqp on oqp.rules_profile_uuid = rp.uuid
inner join rules r on r.uuid = ar.rule_uuid
<where>
oqp.organization_uuid = #{organizationUuid, jdbcType=VARCHAR}
and <foreach collection="profileUuids" item="profileUuid" open="(" separator=" or " close=")">
<foreach collection="profileUuids" item="profileUuid" open="(" separator=" or " close=")">
oqp.uuid = #{profileUuid, jdbcType=VARCHAR}
</foreach>
<choose>

+ 4
- 10
server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/DefaultQProfileMapper.xml 查看文件

@@ -6,13 +6,11 @@
<insert id="insert" useGeneratedKeys="false" parameterType="map">
insert into default_qprofiles
(
organization_uuid,
language,
qprofile_uuid,
created_at,
updated_at
) values (
#{dto.organizationUuid, jdbcType=VARCHAR},
#{dto.language, jdbcType=VARCHAR},
#{dto.qProfileUuid, jdbcType=VARCHAR},
#{now, jdbcType=BIGINT},
@@ -26,8 +24,7 @@
qprofile_uuid = #{dto.qProfileUuid, jdbcType=VARCHAR},
updated_at = #{now, jdbcType=BIGINT}
where
organization_uuid = #{dto.organizationUuid, jdbcType=VARCHAR}
and language = #{dto.language, jdbcType=VARCHAR}
language = #{dto.language, jdbcType=VARCHAR}
</update>

<delete id="deleteByQProfileUuids" parameterType="String">
@@ -42,17 +39,14 @@
select qprofile_uuid
from default_qprofiles
where
organization_uuid = #{organizationUuid, jdbcType=VARCHAR}
and qprofile_uuid in
qprofile_uuid in
<foreach collection="qProfileUuids" open="(" close=")" item="qProfileUuid" separator=",">
#{qProfileUuid, jdbcType=VARCHAR}
</foreach>
</select>

<select id="selectUuidsOfOrganizationsWithoutDefaultProfile" parameterType="String" resultType="String">
select uuid from organizations
where not exists
(select 1 from default_qprofiles dqp where dqp.organization_uuid = uuid and dqp.language = #{language, jdbcType=VARCHAR})
<select id="selectDefaultQProfileUuid" parameterType="String" resultType="String">
select qprofile_uuid from default_qprofiles where language = #{language, jdbcType=VARCHAR}
</select>
</mapper>


+ 1
- 3
server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/QProfileEditGroupsMapper.xml 查看文件

@@ -60,7 +60,6 @@
FROM groups g
LEFT JOIN qprofile_edit_groups qeg ON qeg.group_uuid=g.uuid AND qeg.qprofile_uuid=#{query.qProfileUuid, jdbcType=VARCHAR}
<where>
AND g.organization_uuid=#{query.organizationUuid,jdbcType=VARCHAR}
<choose>
<when test="query.getMembership() == 'IN'">
AND qeg.uuid IS NOT NULL
@@ -75,10 +74,9 @@
</where>
</sql>

<select id="selectQProfileUuidsByOrganizationAndGroups" parameterType="map" resultType="string">
<select id="selectQProfileUuidsByGroups" parameterType="map" resultType="string">
select distinct qeg.qprofile_uuid as qProfileUuid
from qprofile_edit_groups qeg
inner join org_qprofiles oq on qeg.qprofile_uuid=oq.uuid and oq.organization_uuid=#{organizationUuid, jdbcType=VARCHAR}
<where>
qeg.group_uuid in <foreach collection="groupUuids" open="(" close=")" item="groupUuid" separator=",">#{groupUuid, jdbcType=VARCHAR}</foreach>
</where>

+ 1
- 15
server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/QProfileEditUsersMapper.xml 查看文件

@@ -57,7 +57,6 @@
<sql id="sqlSelectByQuery">
FROM users u
LEFT JOIN qprofile_edit_users qeu ON qeu.user_uuid=u.uuid AND qeu.qprofile_uuid=#{query.qProfileUuid, jdbcType=VARCHAR}
INNER JOIN organization_members om ON u.uuid=om.user_uuid AND om.organization_uuid=#{query.organizationUuid, jdbcType=VARCHAR}
<where>
<choose>
<when test="query.getMembership() == 'IN'">
@@ -76,10 +75,9 @@
</where>
</sql>

<select id="selectQProfileUuidsByOrganizationAndUser" parameterType="map" resultType="string">
<select id="selectQProfileUuidsByUser" parameterType="map" resultType="string">
SELECT qeu.qprofile_uuid as qProfileUuid
FROM qprofile_edit_users qeu
INNER JOIN org_qprofiles oq ON qeu.qprofile_uuid=oq.uuid AND oq.organization_uuid=#{organizationUuid, jdbcType=VARCHAR}
<where>
qeu.user_uuid=#{userUuid, jdbcType=VARCHAR}
</where>
@@ -115,17 +113,5 @@
where user_uuid = #{userUuid, jdbcType=VARCHAR}
</delete>

<delete id="deleteByOrganizationAndUser" parameterType="map">
delete from qprofile_edit_users
<where>
user_uuid=#{userUuid, jdbcType=VARCHAR}
and qprofile_uuid in (
select oq.uuid
from org_qprofiles oq
where oq.organization_uuid=#{organizationUuid, jdbcType=VARCHAR}
)
</where>
</delete>

</mapper>


+ 2
- 23
server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/QualityProfileMapper.xml 查看文件

@@ -5,7 +5,6 @@

<sql id="qProfileColumns">
oqp.uuid as kee,
oqp.organization_uuid as organizationUuid,
oqp.parent_uuid as parentKee,
oqp.last_used as lastUsed,
oqp.user_updated_at as userUpdatedAt,
@@ -47,7 +46,6 @@
<insert id="insertOrgQProfile" parameterType="map" useGeneratedKeys="false">
insert into org_qprofiles (
uuid,
organization_uuid,
rules_profile_uuid,
parent_uuid,
last_used,
@@ -56,7 +54,6 @@
updated_at
) values (
#{dto.uuid, jdbcType=VARCHAR},
#{dto.organizationUuid, jdbcType=VARCHAR},
#{dto.rulesProfileUuid, jdbcType=VARCHAR},
#{dto.parentUuid, jdbcType=VARCHAR},
#{dto.lastUsed, jdbcType=BIGINT},
@@ -123,13 +120,11 @@
where rp.uuid = #{uuid, jdbcType=VARCHAR}
</select>

<select id="selectOrderedByOrganizationUuid" parameterType="map" resultType="org.sonar.db.qualityprofile.QProfileDto">
<select id="selectAll" resultType="org.sonar.db.qualityprofile.QProfileDto">
select
<include refid="qProfileColumns"/>
from org_qprofiles oqp
inner join rules_profiles rp on oqp.rules_profile_uuid = rp.uuid
where
oqp.organization_uuid = #{organizationUuid,jdbcType=VARCHAR}
order by rp.name, rp.language
</select>

@@ -141,9 +136,7 @@
inner join default_qprofiles dp on dp.qprofile_uuid = oqp.uuid
where
dp.language = #{language, jdbcType=VARCHAR}
and dp.organization_uuid = #{organizationUuid, jdbcType=VARCHAR}
and rp.language = dp.language
and oqp.organization_uuid = dp.organization_uuid
</select>

<select id="selectDefaultBuiltInProfilesWithoutActiveRules" parameterType="map" resultType="org.sonar.db.qualityprofile.QProfileDto">
@@ -170,9 +163,7 @@
inner join default_qprofiles dp on dp.qprofile_uuid = oqp.uuid
where
dp.language in <foreach collection="languages" open="(" close=")" item="language" separator=",">#{language, jdbcType=VARCHAR}</foreach>
and dp.organization_uuid = oqp.organization_uuid
and rp.language = dp.language
and oqp.organization_uuid = #{organizationUuid, jdbcType=VARCHAR}
</select>

<select id="selectBuiltInRuleProfilesWithActiveRules" resultType="org.sonar.db.qualityprofile.RulesProfileDto">
@@ -194,7 +185,6 @@
where
rp.name = #{name, jdbcType=VARCHAR}
and rp.language = #{language, jdbcType=VARCHAR}
and oqp.organization_uuid = #{organizationUuid, jdbcType=VARCHAR}
</select>

<select id="selectByRuleProfileUuid" parameterType="map" resultType="org.sonar.db.qualityprofile.QProfileDto">
@@ -204,7 +194,6 @@
inner join rules_profiles rp on oqp.rules_profile_uuid = rp.uuid
where
rp.uuid = #{ruleProfileUuid, jdbcType=VARCHAR}
and oqp.organization_uuid = #{organizationUuid, jdbcType=VARCHAR}
</select>

<select id="selectByNameAndLanguages" parameterType="map" resultType="org.sonar.db.qualityprofile.QProfileDto">
@@ -215,7 +204,6 @@
where
rp.name = #{name, jdbcType=VARCHAR}
and rp.language in <foreach collection="languages" open="(" close=")" item="language" separator=",">#{language, jdbcType=VARCHAR}</foreach>
and oqp.organization_uuid = #{organizationUuid, jdbcType=VARCHAR}
</select>

<select id="selectByUuid" parameterType="string" resultType="org.sonar.db.qualityprofile.QProfileDto">
@@ -243,7 +231,6 @@
inner join rules_profiles rp on oqp.rules_profile_uuid = rp.uuid
where
rp.language = #{language, jdbcType=VARCHAR}
and oqp.organization_uuid = #{organizationUuid, jdbcType=VARCHAR}
</select>

<!-- the join on "org_qprofiles parent" is required to benefit from the index on uuid -->
@@ -257,15 +244,13 @@
order by rp.name
</select>

<select id="countProjectsByOrganizationAndProfiles" resultType="KeyLongValue" parameterType="map">
<select id="countProjectsByProfiles" resultType="KeyLongValue" parameterType="map">
select pqp.profile_key as "key", count(pj.uuid) as "value"
from components pj
inner join project_qprofiles pqp on pqp.project_uuid = pj.uuid
inner join org_qprofiles oqp on oqp.uuid = pqp.profile_key
where
pj.enabled = ${_true}
and pj.organization_uuid = #{organizationUuid, jdbcType=VARCHAR}
and oqp.organization_uuid = pj.organization_uuid
and <foreach collection="profileUuids" item="profileUuid" open="(" separator=" or " close=")">
oqp.uuid = #{profileUuid, jdbcType=VARCHAR}
</foreach>
@@ -281,7 +266,6 @@
where
rp.language = #{language, jdbcType=VARCHAR}
and pqp.project_uuid = #{projectUuid, jdbcType=VARCHAR}
and oqp.organization_uuid = #{organizationUuid, jdbcType=VARCHAR}
</select>

<select id="selectAssociatedToProjectUuidAndLanguages" parameterType="map" resultType="org.sonar.db.qualityprofile.QProfileDto">
@@ -293,7 +277,6 @@
where
rp.language in <foreach collection="languages" open="(" close=")" item="language" separator=",">#{language, jdbcType=VARCHAR}</foreach>
and pqp.project_uuid = #{projectUuid, jdbcType=VARCHAR}
and oqp.organization_uuid = #{organizationUuid, jdbcType=VARCHAR}
</select>

<insert id="insertProjectProfileAssociation" useGeneratedKeys="false">
@@ -345,7 +328,6 @@
and pj.qualifier = 'TRK'
and pj.main_branch_project_uuid is null
and upper(pj.name) like #{nameQuery, jdbcType=VARCHAR}
and pj.organization_uuid = #{organizationUuid, jdbcType=VARCHAR}
order by pj.name ASC
</select>

@@ -357,7 +339,6 @@
WHERE pj.scope='PRJ' AND pj.qualifier='TRK' AND pj.main_branch_project_uuid is null
AND UPPER(pj.name) LIKE #{nameQuery, jdbcType=VARCHAR}
AND pp.profile_key IS NULL
AND pj.organization_uuid = #{organizationUuid, jdbcType=VARCHAR}
ORDER BY pj.name ASC
</select>

@@ -368,14 +349,12 @@
AND pp.profile_key = #{profileUuid, jdbcType=VARCHAR}
WHERE pj.scope='PRJ' AND pj.qualifier='TRK' AND pj.main_branch_project_uuid is null
AND UPPER(pj.name) LIKE #{nameQuery, jdbcType=VARCHAR}
AND pj.organization_uuid = #{organizationUuid, jdbcType=VARCHAR}
ORDER BY pj.name ASC
</select>

<select id="selectUuidsOfCustomRuleProfiles" parameterType="map" resultType="string">
select oqp.rules_profile_uuid
from org_qprofiles oqp
inner join organizations o on o.uuid = oqp.organization_uuid
inner join rules_profiles rp on rp.uuid = oqp.rules_profile_uuid
where
rp.language = #{language, jdbcType=VARCHAR}

+ 4
- 16
server/sonar-db-dao/src/main/resources/org/sonar/db/rule/RuleMapper.xml 查看文件

@@ -58,7 +58,6 @@
<sql id="outerJoinRulesMetadata">
left outer join rules_metadata rm on
rm.rule_uuid = r.uuid
and rm.organization_uuid = #{organizationUuid,jdbcType=VARCHAR}
</sql>

<select id="selectAll" resultType="Rule">
@@ -152,21 +151,15 @@
<include refid="sqlSelectIndexingRuleExtensions" />
and
<foreach collection="ruleExtensionIds" index="index" item="ruleExtId" open="" separator=" or " close="">
( r.uuid = #{ruleExtId.ruleUuid, jdbcType=VARCHAR} and
rm.organization_uuid = #{ruleExtId.organizationUuid, jdbcType=VARCHAR} )
( r.uuid = #{ruleExtId, jdbcType=VARCHAR} )
</foreach>
</select>

<select id="scrollIndexingRuleExtensions" resultType="org.sonar.db.rule.RuleExtensionForIndexingDto" fetchSize="${_scrollFetchSize}" resultSetType="FORWARD_ONLY">
<include refid="sqlSelectIndexingRuleExtensions" />
</select>

<sql id="sqlSelectIndexingRuleExtensions">
select
r.uuid as "ruleUuid",
r.plugin_name as "pluginName",
r.plugin_rule_key as "pluginRuleKey",
rm.organization_uuid as "organizationUuid",
rm.tags as "tags"
from rules r
inner join rules_metadata rm on rm.rule_uuid = r.uuid
@@ -180,7 +173,6 @@
r.uuid as "ruleUuid",
r.plugin_name as "pluginName",
r.plugin_rule_key as "pluginRuleKey",
rm.organization_uuid as "organizationUuid",
rm.tags as "tags"
from rules r
inner join rules_metadata rm on rm.rule_uuid = r.uuid
@@ -191,7 +183,6 @@
<select id="selectMetadataByKey" parameterType="map" resultType="org.sonar.db.rule.RuleMetadataDto">
select
rm.rule_uuid as "ruleUuid",
rm.organization_uuid as "organizationUuid",
rm.note_data as "noteData",
rm.note_user_uuid as "noteUserUuid",
rm.note_created_at as "noteCreatedAt",
@@ -212,7 +203,6 @@
where
r.plugin_name=#{ruleKey.repository,jdbcType=VARCHAR}
and r.plugin_rule_key=#{ruleKey.rule,jdbcType=VARCHAR}
and rm.organization_uuid = #{organizationUuid,jdbcType=VARCHAR}
</select>

<select id="selectByKeys" parameterType="map" resultType="Rule">
@@ -272,9 +262,11 @@
r.language as "language",
r.rule_type as "type",
r.created_at as "createdAt",
r.updated_at as "updatedAt"
r.updated_at as "updatedAt",
rm.tags as "tags"
from rules r
left outer join rules t on t.uuid = r.template_uuid
left outer join rules_metadata rm on r.uuid = rm.rule_uuid
</sql>

<select id="selectByQuery" parameterType="map" resultType="Rule">
@@ -403,13 +395,11 @@
rules_metadata rm
where
rm.rule_uuid=#{ruleUuid,jdbcType=VARCHAR}
and rm.organization_uuid=#{organizationUuid,jdbcType=VARCHAR}
</select>

<insert id="insertMetadata" parameterType="org.sonar.db.rule.RuleMetadataDto">
insert into rules_metadata (
rule_uuid,
organization_uuid,
note_data,
note_user_uuid,
note_created_at,
@@ -427,7 +417,6 @@
)
values (
#{ruleUuid,jdbcType=VARCHAR},
#{organizationUuid,jdbcType=VARCHAR},
#{noteData,jdbcType=CLOB},
#{noteUserUuid,jdbcType=VARCHAR},
#{noteCreatedAt,jdbcType=BIGINT},
@@ -462,7 +451,6 @@
updated_at=#{updatedAt,jdbcType=BIGINT}
where
rule_uuid=#{ruleUuid,jdbcType=VARCHAR}
and organization_uuid=#{organizationUuid,jdbcType=VARCHAR}
</update>

<delete id="deleteParams" parameterType="String">

+ 2
- 6
server/sonar-db-dao/src/schema/schema-sq.ddl 查看文件

@@ -219,13 +219,12 @@ CREATE INDEX "PROJECTS_ROOT_UUID" ON "COMPONENTS"("ROOT_UUID");
CREATE INDEX "PROJECTS_UUID" ON "COMPONENTS"("UUID");

CREATE TABLE "DEFAULT_QPROFILES"(
"ORGANIZATION_UUID" VARCHAR(40) NOT NULL,
"LANGUAGE" VARCHAR(20) NOT NULL,
"QPROFILE_UUID" VARCHAR(255) NOT NULL,
"CREATED_AT" BIGINT NOT NULL,
"UPDATED_AT" BIGINT NOT NULL
);
ALTER TABLE "DEFAULT_QPROFILES" ADD CONSTRAINT "PK_DEFAULT_QPROFILES" PRIMARY KEY("ORGANIZATION_UUID", "LANGUAGE");
ALTER TABLE "DEFAULT_QPROFILES" ADD CONSTRAINT "PK_DEFAULT_QPROFILES" PRIMARY KEY("LANGUAGE");
CREATE UNIQUE INDEX "UNIQ_DEFAULT_QPROFILES_UUID" ON "DEFAULT_QPROFILES"("QPROFILE_UUID");

CREATE TABLE "DEPRECATED_RULE_KEYS"(
@@ -493,7 +492,6 @@ ALTER TABLE "NOTIFICATIONS" ADD CONSTRAINT "PK_NOTIFICATIONS" PRIMARY KEY("UUID"

CREATE TABLE "ORG_QPROFILES"(
"UUID" VARCHAR(255) NOT NULL,
"ORGANIZATION_UUID" VARCHAR(40) NOT NULL,
"RULES_PROFILE_UUID" VARCHAR(255) NOT NULL,
"PARENT_UUID" VARCHAR(255),
"LAST_USED" BIGINT,
@@ -502,7 +500,6 @@ CREATE TABLE "ORG_QPROFILES"(
"UPDATED_AT" BIGINT NOT NULL
);
ALTER TABLE "ORG_QPROFILES" ADD CONSTRAINT "PK_ORG_QPROFILES" PRIMARY KEY("UUID");
CREATE INDEX "QPROFILES_ORG_UUID" ON "ORG_QPROFILES"("ORGANIZATION_UUID");
CREATE INDEX "QPROFILES_RP_UUID" ON "ORG_QPROFILES"("RULES_PROFILE_UUID");
CREATE INDEX "ORG_QPROFILES_PARENT_UUID" ON "ORG_QPROFILES"("PARENT_UUID");

@@ -816,7 +813,6 @@ ALTER TABLE "RULES" ADD CONSTRAINT "PK_RULES" PRIMARY KEY("UUID");
CREATE UNIQUE INDEX "RULES_REPO_KEY" ON "RULES"("PLUGIN_RULE_KEY", "PLUGIN_NAME");

CREATE TABLE "RULES_METADATA"(
"ORGANIZATION_UUID" VARCHAR(40) NOT NULL,
"NOTE_DATA" CLOB,
"NOTE_USER_UUID" VARCHAR(255),
"NOTE_CREATED_AT" BIGINT,
@@ -833,7 +829,7 @@ CREATE TABLE "RULES_METADATA"(
"UPDATED_AT" BIGINT NOT NULL,
"RULE_UUID" VARCHAR(40) NOT NULL
);
ALTER TABLE "RULES_METADATA" ADD CONSTRAINT "PK_RULES_METADATA" PRIMARY KEY("RULE_UUID", "ORGANIZATION_UUID");
ALTER TABLE "RULES_METADATA" ADD CONSTRAINT "PK_RULES_METADATA" PRIMARY KEY("RULE_UUID");

CREATE TABLE "RULES_PARAMETERS"(
"NAME" VARCHAR(128) NOT NULL,

+ 0
- 6
server/sonar-db-dao/src/test/java/org/sonar/db/permission/AuthorizationDaoTest.java 查看文件

@@ -245,16 +245,10 @@ public class AuthorizationDaoTest {
db.users().insertPermissionOnUser(organization, user3, ADMINISTER);
db.users().insertPermissionOnAnyone(organization, ADMINISTER);

// other organizations are ignored
OrganizationDto org2 = db.organizations().insert();
db.users().insertPermissionOnUser(org2, user1, ADMINISTER);

assertThat(underTest.selectUserUuidsWithGlobalPermission(db.getSession(), organization.getUuid(), ADMINISTER.getKey()))
.containsExactlyInAnyOrder(user1.getUuid(), user2.getUuid(), user3.getUuid());
assertThat(underTest.selectUserUuidsWithGlobalPermission(db.getSession(), organization.getUuid(), PROVISION_PROJECTS.getKey()))
.containsExactlyInAnyOrder(user1.getUuid(), user2.getUuid());
assertThat(underTest.selectUserUuidsWithGlobalPermission(db.getSession(), org2.getUuid(), ADMINISTER.getKey()))
.containsExactlyInAnyOrder(user1.getUuid());
}

@Test

+ 17
- 32
server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/ActiveRuleDaoTest.java 查看文件

@@ -35,7 +35,6 @@ import org.sonar.api.server.rule.RuleParamType;
import org.sonar.api.utils.System2;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.db.rule.RuleParamDto;

@@ -62,7 +61,6 @@ public class ActiveRuleDaoTest {

private static final long NOW = 10_000_000L;

private OrganizationDto organization;
private QProfileDto profile1;
private QProfileDto profile2;
private RuleDefinitionDto rule1;
@@ -83,9 +81,8 @@ public class ActiveRuleDaoTest {

@Before
public void setUp() {
organization = db.organizations().insert();
profile1 = db.qualityProfiles().insert(organization);
profile2 = db.qualityProfiles().insert(organization);
profile1 = db.qualityProfiles().insert();
profile2 = db.qualityProfiles().insert();
rule1 = db.rules().insert();
rule2 = db.rules().insert();
rule3 = db.rules().insert();
@@ -117,9 +114,9 @@ public class ActiveRuleDaoTest {
underTest.insert(dbSession, activeRule2);
dbSession.commit();

assertThat(underTest.selectByRuleUuid(dbSession, organization, rule1.getUuid())).extracting("key")
assertThat(underTest.selectByOrgRuleUuid(dbSession, rule1.getUuid())).extracting("key")
.containsOnly(activeRule1.getKey(), activeRule2.getKey());
assertThat(underTest.selectByRuleUuid(dbSession, organization, rule3.getUuid())).isEmpty();
assertThat(underTest.selectByOrgRuleUuid(dbSession, rule3.getUuid())).isEmpty();
}

@Test
@@ -132,9 +129,9 @@ public class ActiveRuleDaoTest {
underTest.insert(dbSession, activeRule3);
dbSession.commit();

assertThat(underTest.selectByRuleUuids(dbSession, organization, singletonList(rule1.getUuid())))
assertThat(underTest.selectByRuleUuids(dbSession, singletonList(rule1.getUuid())))
.extracting("key").containsOnly(activeRule1.getKey(), activeRule3.getKey());
assertThat(underTest.selectByRuleUuids(dbSession, organization, newArrayList(rule1.getUuid(), rule2.getUuid())))
assertThat(underTest.selectByRuleUuids(dbSession, newArrayList(rule1.getUuid(), rule2.getUuid())))
.extracting("key").containsOnly(activeRule1.getKey(), activeRule2.getKey(), activeRule3.getKey());
}

@@ -148,8 +145,8 @@ public class ActiveRuleDaoTest {
List<OrgActiveRuleDto> result = underTest.selectByProfile(dbSession, profile1);
assertThat(result)
.hasSize(2)
.extracting(OrgActiveRuleDto::getOrganizationUuid, OrgActiveRuleDto::getOrgProfileUuid, OrgActiveRuleDto::getProfileUuid)
.containsOnly(tuple(organization.getUuid(), profile1.getKee(), profile1.getRulesProfileUuid()));
.extracting(OrgActiveRuleDto::getOrgProfileUuid, OrgActiveRuleDto::getProfileUuid)
.containsOnly(tuple(profile1.getKee(), profile1.getRulesProfileUuid()));

assertThat(underTest.selectByProfile(dbSession, profile2)).isEmpty();
}
@@ -170,8 +167,8 @@ public class ActiveRuleDaoTest {
underTest.insert(dbSession, activeRule1);

assertThat(underTest.selectByTypeAndProfileUuids(dbSession, singletonList(RuleType.VULNERABILITY.getDbConstant()), singletonList(profile1.getKee())))
.extracting(OrgActiveRuleDto::getOrgProfileUuid, OrgActiveRuleDto::getOrganizationUuid, OrgActiveRuleDto::getRuleUuid)
.contains(tuple(profile1.getKee(), profile1.getOrganizationUuid(), rule1.getUuid()));
.extracting(OrgActiveRuleDto::getOrgProfileUuid, OrgActiveRuleDto::getRuleUuid)
.contains(tuple(profile1.getKee(), rule1.getUuid()));
}

@Test
@@ -196,8 +193,8 @@ public class ActiveRuleDaoTest {
underTest.selectByTypeAndProfileUuids(dbSession,
singletonList(RuleType.VULNERABILITY.getDbConstant()),
singletonList(profile1.getKee())))
.extracting(OrgActiveRuleDto::getOrgProfileUuid, OrgActiveRuleDto::getOrganizationUuid, OrgActiveRuleDto::getRuleUuid)
.contains(tuple(profile1.getKee(), profile1.getOrganizationUuid(), rule1.getUuid()));
.extracting(OrgActiveRuleDto::getOrgProfileUuid, OrgActiveRuleDto::getRuleUuid)
.contains(tuple(profile1.getKee(), rule1.getUuid()));

assertThat(
underTest.selectByTypeAndProfileUuids(dbSession,
@@ -579,7 +576,7 @@ public class ActiveRuleDaoTest {
List<String> activeRuleUuids = asList(activeRule1.getUuid(), activeRule2.getUuid());
assertThat(underTest.selectParamsByActiveRuleUuids(dbSession, activeRuleUuids)).hasSize(2);

underTest.deleteParamsByRuleParamOfAllOrganizations(dbSession, rule1Param1);
underTest.deleteParamsByRuleParam(dbSession, rule1Param1);

assertThat(underTest.selectParamsByActiveRuleUuids(dbSession, activeRuleUuids)).isEmpty();
}
@@ -606,9 +603,9 @@ public class ActiveRuleDaoTest {
db.qualityProfiles().activateRule(profile1, rule2);
db.qualityProfiles().activateRule(profile1, removedRule);
db.qualityProfiles().activateRule(profile2, rule1);
QProfileDto profileWithoutActiveRule = db.qualityProfiles().insert(organization);
QProfileDto profileWithoutActiveRule = db.qualityProfiles().insert();

ActiveRuleCountQuery.Builder builder = ActiveRuleCountQuery.builder().setOrganization(organization);
ActiveRuleCountQuery.Builder builder = ActiveRuleCountQuery.builder();
assertThat(underTest.countActiveRulesByQuery(dbSession, builder.setProfiles(asList(profile1, profile2)).build()))
.containsOnly(entry(profile1.getKee(), 2L), entry(profile2.getKee(), 1L));
assertThat(underTest.countActiveRulesByQuery(dbSession, builder.setProfiles(singletonList(profileWithoutActiveRule)).build())).isEmpty();
@@ -628,7 +625,7 @@ public class ActiveRuleDaoTest {
db.qualityProfiles().activateRule(profile2, rule1);
db.qualityProfiles().activateRule(profile2, betaRule);

ActiveRuleCountQuery.Builder builder = ActiveRuleCountQuery.builder().setOrganization(organization);
ActiveRuleCountQuery.Builder builder = ActiveRuleCountQuery.builder();
assertThat(underTest.countActiveRulesByQuery(dbSession, builder.setProfiles(asList(profile1, profile2)).setRuleStatus(BETA).build()))
.containsOnly(entry(profile1.getKee(), 1L), entry(profile2.getKee(), 1L));
assertThat(underTest.countActiveRulesByQuery(dbSession, builder.setProfiles(singletonList(profile1)).setRuleStatus(READY).build()))
@@ -645,25 +642,13 @@ public class ActiveRuleDaoTest {
db.qualityProfiles().activateRule(profile2, rule1, ar -> ar.setInheritance(OVERRIDES));
db.qualityProfiles().activateRule(profile2, rule2, ar -> ar.setInheritance(INHERITED));

ActiveRuleCountQuery.Builder builder = ActiveRuleCountQuery.builder().setOrganization(organization);
ActiveRuleCountQuery.Builder builder = ActiveRuleCountQuery.builder();
assertThat(underTest.countActiveRulesByQuery(dbSession, builder.setProfiles(asList(profile1, profile2)).setInheritance(OVERRIDES).build()))
.containsOnly(entry(profile1.getKee(), 1L), entry(profile2.getKee(), 1L));
assertThat(underTest.countActiveRulesByQuery(dbSession, builder.setProfiles(asList(profile1, profile2)).setInheritance(INHERITED).build()))
.containsOnly(entry(profile2.getKee(), 1L));
}

@Test
public void countActiveRulesByQuery_filter_by_organization() {
db.qualityProfiles().activateRule(profile1, rule1);
OrganizationDto anotherOrganization = db.organizations().insert();
QProfileDto profileOnAnotherOrganization = db.qualityProfiles().insert(anotherOrganization);
db.qualityProfiles().activateRule(profileOnAnotherOrganization, rule1);

assertThat(underTest.countActiveRulesByQuery(dbSession,
ActiveRuleCountQuery.builder().setOrganization(organization).setProfiles(asList(profile1, profileOnAnotherOrganization)).build()))
.containsOnly(entry(profile1.getKee(), 1L));
}

@Test
public void scrollAllForIndexing_empty_table() {
Accumulator accumulator = new Accumulator();

+ 22
- 50
server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/DefaultQProfileDaoTest.java 查看文件

@@ -27,7 +27,6 @@ import org.sonar.api.utils.System2;
import org.sonar.core.util.Uuids;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.organization.OrganizationDto;

import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
@@ -35,31 +34,28 @@ import static org.assertj.core.api.Assertions.assertThat;
public class DefaultQProfileDaoTest {

@Rule
public DbTester dbTester = DbTester.create(System2.INSTANCE).setDisableDefaultOrganization(true);
public DbTester dbTester = DbTester.create(System2.INSTANCE);

private DbSession dbSession = dbTester.getSession();
private DefaultQProfileDao underTest = dbTester.getDbClient().defaultQProfileDao();

@Test
public void insertOrUpdate_inserts_row_when_does_not_exist() {
OrganizationDto org = dbTester.organizations().insert();
QProfileDto profile = dbTester.qualityProfiles().insert(org);
QProfileDto profile = dbTester.qualityProfiles().insert();
DefaultQProfileDto dto = DefaultQProfileDto.from(profile);

underTest.insertOrUpdate(dbSession, dto);
dbSession.commit();

assertThat(countRows()).isEqualTo(1);
assertThatIsDefault(org, profile);
assertThatIsDefault(profile);
}

@Test
public void insertOrUpdate_updates_row_when_exists() {
OrganizationDto org = dbTester.organizations().insert();
String previousQProfileUuid = Uuids.create();
DefaultQProfileDto dto = new DefaultQProfileDto()
.setLanguage("java")
.setOrganizationUuid(org.getUuid())
.setQProfileUuid(previousQProfileUuid);
underTest.insertOrUpdate(dbSession, dto);
dbSession.commit();
@@ -70,79 +66,55 @@ public class DefaultQProfileDaoTest {
dbSession.commit();

assertThat(countRows()).isEqualTo(1);
assertThat(selectUuidOfDefaultProfile(org, dto.getLanguage())).hasValue(newQProfileUuid);
assertThat(selectUuidOfDefaultProfile(dto.getLanguage())).hasValue(newQProfileUuid);
}

@Test
public void deleteByQProfileUuids_deletes_rows_related_to_specified_profile() {
OrganizationDto org1 = dbTester.organizations().insert();
OrganizationDto org2 = dbTester.organizations().insert();
underTest.insertOrUpdate(dbSession, new DefaultQProfileDto().setOrganizationUuid(org1.getUuid()).setLanguage("java").setQProfileUuid("u1"));
underTest.insertOrUpdate(dbSession, new DefaultQProfileDto().setOrganizationUuid(org1.getUuid()).setLanguage("js").setQProfileUuid("u2"));
underTest.insertOrUpdate(dbSession, new DefaultQProfileDto().setOrganizationUuid(org2.getUuid()).setLanguage("java").setQProfileUuid("u3"));
underTest.insertOrUpdate(dbSession, new DefaultQProfileDto().setOrganizationUuid(org2.getUuid()).setLanguage("js").setQProfileUuid("u4"));
underTest.insertOrUpdate(dbSession, new DefaultQProfileDto().setLanguage("java").setQProfileUuid("u1"));
underTest.insertOrUpdate(dbSession, new DefaultQProfileDto().setLanguage("js").setQProfileUuid("u2"));

underTest.deleteByQProfileUuids(dbSession, asList("u1", "u3"));
dbSession.commit();

assertThat(countRows()).isEqualTo(2);
assertThat(selectUuidOfDefaultProfile(org1, "java")).isEmpty();
assertThat(selectUuidOfDefaultProfile(org1, "js")).hasValue("u2");
assertThat(selectUuidOfDefaultProfile(org2, "java")).isEmpty();
assertThat(selectUuidOfDefaultProfile(org2, "js")).hasValue("u4");
assertThat(countRows()).isEqualTo(1);
assertThat(selectUuidOfDefaultProfile("java")).isEmpty();
assertThat(selectUuidOfDefaultProfile("js")).hasValue("u2");
}

@Test
public void selectExistingQProfileUuids_filters_defaults() {
OrganizationDto org = dbTester.organizations().insert();
QProfileDto profile1 = dbTester.qualityProfiles().insert(org);
QProfileDto profile2 = dbTester.qualityProfiles().insert(org);
QProfileDto profile1 = dbTester.qualityProfiles().insert();
QProfileDto profile2 = dbTester.qualityProfiles().insert();
dbTester.qualityProfiles().setAsDefault(profile1);

List<String> profileUuids = asList(profile1.getKee(), profile2.getKee(), "other");
assertThat(underTest.selectExistingQProfileUuids(dbSession, org.getUuid(), profileUuids))
assertThat(underTest.selectExistingQProfileUuids(dbSession, profileUuids))
.containsExactly(profile1.getKee());
}

@Test
public void isDefault_returns_true_if_profile_is_marked_as_default() {
OrganizationDto org = dbTester.organizations().insert();
QProfileDto profile1 = dbTester.qualityProfiles().insert(org);
QProfileDto profile2 = dbTester.qualityProfiles().insert(org);
QProfileDto profile1 = dbTester.qualityProfiles().insert();
QProfileDto profile2 = dbTester.qualityProfiles().insert();
dbTester.qualityProfiles().setAsDefault(profile1);

assertThat(underTest.isDefault(dbSession, org.getUuid(), profile1.getKee())).isTrue();
assertThat(underTest.isDefault(dbSession, org.getUuid(), profile2.getKee())).isFalse();
assertThat(underTest.isDefault(dbSession, org.getUuid(), "does_not_exist")).isFalse();
}

@Test
public void selectUuidsOfOrganizationsWithoutDefaultProfile() {
OrganizationDto org1 = dbTester.organizations().insert();
OrganizationDto org2 = dbTester.organizations().insert();
QProfileDto profileInOrg1 = dbTester.qualityProfiles().insert(org1, p -> p.setLanguage("java"));
QProfileDto profileInOrg2 = dbTester.qualityProfiles().insert(org2, p -> p.setLanguage("java"));
dbTester.qualityProfiles().setAsDefault(profileInOrg1);

assertThat(underTest.selectUuidsOfOrganizationsWithoutDefaultProfile(dbSession, "java"))
.containsExactly(org2.getUuid());
assertThat(underTest.selectUuidsOfOrganizationsWithoutDefaultProfile(dbSession, "js"))
.containsExactlyInAnyOrder(org1.getUuid(), org2.getUuid());
assertThat(underTest.isDefault(dbSession, profile1.getKee())).isTrue();
assertThat(underTest.isDefault(dbSession, profile2.getKee())).isFalse();
assertThat(underTest.isDefault(dbSession, "does_not_exist")).isFalse();
}

private void assertThatIsDefault(OrganizationDto org, QProfileDto profile) {
assertThat(selectUuidOfDefaultProfile(org, profile.getLanguage())).hasValue(profile.getKee());
assertThat(underTest.isDefault(dbSession, org.getUuid(), profile.getKee())).isTrue();
private void assertThatIsDefault(QProfileDto profile) {
assertThat(selectUuidOfDefaultProfile(profile.getLanguage())).hasValue(profile.getKee());
assertThat(underTest.isDefault(dbSession, profile.getKee())).isTrue();
}

private int countRows() {
return dbTester.countRowsOfTable("default_qprofiles");
}

private Optional<String> selectUuidOfDefaultProfile(OrganizationDto org, String language) {
return dbTester.select("select qprofile_uuid as \"profileUuid\" " +
" from default_qprofiles " +
" where organization_uuid='" + org.getUuid() + "' and language='" + language + "'")
private Optional<String> selectUuidOfDefaultProfile(String language) {
return dbTester.select("select qprofile_uuid as \"profileUuid\" from default_qprofiles where language='" + language + "'")
.stream()
.findFirst()
.map(m -> (String) m.get("profileUuid"));

+ 12
- 12
server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/QProfileChangeDaoTest.java 查看文件

@@ -92,8 +92,8 @@ public class QProfileChangeDaoTest {

@Test
public void selectByQuery_returns_changes_ordered_by_descending_date() {
QProfileDto profile1 = db.qualityProfiles().insert(db.getDefaultOrganization());
QProfileDto profile2 = db.qualityProfiles().insert(db.getDefaultOrganization());
QProfileDto profile1 = db.qualityProfiles().insert();
QProfileDto profile2 = db.qualityProfiles().insert();

QProfileChangeDto change1OnP1 = insertChange(profile1, "ACTIVATED", null, null);
QProfileChangeDto change2OnP1 = insertChange(profile1, "ACTIVATED", null, null);
@@ -107,7 +107,7 @@ public class QProfileChangeDaoTest {

@Test
public void selectByQuery_supports_pagination_of_changes() {
QProfileDto profile = db.qualityProfiles().insert(db.getDefaultOrganization());
QProfileDto profile = db.qualityProfiles().insert();
QProfileChangeDto change1 = insertChange(profile, "ACTIVATED", null, null);
QProfileChangeDto change2 = insertChange(profile, "ACTIVATED", null, null);
QProfileChangeDto change3 = insertChange(profile, "ACTIVATED", null, null);
@@ -124,7 +124,7 @@ public class QProfileChangeDaoTest {

@Test
public void selectByQuery_returns_changes_after_given_date() {
QProfileDto profile = db.qualityProfiles().insert(db.getDefaultOrganization());
QProfileDto profile = db.qualityProfiles().insert();
QProfileChangeDto change1 = insertChange(profile, "ACTIVATED", null, null);
QProfileChangeDto change2 = insertChange(profile, "ACTIVATED", null, null);
QProfileChangeDto change3 = insertChange(profile, "ACTIVATED", null, null);
@@ -139,7 +139,7 @@ public class QProfileChangeDaoTest {

@Test
public void selectByQuery_returns_changes_before_given_date() {
QProfileDto profile = db.qualityProfiles().insert(db.getDefaultOrganization());
QProfileDto profile = db.qualityProfiles().insert();
QProfileChangeDto change1 = insertChange(profile, "ACTIVATED", null, null);
QProfileChangeDto change2 = insertChange(profile, "ACTIVATED", null, null);
QProfileChangeDto change3 = insertChange(profile, "ACTIVATED", null, null);
@@ -154,7 +154,7 @@ public class QProfileChangeDaoTest {

@Test
public void selectByQuery_returns_changes_in_a_range_of_dates() {
QProfileDto profile = db.qualityProfiles().insert(db.getDefaultOrganization());
QProfileDto profile = db.qualityProfiles().insert();
QProfileChangeDto change1 = insertChange(profile, "ACTIVATED", null, null);
QProfileChangeDto change2 = insertChange(profile, "ACTIVATED", null, null);
QProfileChangeDto change3 = insertChange(profile, "ACTIVATED", null, null);
@@ -171,7 +171,7 @@ public class QProfileChangeDaoTest {

@Test
public void test_selectByQuery_mapping() {
QProfileDto profile = db.qualityProfiles().insert(db.getDefaultOrganization());
QProfileDto profile = db.qualityProfiles().insert();
QProfileChangeDto inserted = insertChange(profile, "ACTIVATED", "theLogin", "theData");

List<QProfileChangeDto> result = underTest.selectByQuery(dbSession, new QProfileChangeQuery(profile.getKee()));
@@ -188,8 +188,8 @@ public class QProfileChangeDaoTest {

@Test
public void countByQuery() {
QProfileDto profile1 = db.qualityProfiles().insert(db.getDefaultOrganization());
QProfileDto profile2 = db.qualityProfiles().insert(db.getDefaultOrganization());
QProfileDto profile1 = db.qualityProfiles().insert();
QProfileDto profile2 = db.qualityProfiles().insert();
long start = system2.now();
insertChange(profile1, "ACTIVATED", null, null);
insertChange(profile1, "ACTIVATED", null, null);
@@ -211,8 +211,8 @@ public class QProfileChangeDaoTest {

@Test
public void deleteByRulesProfileUuids() {
QProfileDto profile1 = db.qualityProfiles().insert(db.getDefaultOrganization());
QProfileDto profile2 = db.qualityProfiles().insert(db.getDefaultOrganization());
QProfileDto profile1 = db.qualityProfiles().insert();
QProfileDto profile2 = db.qualityProfiles().insert();
insertChange(profile1, "ACTIVATED", null, null);
insertChange(profile1, "ACTIVATED", null, null);
insertChange(profile2, "ACTIVATED", null, null);
@@ -225,7 +225,7 @@ public class QProfileChangeDaoTest {

@Test
public void deleteByProfileKeys_does_nothing_if_row_with_specified_key_does_not_exist() {
QProfileDto profile1 = db.qualityProfiles().insert(db.getDefaultOrganization());
QProfileDto profile1 = db.qualityProfiles().insert();
insertChange(profile1.getRulesProfileUuid(), "ACTIVATED", null, null);

underTest.deleteByRulesProfileUuids(dbSession, asList("does not exist"));

+ 45
- 78
server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/QProfileEditGroupsDaoTest.java 查看文件

@@ -21,11 +21,10 @@ package org.sonar.db.qualityprofile;

import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.utils.System2;
import org.sonar.api.impl.utils.TestSystem2;
import org.sonar.api.utils.System2;
import org.sonar.db.DbTester;
import org.sonar.db.Pagination;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.user.GroupDto;

import static java.util.Arrays.asList;
@@ -52,11 +51,10 @@ public class QProfileEditGroupsDaoTest {

@Test
public void exists() {
OrganizationDto organization = db.organizations().insert();
QProfileDto profile = db.qualityProfiles().insert(organization);
QProfileDto anotherProfile = db.qualityProfiles().insert(organization);
GroupDto group = db.users().insertGroup(organization);
GroupDto anotherGroup = db.users().insertGroup(organization);
QProfileDto profile = db.qualityProfiles().insert();
QProfileDto anotherProfile = db.qualityProfiles().insert();
GroupDto group = db.users().insertGroup();
GroupDto anotherGroup = db.users().insertGroup();
db.qualityProfiles().addGroupPermission(profile, group);

assertThat(underTest.exists(db.getSession(), profile, group)).isTrue();
@@ -70,28 +68,24 @@ public class QProfileEditGroupsDaoTest {

@Test
public void countByQuery() {
OrganizationDto organization = db.organizations().insert();
QProfileDto profile = db.qualityProfiles().insert(organization);
GroupDto group1 = db.users().insertGroup(organization);
GroupDto group2 = db.users().insertGroup(organization);
GroupDto group3 = db.users().insertGroup(organization);
QProfileDto profile = db.qualityProfiles().insert();
GroupDto group1 = db.users().insertGroup();
GroupDto group2 = db.users().insertGroup();
GroupDto group3 = db.users().insertGroup();
db.qualityProfiles().addGroupPermission(profile, group1);
db.qualityProfiles().addGroupPermission(profile, group2);

assertThat(underTest.countByQuery(db.getSession(), builder()
.setOrganization(organization)
.setProfile(profile)
.setMembership(ANY).build()))
.isEqualTo(3);

assertThat(underTest.countByQuery(db.getSession(), builder()
.setOrganization(organization)
.setProfile(profile)
.setMembership(IN).build()))
.isEqualTo(2);

assertThat(underTest.countByQuery(db.getSession(), builder()
.setOrganization(organization)
.setProfile(profile)
.setMembership(OUT).build()))
.isEqualTo(1);
@@ -99,16 +93,14 @@ public class QProfileEditGroupsDaoTest {

@Test
public void selectByQuery() {
OrganizationDto organization = db.organizations().insert();
QProfileDto profile = db.qualityProfiles().insert(organization);
GroupDto group1 = db.users().insertGroup(organization);
GroupDto group2 = db.users().insertGroup(organization);
GroupDto group3 = db.users().insertGroup(organization);
QProfileDto profile = db.qualityProfiles().insert();
GroupDto group1 = db.users().insertGroup();
GroupDto group2 = db.users().insertGroup();
GroupDto group3 = db.users().insertGroup();
db.qualityProfiles().addGroupPermission(profile, group1);
db.qualityProfiles().addGroupPermission(profile, group2);

assertThat(underTest.selectByQuery(db.getSession(), builder()
.setOrganization(organization)
.setProfile(profile)
.setMembership(ANY).build(), Pagination.all()))
.extracting(GroupMembershipDto::getGroupUuid, GroupMembershipDto::isSelected)
@@ -118,7 +110,6 @@ public class QProfileEditGroupsDaoTest {
tuple(group3.getUuid(), false));

assertThat(underTest.selectByQuery(db.getSession(), builder()
.setOrganization(organization)
.setProfile(profile)
.setMembership(IN).build(),
Pagination.all()))
@@ -126,7 +117,6 @@ public class QProfileEditGroupsDaoTest {
.containsExactlyInAnyOrder(tuple(group1.getUuid(), true), tuple(group2.getUuid(), true));

assertThat(underTest.selectByQuery(db.getSession(), builder()
.setOrganization(organization)
.setProfile(profile)
.setMembership(OUT).build(),
Pagination.all()))
@@ -136,17 +126,15 @@ public class QProfileEditGroupsDaoTest {

@Test
public void selectByQuery_search_by_name() {
OrganizationDto organization = db.organizations().insert();
QProfileDto profile = db.qualityProfiles().insert(organization);
GroupDto group1 = db.users().insertGroup(organization, "sonar-users-project");
GroupDto group2 = db.users().insertGroup(organization, "sonar-users-qprofile");
GroupDto group3 = db.users().insertGroup(organization, "sonar-admin");
QProfileDto profile = db.qualityProfiles().insert();
GroupDto group1 = db.users().insertGroup("sonar-users-project");
GroupDto group2 = db.users().insertGroup("sonar-users-qprofile");
GroupDto group3 = db.users().insertGroup("sonar-admin");
db.qualityProfiles().addGroupPermission(profile, group1);
db.qualityProfiles().addGroupPermission(profile, group2);
db.qualityProfiles().addGroupPermission(profile, group3);

assertThat(underTest.selectByQuery(db.getSession(), builder()
.setOrganization(organization)
.setProfile(profile)
.setMembership(IN)
.setQuery("project").build(),
@@ -155,7 +143,6 @@ public class QProfileEditGroupsDaoTest {
.containsExactlyInAnyOrder(group1.getUuid());

assertThat(underTest.selectByQuery(db.getSession(), builder()
.setOrganization(organization)
.setProfile(profile)
.setMembership(IN)
.setQuery("UserS").build(),
@@ -166,16 +153,14 @@ public class QProfileEditGroupsDaoTest {

@Test
public void selectByQuery_with_paging() {
OrganizationDto organization = db.organizations().insert();
QProfileDto profile = db.qualityProfiles().insert(organization);
GroupDto group1 = db.users().insertGroup(organization, "group1");
GroupDto group2 = db.users().insertGroup(organization, "group2");
GroupDto group3 = db.users().insertGroup(organization, "group3");
QProfileDto profile = db.qualityProfiles().insert();
GroupDto group1 = db.users().insertGroup("group1");
GroupDto group2 = db.users().insertGroup("group2");
GroupDto group3 = db.users().insertGroup("group3");
db.qualityProfiles().addGroupPermission(profile, group1);
db.qualityProfiles().addGroupPermission(profile, group2);

assertThat(underTest.selectByQuery(db.getSession(), builder()
.setOrganization(organization)
.setProfile(profile)
.setMembership(ANY)
.build(),
@@ -184,7 +169,6 @@ public class QProfileEditGroupsDaoTest {
.containsExactly(group1.getUuid());

assertThat(underTest.selectByQuery(db.getSession(), builder()
.setOrganization(organization)
.setProfile(profile)
.setMembership(ANY)
.build(),
@@ -193,7 +177,6 @@ public class QProfileEditGroupsDaoTest {
.containsExactly(group3.getUuid());

assertThat(underTest.selectByQuery(db.getSession(), builder()
.setOrganization(organization)
.setProfile(profile)
.setMembership(ANY)
.build(),
@@ -203,27 +186,21 @@ public class QProfileEditGroupsDaoTest {
}

@Test
public void selectQProfileUuidsByOrganizationAndGroups() {
OrganizationDto organization = db.organizations().insert();
OrganizationDto anotherOrganization = db.organizations().insert();
QProfileDto profile1 = db.qualityProfiles().insert(organization);
QProfileDto profile2 = db.qualityProfiles().insert(organization);
QProfileDto anotherProfile = db.qualityProfiles().insert(anotherOrganization);
GroupDto group1 = db.users().insertGroup(organization, "group1");
GroupDto group2 = db.users().insertGroup(organization, "group2");
GroupDto group3 = db.users().insertGroup(organization, "group3");
public void selectQProfileUuidsByGroups() {
QProfileDto profile1 = db.qualityProfiles().insert();
QProfileDto profile2 = db.qualityProfiles().insert();
GroupDto group1 = db.users().insertGroup("group1");
GroupDto group2 = db.users().insertGroup("group2");
GroupDto group3 = db.users().insertGroup("group3");
db.qualityProfiles().addGroupPermission(profile1, group1);
db.qualityProfiles().addGroupPermission(profile1, group2);
db.qualityProfiles().addGroupPermission(profile2, group2);
db.qualityProfiles().addGroupPermission(anotherProfile, group1);
db.qualityProfiles().addGroupPermission(anotherProfile, group3);

assertThat(underTest.selectQProfileUuidsByOrganizationAndGroups(db.getSession(), organization, asList(group1, group2)))
.containsExactlyInAnyOrder(profile1.getKee(), profile2.getKee())
.doesNotContain(anotherProfile.getKee());
assertThat(underTest.selectQProfileUuidsByOrganizationAndGroups(db.getSession(), organization, asList(group1, group2, group3)))
assertThat(underTest.selectQProfileUuidsByGroups(db.getSession(), asList(group1, group2)))
.containsExactlyInAnyOrder(profile1.getKee(), profile2.getKee());
assertThat(underTest.selectQProfileUuidsByGroups(db.getSession(), asList(group1, group2, group3)))
.containsExactlyInAnyOrder(profile1.getKee(), profile2.getKee());
assertThat(underTest.selectQProfileUuidsByOrganizationAndGroups(db.getSession(), organization, emptyList())).isEmpty();
assertThat(underTest.selectQProfileUuidsByGroups(db.getSession(),emptyList())).isEmpty();
}

@Test
@@ -234,7 +211,8 @@ public class QProfileEditGroupsDaoTest {
.setQProfileUuid("QPROFILE")
);

assertThat(db.selectFirst(db.getSession(), "select uuid as \"uuid\", group_uuid as \"groupUuid\", qprofile_uuid as \"qProfileUuid\", created_at as \"createdAt\" from qprofile_edit_groups")).contains(
assertThat(db.selectFirst(db.getSession(),
"select uuid as \"uuid\", group_uuid as \"groupUuid\", qprofile_uuid as \"qProfileUuid\", created_at as \"createdAt\" from qprofile_edit_groups")).contains(
entry("uuid", "ABCD"),
entry("groupUuid", "100"),
entry("qProfileUuid", "QPROFILE"),
@@ -243,9 +221,8 @@ public class QProfileEditGroupsDaoTest {

@Test
public void deleteByQProfileAndGroup() {
OrganizationDto organization = db.organizations().insert();
QProfileDto profile = db.qualityProfiles().insert(organization);
GroupDto group = db.users().insertGroup(organization);
QProfileDto profile = db.qualityProfiles().insert();
GroupDto group = db.users().insertGroup();
db.qualityProfiles().addGroupPermission(profile, group);
assertThat(underTest.exists(db.getSession(), profile, group)).isTrue();

@@ -256,48 +233,38 @@ public class QProfileEditGroupsDaoTest {

@Test
public void deleteByQProfiles() {
OrganizationDto organization = db.organizations().insert();
OrganizationDto anotherOrganization = db.organizations().insert();
QProfileDto profile1 = db.qualityProfiles().insert(organization);
QProfileDto profile2 = db.qualityProfiles().insert(organization);
QProfileDto profile3 = db.qualityProfiles().insert(organization);
QProfileDto anotherProfile = db.qualityProfiles().insert(anotherOrganization);
GroupDto group1 = db.users().insertGroup(organization);
GroupDto group2 = db.users().insertGroup(organization);
QProfileDto profile1 = db.qualityProfiles().insert();
QProfileDto profile2 = db.qualityProfiles().insert();
QProfileDto profile3 = db.qualityProfiles().insert();
GroupDto group1 = db.users().insertGroup();
GroupDto group2 = db.users().insertGroup();
db.qualityProfiles().addGroupPermission(profile1, group1);
db.qualityProfiles().addGroupPermission(profile2, group2);
db.qualityProfiles().addGroupPermission(profile3, group1);
db.qualityProfiles().addGroupPermission(anotherProfile, group1);

underTest.deleteByQProfiles(db.getSession(), asList(profile1, profile2));

assertThat(underTest.exists(db.getSession(), profile1, group1)).isFalse();
assertThat(underTest.exists(db.getSession(), profile2, group2)).isFalse();
assertThat(underTest.exists(db.getSession(), profile3, group1)).isTrue();
assertThat(underTest.exists(db.getSession(), anotherProfile, group1)).isTrue();
}

@Test
public void deleteByGroup() {
OrganizationDto organization = db.organizations().insert();
OrganizationDto anotherOrganization = db.organizations().insert();
QProfileDto profile1 = db.qualityProfiles().insert(organization);
QProfileDto profile2 = db.qualityProfiles().insert(organization);
QProfileDto profile3 = db.qualityProfiles().insert(organization);
QProfileDto anotherProfile = db.qualityProfiles().insert(anotherOrganization);
GroupDto group1 = db.users().insertGroup(organization);
GroupDto group2 = db.users().insertGroup(organization);
QProfileDto profile1 = db.qualityProfiles().insert();
QProfileDto profile2 = db.qualityProfiles().insert();
QProfileDto profile3 = db.qualityProfiles().insert();
GroupDto group1 = db.users().insertGroup();
GroupDto group2 = db.users().insertGroup();
db.qualityProfiles().addGroupPermission(profile1, group1);
db.qualityProfiles().addGroupPermission(profile2, group2);
db.qualityProfiles().addGroupPermission(profile3, group1);
db.qualityProfiles().addGroupPermission(anotherProfile, group1);

underTest.deleteByGroup(db.getSession(), group1);

assertThat(underTest.exists(db.getSession(), profile1, group1)).isFalse();
assertThat(underTest.exists(db.getSession(), profile2, group2)).isTrue();
assertThat(underTest.exists(db.getSession(), profile3, group1)).isFalse();
assertThat(underTest.exists(db.getSession(), anotherProfile, group1)).isFalse();
}

}

+ 28
- 77
server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/QProfileEditUsersDaoTest.java 查看文件

@@ -55,9 +55,8 @@ public class QProfileEditUsersDaoTest {

@Test
public void exists() {
OrganizationDto organization = db.organizations().insert();
QProfileDto profile = db.qualityProfiles().insert(organization);
QProfileDto anotherProfile = db.qualityProfiles().insert(organization);
QProfileDto profile = db.qualityProfiles().insert();
QProfileDto anotherProfile = db.qualityProfiles().insert();
UserDto user = db.users().insertUser();
UserDto anotherUser = db.users().insertUser();
db.qualityProfiles().addUserPermission(profile, user);
@@ -70,8 +69,8 @@ public class QProfileEditUsersDaoTest {

@Test
public void countByQuery() {
OrganizationDto organization = db.organizations().insert();
QProfileDto profile = db.qualityProfiles().insert(organization);
OrganizationDto organization = db.getDefaultOrganization();
QProfileDto profile = db.qualityProfiles().insert();
UserDto user1 = db.users().insertUser();
UserDto user2 = db.users().insertUser();
UserDto user3 = db.users().insertUser();
@@ -82,19 +81,16 @@ public class QProfileEditUsersDaoTest {
db.qualityProfiles().addUserPermission(profile, user2);

assertThat(underTest.countByQuery(db.getSession(), builder()
.setOrganization(organization)
.setProfile(profile)
.setMembership(ANY).build()))
.isEqualTo(3);

assertThat(underTest.countByQuery(db.getSession(), builder()
.setOrganization(organization)
.setProfile(profile)
.setMembership(IN).build()))
.isEqualTo(2);

assertThat(underTest.countByQuery(db.getSession(), builder()
.setOrganization(organization)
.setProfile(profile)
.setMembership(OUT).build()))
.isEqualTo(1);
@@ -102,19 +98,17 @@ public class QProfileEditUsersDaoTest {

@Test
public void selectByQuery() {
OrganizationDto organization = db.organizations().insert();
QProfileDto profile = db.qualityProfiles().insert(organization);
QProfileDto profile = db.qualityProfiles().insert();
UserDto user1 = db.users().insertUser();
UserDto user2 = db.users().insertUser();
UserDto user3 = db.users().insertUser();
db.organizations().addMember(organization, user1);
db.organizations().addMember(organization, user2);
db.organizations().addMember(organization, user3);
db.organizations().addMember(db.getDefaultOrganization(), user1);
db.organizations().addMember(db.getDefaultOrganization(), user2);
db.organizations().addMember(db.getDefaultOrganization(), user3);
db.qualityProfiles().addUserPermission(profile, user1);
db.qualityProfiles().addUserPermission(profile, user2);

assertThat(underTest.selectByQuery(db.getSession(), builder()
.setOrganization(organization)
.setProfile(profile)
.setMembership(ANY).build(), Pagination.all()))
.extracting(UserMembershipDto::getUserUuid, UserMembershipDto::isSelected)
@@ -124,7 +118,6 @@ public class QProfileEditUsersDaoTest {
tuple(user3.getUuid(), false));

assertThat(underTest.selectByQuery(db.getSession(), builder()
.setOrganization(organization)
.setProfile(profile)
.setMembership(IN).build(),
Pagination.all()))
@@ -132,7 +125,6 @@ public class QProfileEditUsersDaoTest {
.containsExactlyInAnyOrder(tuple(user1.getUuid(), true), tuple(user2.getUuid(), true));

assertThat(underTest.selectByQuery(db.getSession(), builder()
.setOrganization(organization)
.setProfile(profile)
.setMembership(OUT).build(),
Pagination.all()))
@@ -142,20 +134,18 @@ public class QProfileEditUsersDaoTest {

@Test
public void selectByQuery_search_by_name_or_login() {
OrganizationDto organization = db.organizations().insert();
QProfileDto profile = db.qualityProfiles().insert(organization);
QProfileDto profile = db.qualityProfiles().insert();
UserDto user1 = db.users().insertUser(u -> u.setLogin("user1").setName("John Doe"));
UserDto user2 = db.users().insertUser(u -> u.setLogin("user2").setName("John Smith"));
UserDto user3 = db.users().insertUser(u -> u.setLogin("user3").setName("Jane Doe"));
db.organizations().addMember(organization, user1);
db.organizations().addMember(organization, user2);
db.organizations().addMember(organization, user3);
db.organizations().addMember(db.getDefaultOrganization(), user1);
db.organizations().addMember(db.getDefaultOrganization(), user2);
db.organizations().addMember(db.getDefaultOrganization(), user3);
db.qualityProfiles().addUserPermission(profile, user1);
db.qualityProfiles().addUserPermission(profile, user2);
db.qualityProfiles().addUserPermission(profile, user3);

assertThat(underTest.selectByQuery(db.getSession(), builder()
.setOrganization(organization)
.setProfile(profile)
.setMembership(IN)
.setQuery("user2").build(),
@@ -164,7 +154,6 @@ public class QProfileEditUsersDaoTest {
.containsExactlyInAnyOrder(user2.getUuid());

assertThat(underTest.selectByQuery(db.getSession(), builder()
.setOrganization(organization)
.setProfile(profile)
.setMembership(IN)
.setQuery("joh").build(),
@@ -173,7 +162,6 @@ public class QProfileEditUsersDaoTest {
.containsExactlyInAnyOrder(user1.getUuid(), user2.getUuid());

assertThat(underTest.selectByQuery(db.getSession(), builder()
.setOrganization(organization)
.setProfile(profile)
.setMembership(IN)
.setQuery("Doe").build(),
@@ -184,19 +172,17 @@ public class QProfileEditUsersDaoTest {

@Test
public void selectByQuery_with_paging() {
OrganizationDto organization = db.organizations().insert();
QProfileDto profile = db.qualityProfiles().insert(organization);
QProfileDto profile = db.qualityProfiles().insert();
UserDto user1 = db.users().insertUser(u -> u.setName("user1"));
UserDto user2 = db.users().insertUser(u -> u.setName("user2"));
UserDto user3 = db.users().insertUser(u -> u.setName("user3"));
db.organizations().addMember(organization, user1);
db.organizations().addMember(organization, user2);
db.organizations().addMember(organization, user3);
db.organizations().addMember(db.getDefaultOrganization(), user1);
db.organizations().addMember(db.getDefaultOrganization(), user2);
db.organizations().addMember(db.getDefaultOrganization(), user3);
db.qualityProfiles().addUserPermission(profile, user1);
db.qualityProfiles().addUserPermission(profile, user2);

assertThat(underTest.selectByQuery(db.getSession(), builder()
.setOrganization(organization)
.setProfile(profile)
.setMembership(ANY)
.build(),
@@ -205,7 +191,6 @@ public class QProfileEditUsersDaoTest {
.containsExactly(user1.getUuid());

assertThat(underTest.selectByQuery(db.getSession(), builder()
.setOrganization(organization)
.setProfile(profile)
.setMembership(ANY)
.build(),
@@ -214,7 +199,6 @@ public class QProfileEditUsersDaoTest {
.containsExactly(user3.getUuid());

assertThat(underTest.selectByQuery(db.getSession(), builder()
.setOrganization(organization)
.setProfile(profile)
.setMembership(ANY)
.build(),
@@ -224,22 +208,17 @@ public class QProfileEditUsersDaoTest {
}

@Test
public void selectQProfileUuidsByOrganizationAndUser() {
OrganizationDto organization = db.organizations().insert();
OrganizationDto anotherOrganization = db.organizations().insert();
QProfileDto profile1 = db.qualityProfiles().insert(organization);
QProfileDto profile2 = db.qualityProfiles().insert(organization);
QProfileDto anotherProfile = db.qualityProfiles().insert(anotherOrganization);
public void selectQProfileUuidsByUser() {
QProfileDto profile1 = db.qualityProfiles().insert();
QProfileDto profile2 = db.qualityProfiles().insert();
UserDto user1 = db.users().insertUser(u -> u.setName("user1"));
UserDto user2 = db.users().insertUser(u -> u.setName("user2"));
db.qualityProfiles().addUserPermission(profile1, user1);
db.qualityProfiles().addUserPermission(profile2, user1);
db.qualityProfiles().addUserPermission(anotherProfile, user1);

assertThat(underTest.selectQProfileUuidsByOrganizationAndUser(db.getSession(), organization, user1))
.containsExactlyInAnyOrder(profile1.getKee(), profile2.getKee())
.doesNotContain(anotherProfile.getKee());
assertThat(underTest.selectQProfileUuidsByOrganizationAndUser(db.getSession(), organization, user2)).isEmpty();
assertThat(underTest.selectQProfileUuidsByUser(db.getSession(), user1))
.containsExactlyInAnyOrder(profile1.getKee(), profile2.getKee());
assertThat(underTest.selectQProfileUuidsByUser(db.getSession(), user2)).isEmpty();
}

@Test
@@ -274,8 +253,7 @@ public class QProfileEditUsersDaoTest {

@Test
public void deleteByQProfileAndUser() {
OrganizationDto organization = db.organizations().insert();
QProfileDto profile = db.qualityProfiles().insert(organization);
QProfileDto profile = db.qualityProfiles().insert();
UserDto user = db.users().insertUser();
db.qualityProfiles().addUserPermission(profile, user);
assertThat(underTest.exists(db.getSession(), profile, user)).isTrue();
@@ -287,62 +265,35 @@ public class QProfileEditUsersDaoTest {

@Test
public void deleteByQProfiles() {
OrganizationDto organization = db.organizations().insert();
OrganizationDto anotherOrganization = db.organizations().insert();
QProfileDto profile1 = db.qualityProfiles().insert(organization);
QProfileDto profile2 = db.qualityProfiles().insert(organization);
QProfileDto profile3 = db.qualityProfiles().insert(organization);
QProfileDto anotherProfile = db.qualityProfiles().insert(anotherOrganization);
QProfileDto profile1 = db.qualityProfiles().insert();
QProfileDto profile2 = db.qualityProfiles().insert();
QProfileDto profile3 = db.qualityProfiles().insert();
UserDto user1 = db.users().insertUser();
UserDto user2 = db.users().insertUser();
db.qualityProfiles().addUserPermission(profile1, user1);
db.qualityProfiles().addUserPermission(profile2, user2);
db.qualityProfiles().addUserPermission(profile3, user1);
db.qualityProfiles().addUserPermission(anotherProfile, user1);

underTest.deleteByQProfiles(db.getSession(), asList(profile1, profile2));

assertThat(underTest.exists(db.getSession(), profile1, user1)).isFalse();
assertThat(underTest.exists(db.getSession(), profile2, user2)).isFalse();
assertThat(underTest.exists(db.getSession(), profile3, user1)).isTrue();
assertThat(underTest.exists(db.getSession(), anotherProfile, user1)).isTrue();
}

@Test
public void deleteByUser() {
OrganizationDto organization1 = db.organizations().insert();
OrganizationDto organization2 = db.organizations().insert();
QProfileDto profile1 = db.qualityProfiles().insert(organization1);
QProfileDto profile2 = db.qualityProfiles().insert(organization2);
QProfileDto profile3 = db.qualityProfiles().insert(organization1);
QProfileDto profile1 = db.qualityProfiles().insert();
QProfileDto profile3 = db.qualityProfiles().insert();
UserDto user1 = db.users().insertUser();
UserDto user2 = db.users().insertUser();
db.qualityProfiles().addUserPermission(profile1, user1);
db.qualityProfiles().addUserPermission(profile2, user1);
db.qualityProfiles().addUserPermission(profile3, user2);

underTest.deleteByUser(db.getSession(), user1);

assertThat(underTest.exists(db.getSession(), profile1, user1)).isFalse();
assertThat(underTest.exists(db.getSession(), profile2, user1)).isFalse();
assertThat(underTest.exists(db.getSession(), profile3, user2)).isTrue();
}

@Test
public void deleteByOrganizationAndUser() {
OrganizationDto organization1 = db.organizations().insert();
OrganizationDto organization2 = db.organizations().insert();
QProfileDto profile1 = db.qualityProfiles().insert(organization1);
QProfileDto profile2 = db.qualityProfiles().insert(organization2);
UserDto user = db.users().insertUser();
db.organizations().addMember(organization1, user);
db.organizations().addMember(organization2, user);
db.qualityProfiles().addUserPermission(profile1, user);
db.qualityProfiles().addUserPermission(profile2, user);

underTest.deleteByOrganizationAndUser(db.getSession(), organization1, user);

assertThat(underTest.exists(db.getSession(), profile1, user)).isFalse();
assertThat(underTest.exists(db.getSession(), profile2, user)).isTrue();
}
}

+ 95
- 174
server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/QualityProfileDaoTest.java 查看文件

@@ -38,7 +38,6 @@ import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.organization.OrganizationTesting;
import org.sonar.db.project.ProjectDto;
import org.sonar.db.rule.RuleDefinitionDto;

@@ -64,12 +63,10 @@ public class QualityProfileDaoTest {

private DbSession dbSession = db.getSession();
private QualityProfileDao underTest = db.getDbClient().qualityProfileDao();
private OrganizationDto organization;

@Before
public void before() {
when(system.now()).thenReturn(UtcDateUtils.parseDateTime("2014-01-20T12:00:00+0000").getTime());
organization = db.organizations().insertForUuid("QualityProfileDaoTest-ORG");
}

@After
@@ -82,7 +79,6 @@ public class QualityProfileDaoTest {
QProfileDto dto = new QProfileDto()
.setKee("theUuid")
.setRulesProfileUuid("theRulesProfileUuid")
.setOrganizationUuid(organization.getUuid())
.setName("theName")
.setLanguage("theLang")
.setLastUsed(1_000L)
@@ -101,7 +97,6 @@ public class QualityProfileDaoTest {
assertThat(reloaded.getLastUsed()).isEqualTo(dto.getLastUsed());
assertThat(reloaded.getRulesUpdatedAt()).isEqualTo(dto.getRulesUpdatedAt());
assertThat(reloaded.getParentKee()).isEqualTo(dto.getParentKee());
assertThat(reloaded.getOrganizationUuid()).isEqualTo(dto.getOrganizationUuid());
assertThat(reloaded.isBuiltIn()).isEqualTo(dto.isBuiltIn());
}

@@ -110,7 +105,6 @@ public class QualityProfileDaoTest {
QProfileDto initial = new QProfileDto()
.setKee("theUuid")
.setRulesProfileUuid("theRulesProfileUuid")
.setOrganizationUuid(organization.getUuid())
.setName("theName")
.setLanguage("theLang")
.setLastUsed(1_000L)
@@ -129,15 +123,11 @@ public class QualityProfileDaoTest {
.setParentKee("theNewParentUuid")
.setUserUpdatedAt(12_000L)
.setRulesUpdatedAt("2017-06-01")
.setIsBuiltIn(false)

// field that cannot be changed
.setOrganizationUuid("theNewOrg");
.setIsBuiltIn(false);
underTest.update(dbSession, update);

QProfileDto reloaded = underTest.selectByUuid(dbSession, initial.getKee());
assertThat(reloaded.getKee()).isEqualTo(initial.getKee());
assertThat(reloaded.getOrganizationUuid()).isEqualTo(initial.getOrganizationUuid());

// updated fields
assertThat(reloaded.getLanguage()).isEqualTo(update.getLanguage());
@@ -237,11 +227,11 @@ public class QualityProfileDaoTest {

@Test
public void test_deleteProjectAssociationsByProfileUuids() {
QProfileDto profile1 = db.qualityProfiles().insert(organization);
QProfileDto profile2 = db.qualityProfiles().insert(organization);
ProjectDto project1 = db.components().insertPrivateProjectDto(organization);
ProjectDto project2 = db.components().insertPrivateProjectDto(organization);
ProjectDto project3 = db.components().insertPrivateProjectDto(organization);
QProfileDto profile1 = db.qualityProfiles().insert();
QProfileDto profile2 = db.qualityProfiles().insert();
ProjectDto project1 = db.components().insertPrivateProjectDto();
ProjectDto project2 = db.components().insertPrivateProjectDto();
ProjectDto project3 = db.components().insertPrivateProjectDto();

db.getDbClient().projectDao().selectByUuid(dbSession, project1.getUuid()).get();

@@ -259,7 +249,7 @@ public class QualityProfileDaoTest {

@Test
public void deleteProjectAssociationsByProfileUuids_does_nothing_if_empty_uuids() {
QProfileDto profile = db.qualityProfiles().insert(organization);
QProfileDto profile = db.qualityProfiles().insert();
ProjectDto project = db.components().insertPrivateProjectDto();
db.qualityProfiles().associateWithProject(project, profile);

@@ -272,7 +262,7 @@ public class QualityProfileDaoTest {
public void test_selectAll() {
List<QProfileDto> sharedData = createSharedData();

List<QProfileDto> reloadeds = underTest.selectOrderedByOrganizationUuid(dbSession, organization);
List<QProfileDto> reloadeds = underTest.selectAll(dbSession);

assertThat(reloadeds).hasSize(sharedData.size());

@@ -285,7 +275,6 @@ public class QualityProfileDaoTest {
assertThat(reloaded.getRulesProfileUuid()).isEqualTo(original.getRulesProfileUuid());
assertThat(reloaded.getName()).isEqualTo(original.getName());
assertThat(reloaded.getKee()).isEqualTo(original.getKee());
assertThat(reloaded.getOrganizationUuid()).isEqualTo(original.getOrganizationUuid());
assertThat(reloaded.getLanguage()).isEqualTo(original.getLanguage());
assertThat(reloaded.getParentKee()).isEqualTo(original.getParentKee());
assertThat(reloaded.getRulesUpdatedAt()).isEqualTo(original.getRulesUpdatedAt());
@@ -296,11 +285,10 @@ public class QualityProfileDaoTest {
}

@Test
public void selectOrderedByOrganizationUuid_is_sorted_by_profile_name() {
public void selectAll_is_sorted_by_profile_name() {
QProfileDto dto1 = new QProfileDto()
.setKee("js_first")
.setRulesProfileUuid("rp-js_first")
.setOrganizationUuid(organization.getUuid())
.setName("First")
.setLanguage("js")
.setLastUsed(1_000L)
@@ -312,7 +300,6 @@ public class QualityProfileDaoTest {
QProfileDto dto2 = new QProfileDto()
.setKee("js_second")
.setRulesProfileUuid("rp-js_second")
.setOrganizationUuid(organization.getUuid())
.setName("Second")
.setLanguage("js")
.setLastUsed(1_000L)
@@ -324,7 +311,6 @@ public class QualityProfileDaoTest {
QProfileDto dto3 = new QProfileDto()
.setKee("js_third")
.setRulesProfileUuid("rp-js_third")
.setOrganizationUuid(organization.getUuid())
.setName("Third")
.setLanguage("js")
.setLastUsed(1_000L)
@@ -333,7 +319,7 @@ public class QualityProfileDaoTest {
.setIsBuiltIn(false);
underTest.insert(dbSession, dto3);

List<QProfileDto> dtos = underTest.selectOrderedByOrganizationUuid(dbSession, organization);
List<QProfileDto> dtos = underTest.selectAll(dbSession);

assertThat(dtos).hasSize(3);
assertThat(dtos.get(0).getName()).isEqualTo("First");
@@ -343,92 +329,78 @@ public class QualityProfileDaoTest {

@Test
public void selectDefaultProfile() {
List<QProfileDto> sharedData = createSharedData();
createSharedData();

QProfileDto java = underTest.selectDefaultProfile(dbSession, organization, "java");
QProfileDto java = underTest.selectDefaultProfile(dbSession, "java");
assertThat(java).isNotNull();
assertThat(java.getKee()).isEqualTo("java_sonar_way");

assertThat(underTest.selectDefaultProfile(dbSession, db.organizations().insert(), "java")).isNull();
assertThat(underTest.selectDefaultProfile(dbSession, organization, "js")).isNull();
assertThat(underTest.selectDefaultProfile(dbSession, "js")).isNull();
}

@Test
public void selectDefaultProfiles() {
createSharedData();

List<QProfileDto> java = underTest.selectDefaultProfiles(dbSession, organization, singletonList("java"));
List<QProfileDto> java = underTest.selectDefaultProfiles(dbSession, singletonList("java"));
assertThat(java).extracting(QProfileDto::getKee).containsOnly("java_sonar_way");

assertThat(underTest.selectDefaultProfiles(dbSession, organization, singletonList("js"))).isEmpty();
assertThat(underTest.selectDefaultProfiles(dbSession, organization, of("java", "js"))).extracting(QProfileDto::getKee).containsOnly("java_sonar_way");
assertThat(underTest.selectDefaultProfiles(dbSession, organization, of("js", "java"))).extracting(QProfileDto::getKee).containsOnly("java_sonar_way");
assertThat(underTest.selectDefaultProfiles(dbSession, organization, Collections.emptyList())).isEmpty();
assertThat(underTest.selectDefaultProfiles(dbSession, singletonList("js"))).isEmpty();
assertThat(underTest.selectDefaultProfiles(dbSession, of("java", "js"))).extracting(QProfileDto::getKee).containsOnly("java_sonar_way");
assertThat(underTest.selectDefaultProfiles(dbSession, of("js", "java"))).extracting(QProfileDto::getKee).containsOnly("java_sonar_way");
assertThat(underTest.selectDefaultProfiles(dbSession, Collections.emptyList())).isEmpty();
}

@Test
public void selectByNameAndLanguage() {
List<QProfileDto> sharedData = createSharedData();

QProfileDto dto = underTest.selectByNameAndLanguage(dbSession, organization, "Sonar Way", "java");
QProfileDto dto = underTest.selectByNameAndLanguage(dbSession, "Sonar Way", "java");
assertThat(dto.getName()).isEqualTo("Sonar Way");
assertThat(dto.getLanguage()).isEqualTo("java");
assertThat(dto.getParentKee()).isNull();

assertThat(underTest.selectByNameAndLanguage(dbSession, organization, "Sonar Way", "java")).isNotNull();
assertThat(underTest.selectByNameAndLanguage(dbSession, organization, "Sonar Way", "unknown")).isNull();
assertThat(underTest.selectByNameAndLanguage(dbSession, "Sonar Way", "java")).isNotNull();
assertThat(underTest.selectByNameAndLanguage(dbSession, "Sonar Way", "unknown")).isNull();
}

@Test
public void selectByNameAndLanguages() {
createSharedData();

List<QProfileDto> dtos = underTest.selectByNameAndLanguages(dbSession, organization, "Sonar Way", singletonList("java"));
List<QProfileDto> dtos = underTest.selectByNameAndLanguages(dbSession, "Sonar Way", singletonList("java"));
assertThat(dtos).hasSize(1);
QProfileDto dto = dtos.iterator().next();
assertThat(dto.getName()).isEqualTo("Sonar Way");
assertThat(dto.getLanguage()).isEqualTo("java");
assertThat(dto.getParentKee()).isNull();

assertThat(underTest.selectByNameAndLanguages(dbSession, organization, "Sonar Way", singletonList("unknown"))).isEmpty();
assertThat(underTest.selectByNameAndLanguages(dbSession, organization, "Sonar Way", of("java", "unknown")))
assertThat(underTest.selectByNameAndLanguages(dbSession, "Sonar Way", singletonList("unknown"))).isEmpty();
assertThat(underTest.selectByNameAndLanguages(dbSession, "Sonar Way", of("java", "unknown")))
.extracting(QProfileDto::getKee).containsOnly(dto.getKee());
}

@Test
public void selectByLanguage() {
QProfileDto profile = QualityProfileTesting.newQualityProfileDto()
.setOrganizationUuid(organization.getUuid());
QProfileDto profile = QualityProfileTesting.newQualityProfileDto();
underTest.insert(dbSession, profile);

List<QProfileDto> results = underTest.selectByLanguage(dbSession, organization, profile.getLanguage());
List<QProfileDto> results = underTest.selectByLanguage(dbSession, profile.getLanguage());
assertThat(results).hasSize(1);
QProfileDto result = results.get(0);

assertThat(result.getName()).isEqualTo(profile.getName());
assertThat(result.getKee()).isEqualTo(profile.getKee());
assertThat(result.getLanguage()).isEqualTo(profile.getLanguage());
assertThat(result.getOrganizationUuid()).isEqualTo(profile.getOrganizationUuid());
assertThat(result.getRulesProfileUuid()).isEqualTo(profile.getRulesProfileUuid());
}

@Test
public void should_not_selectByLanguage_in_wrong_organization() {
QProfileDto profile = QualityProfileTesting.newQualityProfileDto()
.setOrganizationUuid(organization.getUuid());
underTest.insert(dbSession, profile);

List<QProfileDto> results = underTest.selectByLanguage(dbSession, OrganizationTesting.newOrganizationDto(), profile.getLanguage());
assertThat(results).isEmpty();
}

@Test
public void should_not_selectByLanguage_with_wrong_language() {
QProfileDto profile = QualityProfileTesting.newQualityProfileDto()
.setOrganizationUuid(organization.getUuid());
QProfileDto profile = QualityProfileTesting.newQualityProfileDto();
underTest.insert(dbSession, profile);

List<QProfileDto> results = underTest.selectByLanguage(dbSession, organization, "another language");
List<QProfileDto> results = underTest.selectByLanguage(dbSession, "another language");
assertThat(results).isEmpty();
}

@@ -437,7 +409,6 @@ public class QualityProfileDaoTest {
QProfileDto original1 = new QProfileDto()
.setKee("java_child1")
.setRulesProfileUuid("rp-java_child1")
.setOrganizationUuid(organization.getUuid())
.setName("Child1")
.setLanguage("java")
.setLastUsed(1_000L)
@@ -450,7 +421,6 @@ public class QualityProfileDaoTest {
QProfileDto original2 = new QProfileDto()
.setKee("java_child2")
.setRulesProfileUuid("rp-java_child2")
.setOrganizationUuid(organization.getUuid())
.setName("Child2")
.setLanguage("java")
.setLastUsed(1_000L)
@@ -463,7 +433,6 @@ public class QualityProfileDaoTest {
QProfileDto original3 = new QProfileDto()
.setKee("java_parent")
.setRulesProfileUuid("rp-java_parent")
.setOrganizationUuid(organization.getUuid())
.setName("Parent")
.setLanguage("java")
.setLastUsed(1_000L)
@@ -475,7 +444,6 @@ public class QualityProfileDaoTest {
QProfileDto original4 = new QProfileDto()
.setKee("js_child1")
.setRulesProfileUuid("rp-js_child1")
.setOrganizationUuid(organization.getUuid())
.setName("Child1")
.setLanguage("js")
.setLastUsed(1_000L)
@@ -488,7 +456,6 @@ public class QualityProfileDaoTest {
QProfileDto original5 = new QProfileDto()
.setKee("js_child2")
.setRulesProfileUuid("rp-js_child2")
.setOrganizationUuid(organization.getUuid())
.setName("Child2")
.setLanguage("js")
.setLastUsed(1_000L)
@@ -501,7 +468,6 @@ public class QualityProfileDaoTest {
QProfileDto original6 = new QProfileDto()
.setKee("js_parent")
.setRulesProfileUuid("rp-js_parent")
.setOrganizationUuid(organization.getUuid())
.setName("Parent")
.setLanguage("js")
.setLastUsed(1_000L)
@@ -528,13 +494,13 @@ public class QualityProfileDaoTest {
@Test
public void selectBuiltInRuleProfilesWithActiveRules() {
// a quality profile without active rules but not builtin
db.qualityProfiles().insert(db.getDefaultOrganization(), qp -> qp.setIsBuiltIn(false));
db.qualityProfiles().insert(qp -> qp.setIsBuiltIn(false));

// a built-in quality profile without active rules
db.qualityProfiles().insert(db.getDefaultOrganization(), qp -> qp.setIsBuiltIn(true));
db.qualityProfiles().insert(qp -> qp.setIsBuiltIn(true));

// a built-in quality profile with active rules
QProfileDto builtInQPWithActiveRules = db.qualityProfiles().insert(db.getDefaultOrganization(), qp -> qp.setIsBuiltIn(true));
QProfileDto builtInQPWithActiveRules = db.qualityProfiles().insert(qp -> qp.setIsBuiltIn(true));
RuleDefinitionDto ruleDefinitionDto = db.rules().insert();
db.qualityProfiles().activateRule(builtInQPWithActiveRules, ruleDefinitionDto);

@@ -547,38 +513,35 @@ public class QualityProfileDaoTest {

@Test
public void selectByRuleProfileUuid() {
db.qualityProfiles().insert(db.getDefaultOrganization(), qp -> qp.setIsBuiltIn(false));
db.qualityProfiles().insert(db.getDefaultOrganization(), qp -> qp.setIsBuiltIn(true));
QProfileDto qprofile1 = db.qualityProfiles().insert(db.getDefaultOrganization(), qp -> qp.setIsBuiltIn(true));
db.qualityProfiles().insert(qp -> qp.setIsBuiltIn(false));
db.qualityProfiles().insert(qp -> qp.setIsBuiltIn(true));
QProfileDto qprofile1 = db.qualityProfiles().insert(qp -> qp.setIsBuiltIn(true));

dbSession.commit();

assertThat(underTest.selectByRuleProfileUuid(dbSession, db.getDefaultOrganization().getUuid(), qprofile1.getRulesProfileUuid()))
assertThat(underTest.selectByRuleProfileUuid(dbSession, qprofile1.getRulesProfileUuid()))
.extracting(QProfileDto::getName)
.isEqualTo(qprofile1.getName());

assertThat(underTest.selectByRuleProfileUuid(dbSession, "A", qprofile1.getRulesProfileUuid()))
.isNull();

assertThat(underTest.selectByRuleProfileUuid(dbSession, db.getDefaultOrganization().getUuid(), "A"))
assertThat(underTest.selectByRuleProfileUuid(dbSession, "A"))
.isNull();
}

@Test
public void selectDefaultBuiltInProfilesWithoutActiveRules() {
// a quality profile without active rules but not builtin
db.qualityProfiles().insert(db.getDefaultOrganization(), qp -> qp.setIsBuiltIn(false).setLanguage("java"));
db.qualityProfiles().insert(qp -> qp.setIsBuiltIn(false).setLanguage("java"));

// a built-in quality profile without active rules
QProfileDto javaQPWithoutActiveRules = db.qualityProfiles().insert(db.getDefaultOrganization(), qp -> qp.setIsBuiltIn(true).setLanguage("java"));
QProfileDto javaQPWithoutActiveRules = db.qualityProfiles().insert(qp -> qp.setIsBuiltIn(true).setLanguage("java"));
db.qualityProfiles().setAsDefault(javaQPWithoutActiveRules);

// a built-in quality profile without active rules
QProfileDto cppQPWithoutActiveRules = db.qualityProfiles().insert(db.getDefaultOrganization(), qp -> qp.setIsBuiltIn(true).setLanguage("cpp"));
QProfileDto cppQPWithoutActiveRules = db.qualityProfiles().insert(qp -> qp.setIsBuiltIn(true).setLanguage("cpp"));
db.qualityProfiles().setAsDefault(cppQPWithoutActiveRules);

// a built-in quality profile with active rules
QProfileDto builtInQPWithActiveRules = db.qualityProfiles().insert(db.getDefaultOrganization(), qp -> qp.setIsBuiltIn(true).setLanguage("java"));
QProfileDto builtInQPWithActiveRules = db.qualityProfiles().insert(qp -> qp.setIsBuiltIn(true).setLanguage("java"));
RuleDefinitionDto ruleDefinitionDto = db.rules().insert();
db.qualityProfiles().activateRule(builtInQPWithActiveRules, ruleDefinitionDto);

@@ -601,7 +564,7 @@ public class QualityProfileDaoTest {

@Test
public void selectDescendants_returns_empty_if_no_children() {
QProfileDto base = db.qualityProfiles().insert(db.getDefaultOrganization());
QProfileDto base = db.qualityProfiles().insert();

Collection<QProfileDto> descendants = underTest.selectDescendants(dbSession, singleton(base));

@@ -617,14 +580,14 @@ public class QualityProfileDaoTest {

@Test
public void selectDescendants_returns_descendants_in_any_order() {
QProfileDto base1 = db.qualityProfiles().insert(db.getDefaultOrganization());
QProfileDto child1OfBase1 = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setParentKee(base1.getKee()));
QProfileDto child2OfBase1 = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setParentKee(base1.getKee()));
QProfileDto grandChildOfBase1 = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setParentKee(child1OfBase1.getKee()));
QProfileDto base2 = db.qualityProfiles().insert(db.getDefaultOrganization());
QProfileDto childOfBase2 = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setParentKee(base2.getKee()));
QProfileDto grandChildOfBase2 = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setParentKee(childOfBase2.getKee()));
QProfileDto other = db.qualityProfiles().insert(db.getDefaultOrganization());
QProfileDto base1 = db.qualityProfiles().insert();
QProfileDto child1OfBase1 = db.qualityProfiles().insert(p -> p.setParentKee(base1.getKee()));
QProfileDto child2OfBase1 = db.qualityProfiles().insert(p -> p.setParentKee(base1.getKee()));
QProfileDto grandChildOfBase1 = db.qualityProfiles().insert(p -> p.setParentKee(child1OfBase1.getKee()));
QProfileDto base2 = db.qualityProfiles().insert();
QProfileDto childOfBase2 = db.qualityProfiles().insert(p -> p.setParentKee(base2.getKee()));
QProfileDto grandChildOfBase2 = db.qualityProfiles().insert(p -> p.setParentKee(childOfBase2.getKee()));
QProfileDto other = db.qualityProfiles().insert();

// descendants of a single base profile
verifyDescendants(singleton(base1), asList(child1OfBase1, child2OfBase1, grandChildOfBase1));
@@ -650,32 +613,25 @@ public class QualityProfileDaoTest {

@Test
public void countProjectsByProfileKey() {
QProfileDto profileWithoutProjects = db.qualityProfiles().insert(organization);
QProfileDto profileWithProjects = db.qualityProfiles().insert(organization);
ProjectDto project1 = db.components().insertPrivateProjectDto(organization);
ProjectDto project2 = db.components().insertPrivateProjectDto(organization);
QProfileDto profileWithoutProjects = db.qualityProfiles().insert();
QProfileDto profileWithProjects = db.qualityProfiles().insert();
ProjectDto project1 = db.components().insertPrivateProjectDto();
ProjectDto project2 = db.components().insertPrivateProjectDto();

db.qualityProfiles().associateWithProject(project1, profileWithProjects);
db.qualityProfiles().associateWithProject(project2, profileWithProjects);

OrganizationDto otherOrg = db.organizations().insert();
QProfileDto profileInOtherOrg = db.qualityProfiles().insert(otherOrg);
ProjectDto projectInOtherOrg = db.components().insertPrivateProjectDto(otherOrg);
db.qualityProfiles().associateWithProject(projectInOtherOrg, profileInOtherOrg);

assertThat(underTest.countProjectsByOrganizationAndProfiles(dbSession, organization, asList(profileWithoutProjects, profileWithProjects, profileInOtherOrg))).containsOnly(
assertThat(underTest.countProjectsByProfiles(dbSession, asList(profileWithoutProjects, profileWithProjects))).containsOnly(
MapEntry.entry(profileWithProjects.getKee(), 2L));
assertThat(underTest.countProjectsByOrganizationAndProfiles(dbSession, otherOrg, singletonList(profileWithoutProjects))).isEmpty();
assertThat(underTest.countProjectsByOrganizationAndProfiles(dbSession, organization, Collections.emptyList())).isEmpty();
assertThat(underTest.countProjectsByProfiles(dbSession, Collections.emptyList())).isEmpty();
}

@Test
public void test_selectAssociatedToProjectAndLanguage() {
OrganizationDto org = db.organizations().insert();
ProjectDto project1 = db.components().insertPublicProjectDto(org);
ProjectDto project2 = db.components().insertPublicProjectDto(org);
QProfileDto javaProfile = db.qualityProfiles().insert(org, p -> p.setLanguage("java"));
QProfileDto jsProfile = db.qualityProfiles().insert(org, p -> p.setLanguage("js"));
ProjectDto project1 = db.components().insertPublicProjectDto();
ProjectDto project2 = db.components().insertPublicProjectDto();
QProfileDto javaProfile = db.qualityProfiles().insert(p -> p.setLanguage("java"));
QProfileDto jsProfile = db.qualityProfiles().insert(p -> p.setLanguage("js"));
db.qualityProfiles().associateWithProject(project1, javaProfile, jsProfile);

assertThat(underTest.selectAssociatedToProjectAndLanguage(dbSession, project1, "java").getKee())
@@ -690,11 +646,10 @@ public class QualityProfileDaoTest {

@Test
public void test_selectAssociatedToProjectUuidAndLanguages() {
OrganizationDto org = db.organizations().insert();
ProjectDto project1 = db.components().insertPublicProjectDto(org);
ProjectDto project2 = db.components().insertPublicProjectDto(org);
QProfileDto javaProfile = db.qualityProfiles().insert(org, p -> p.setLanguage("java"));
QProfileDto jsProfile = db.qualityProfiles().insert(org, p -> p.setLanguage("js"));
ProjectDto project1 = db.components().insertPublicProjectDto();
ProjectDto project2 = db.components().insertPublicProjectDto();
QProfileDto javaProfile = db.qualityProfiles().insert(p -> p.setLanguage("java"));
QProfileDto jsProfile = db.qualityProfiles().insert(p -> p.setLanguage("js"));
db.qualityProfiles().associateWithProject(project1, javaProfile, jsProfile);

assertThat(underTest.selectAssociatedToProjectUuidAndLanguages(dbSession, project1, singletonList("java")))
@@ -713,11 +668,10 @@ public class QualityProfileDaoTest {

@Test
public void test_updateProjectProfileAssociation() {
OrganizationDto org = db.organizations().insert();
ProjectDto project = db.components().insertPrivateProjectDto(org);
QProfileDto javaProfile1 = db.qualityProfiles().insert(org, p -> p.setLanguage("java"));
QProfileDto jsProfile = db.qualityProfiles().insert(org, p -> p.setLanguage("js"));
QProfileDto javaProfile2 = db.qualityProfiles().insert(org, p -> p.setLanguage("java"));
ProjectDto project = db.components().insertPrivateProjectDto();
QProfileDto javaProfile1 = db.qualityProfiles().insert(p -> p.setLanguage("java"));
QProfileDto jsProfile = db.qualityProfiles().insert(p -> p.setLanguage("js"));
QProfileDto javaProfile2 = db.qualityProfiles().insert(p -> p.setLanguage("java"));
db.qualityProfiles().associateWithProject(project, javaProfile1, jsProfile);

underTest.updateProjectProfileAssociation(dbSession, project, javaProfile2.getKee(), javaProfile1.getKee());
@@ -741,9 +695,9 @@ public class QualityProfileDaoTest {

@Test
public void select_selected_projects() {
ComponentDto project1 = db.components().insertPrivateProject(t -> t.setName("Project1 name").setOrganizationUuid(organization.getUuid()));
ComponentDto project2 = db.components().insertPrivateProject(t -> t.setName("Project2 name").setOrganizationUuid(organization.getUuid()));
ComponentDto project3 = db.components().insertPrivateProject(t -> t.setName("Project3 name").setOrganizationUuid(organization.getUuid()));
ComponentDto project1 = db.components().insertPrivateProject(t -> t.setName("Project1 name"));
ComponentDto project2 = db.components().insertPrivateProject(t -> t.setName("Project2 name"));
ComponentDto project3 = db.components().insertPrivateProject(t -> t.setName("Project3 name"));
OrganizationDto organization2 = db.organizations().insert();
ComponentDto project4 = db.components().insertPrivateProject(t -> t.setName("Project4 name").setOrganizationUuid(organization2.getUuid()));
ComponentDto branch = db.components().insertProjectBranch(project1, t -> t.setKey("branch"));
@@ -758,24 +712,21 @@ public class QualityProfileDaoTest {
db.qualityProfiles().associateWithProject(db.components().getProjectDto(project3), profile2);
QProfileDto profile3 = newQualityProfileDto();

assertThat(underTest.selectSelectedProjects(dbSession, organization, profile1, null))
assertThat(underTest.selectSelectedProjects(dbSession, profile1, null))
.extracting("projectUuid", "projectKey", "projectName", "profileKey")
.containsOnly(
tuple(project1.uuid(), project1.getDbKey(), project1.name(), profile1.getKee()),
tuple(project2.uuid(), project2.getDbKey(), project2.name(), profile1.getKee()));

assertThat(underTest.selectSelectedProjects(dbSession, organization, profile1, "ect1")).hasSize(1);
assertThat(underTest.selectSelectedProjects(dbSession, organization, profile3, null)).isEmpty();
assertThat(underTest.selectSelectedProjects(dbSession, profile1, "ect1")).hasSize(1);
assertThat(underTest.selectSelectedProjects(dbSession, profile3, null)).isEmpty();
}

@Test
public void select_deselected_projects() {
ComponentDto project1 = db.components().insertPrivateProject(t -> t.setName("Project1 name").setOrganizationUuid(organization.getUuid()));
ComponentDto project2 = db.components().insertPrivateProject(t -> t.setName("Project2 name").setOrganizationUuid(organization.getUuid()));
ComponentDto project3 = db.components().insertPrivateProject(t -> t.setName("Project3 name").setOrganizationUuid(organization.getUuid()));
OrganizationDto organization2 = db.organizations().insert();
ComponentDto project4 = db.components().insertPrivateProject(t -> t.setName("Project4 name").setOrganizationUuid(organization2.getUuid()));
ComponentDto branch = db.components().insertProjectBranch(project1, t -> t.setKey("branch"));
ComponentDto project1 = db.components().insertPrivateProject(t -> t.setName("Project1 name"));
ComponentDto project2 = db.components().insertPrivateProject(t -> t.setName("Project2 name"));
ComponentDto project3 = db.components().insertPrivateProject(t -> t.setName("Project3 name"));

QProfileDto profile1 = newQualityProfileDto();
db.qualityProfiles().insert(profile1);
@@ -786,23 +737,21 @@ public class QualityProfileDaoTest {
db.qualityProfiles().associateWithProject(db.components().getProjectDto(project2), profile2);
QProfileDto profile3 = newQualityProfileDto();

assertThat(underTest.selectDeselectedProjects(dbSession, organization, profile1, null))
assertThat(underTest.selectDeselectedProjects(dbSession, profile1, null))
.extracting("projectUuid", "projectKey", "projectName", "profileKey")
.containsExactly(
tuple(project2.uuid(), project2.getDbKey(), project2.name(), null),
tuple(project3.uuid(), project3.getDbKey(), project3.name(), null));

assertThat(underTest.selectDeselectedProjects(dbSession, organization, profile1, "ect2")).hasSize(1);
assertThat(underTest.selectDeselectedProjects(dbSession, organization, profile3, null)).hasSize(3);
assertThat(underTest.selectDeselectedProjects(dbSession, profile1, "ect2")).hasSize(1);
assertThat(underTest.selectDeselectedProjects(dbSession, profile3, null)).hasSize(3);
}

@Test
public void select_project_associations() {
ComponentDto project1 = db.components().insertPrivateProject(t -> t.setName("Project1 name").setOrganizationUuid(organization.getUuid()));
ComponentDto project2 = db.components().insertPrivateProject(t -> t.setName("Project2 name").setOrganizationUuid(organization.getUuid()));
ComponentDto project3 = db.components().insertPrivateProject(t -> t.setName("Project3 name").setOrganizationUuid(organization.getUuid()));
OrganizationDto organization2 = db.organizations().insert();
ComponentDto project4 = db.components().insertPrivateProject(t -> t.setName("Project4 name").setOrganizationUuid(organization2.getUuid()));
ComponentDto project1 = db.components().insertPrivateProject(t -> t.setName("Project1 name"));
ComponentDto project2 = db.components().insertPrivateProject(t -> t.setName("Project2 name"));
ComponentDto project3 = db.components().insertPrivateProject(t -> t.setName("Project3 name"));
ComponentDto branch = db.components().insertProjectBranch(project1, t -> t.setKey("branch"));

QProfileDto profile1 = newQualityProfileDto();
@@ -814,31 +763,25 @@ public class QualityProfileDaoTest {
db.qualityProfiles().associateWithProject(db.components().getProjectDto(project2), profile2);
QProfileDto profile3 = newQualityProfileDto();

assertThat(underTest.selectProjectAssociations(dbSession, organization, profile1, null))
assertThat(underTest.selectProjectAssociations(dbSession, profile1, null))
.extracting("projectUuid", "projectKey", "projectName", "profileKey")
.containsOnly(
tuple(project1.uuid(), project1.getDbKey(), project1.name(), profile1.getKee()),
tuple(project2.uuid(), project2.getDbKey(), project2.name(), null),
tuple(project3.uuid(), project3.getDbKey(), project3.name(), null));

assertThat(underTest.selectProjectAssociations(dbSession, organization, profile1, "ect2")).hasSize(1);
assertThat(underTest.selectProjectAssociations(dbSession, organization, profile3, null)).hasSize(3);
assertThat(underTest.selectProjectAssociations(dbSession, profile1, "ect2")).hasSize(1);
assertThat(underTest.selectProjectAssociations(dbSession, profile3, null)).hasSize(3);
}

@Test
public void selectUuidsOfCustomRulesProfiles_returns_the_custom_profiles_with_specified_name() {
OrganizationDto org1 = db.organizations().insert();
OrganizationDto org2 = db.organizations().insert();
OrganizationDto org3 = db.organizations().insert();
QProfileDto outdatedProfile1 = db.qualityProfiles().insert(org1, p -> p.setIsBuiltIn(false).setLanguage("java").setName("foo"));
QProfileDto outdatedProfile2 = db.qualityProfiles().insert(org2, p -> p.setIsBuiltIn(false).setLanguage("java").setName("foo"));
QProfileDto builtInProfile = db.qualityProfiles().insert(org3, p -> p.setIsBuiltIn(true).setLanguage("java").setName("foo"));
QProfileDto differentLanguage = db.qualityProfiles().insert(org1, p -> p.setIsBuiltIn(false).setLanguage("cobol").setName("foo"));
QProfileDto differentName = db.qualityProfiles().insert(org1, p -> p.setIsBuiltIn(false).setLanguage("java").setName("bar"));
QProfileDto outdatedProfile1 = db.qualityProfiles().insert(p -> p.setIsBuiltIn(false).setLanguage("java").setName("foo"));
QProfileDto differentLanguage = db.qualityProfiles().insert(p -> p.setIsBuiltIn(false).setLanguage("cobol").setName("foo"));
QProfileDto differentName = db.qualityProfiles().insert(p -> p.setIsBuiltIn(false).setLanguage("java").setName("bar"));

Collection<String> keys = underTest.selectUuidsOfCustomRulesProfiles(dbSession, "java", "foo");

assertThat(keys).containsExactlyInAnyOrder(outdatedProfile1.getRulesProfileUuid(), outdatedProfile2.getRulesProfileUuid());
assertThat(keys).containsOnly(outdatedProfile1.getRulesProfileUuid());
}

@Test
@@ -849,22 +792,18 @@ public class QualityProfileDaoTest {
@Test
public void renameAndCommit_updates_name_of_specified_profiles() {
OrganizationDto org1 = db.organizations().insert();
OrganizationDto org2 = db.organizations().insert();
QProfileDto fooInOrg1 = db.qualityProfiles().insert(org1, p -> p.setName("foo"));
QProfileDto fooInOrg2 = db.qualityProfiles().insert(org2, p -> p.setName("foo"));
QProfileDto bar = db.qualityProfiles().insert(org1, p -> p.setName("bar"));
QProfileDto fooInOrg1 = db.qualityProfiles().insert(p -> p.setName("foo"));
QProfileDto bar = db.qualityProfiles().insert(p -> p.setName("bar"));

underTest.renameRulesProfilesAndCommit(dbSession, asList(fooInOrg1.getRulesProfileUuid(), fooInOrg2.getRulesProfileUuid()), "foo (copy)");
underTest.renameRulesProfilesAndCommit(dbSession, asList(fooInOrg1.getRulesProfileUuid()), "foo (copy)");

assertThat(underTest.selectOrFailByUuid(dbSession, fooInOrg1.getKee()).getName()).isEqualTo("foo (copy)");
assertThat(underTest.selectOrFailByUuid(dbSession, fooInOrg2.getKee()).getName()).isEqualTo("foo (copy)");
assertThat(underTest.selectOrFailByUuid(dbSession, bar.getKee()).getName()).isEqualTo("bar");
}

@Test
public void renameAndCommit_does_nothing_if_empty_keys() {
OrganizationDto org = db.organizations().insert();
QProfileDto profile = db.qualityProfiles().insert(org, p -> p.setName("foo"));
QProfileDto profile = db.qualityProfiles().insert(p -> p.setName("foo"));

underTest.renameRulesProfilesAndCommit(dbSession, Collections.emptyList(), "foo (copy)");

@@ -873,25 +812,13 @@ public class QualityProfileDaoTest {

@Test
public void selectQProfilesByRuleProfileUuid() {
OrganizationDto org1 = db.organizations().insert();
OrganizationDto org2 = db.organizations().insert();

RulesProfileDto ruleProfile1 = QualityProfileTesting.newRuleProfileDto();
OrgQProfileDto profile1InOrg1 = new OrgQProfileDto().setOrganizationUuid(org1.getUuid()).setRulesProfileUuid(ruleProfile1.getUuid()).setUuid(Uuids.create());
OrgQProfileDto profile1InOrg2 = new OrgQProfileDto().setOrganizationUuid(org2.getUuid()).setRulesProfileUuid(ruleProfile1.getUuid()).setUuid(Uuids.create());
RulesProfileDto ruleProfile2 = QualityProfileTesting.newRuleProfileDto();
OrgQProfileDto profile2InOrg1 = new OrgQProfileDto().setOrganizationUuid(org1.getUuid()).setRulesProfileUuid(ruleProfile2.getUuid()).setUuid(Uuids.create());
OrgQProfileDto profile1InOrg1 = new OrgQProfileDto().setRulesProfileUuid(ruleProfile1.getUuid()).setUuid(Uuids.create());
db.getDbClient().qualityProfileDao().insert(db.getSession(), ruleProfile1);
db.getDbClient().qualityProfileDao().insert(db.getSession(), profile1InOrg1);
db.getDbClient().qualityProfileDao().insert(db.getSession(), profile1InOrg2);
db.getDbClient().qualityProfileDao().insert(db.getSession(), ruleProfile2);
db.getDbClient().qualityProfileDao().insert(db.getSession(), profile2InOrg1);

List<QProfileDto> result = db.getDbClient().qualityProfileDao().selectQProfilesByRuleProfile(db.getSession(), ruleProfile1);
assertThat(result).extracting(QProfileDto::getKee).containsExactlyInAnyOrder(profile1InOrg1.getUuid(), profile1InOrg2.getUuid());

result = db.getDbClient().qualityProfileDao().selectQProfilesByRuleProfile(db.getSession(), ruleProfile2);
assertThat(result).extracting(QProfileDto::getKee).containsExactlyInAnyOrder(profile2InOrg1.getUuid());
assertThat(result).extracting(QProfileDto::getKee).containsExactlyInAnyOrder(profile1InOrg1.getUuid());
}

@Test
@@ -905,7 +832,6 @@ public class QualityProfileDaoTest {
QProfileDto dto1 = new QProfileDto()
.setKee("java_sonar_way")
.setRulesProfileUuid("rp-java_sonar_way")
.setOrganizationUuid(organization.getUuid())
.setName("Sonar Way")
.setLanguage("java")
.setLastUsed(1_000L)
@@ -917,7 +843,6 @@ public class QualityProfileDaoTest {
QProfileDto dto2 = new QProfileDto()
.setKee("js_sonar_way")
.setRulesProfileUuid("rp-js_sonar_way")
.setOrganizationUuid(organization.getUuid())
.setName("Sonar Way")
.setLanguage("js")
.setLastUsed(1_000L)
@@ -926,10 +851,6 @@ public class QualityProfileDaoTest {
.setIsBuiltIn(true);
underTest.insert(dbSession, dto2);

DefaultQProfileDto defaultQProfileDto = new DefaultQProfileDto()
.setQProfileUuid(dto1.getKee())
.setLanguage(dto1.getLanguage())
.setOrganizationUuid(organization.getUuid());
db.getDbClient().defaultQProfileDao().insertOrUpdate(dbSession, DefaultQProfileDto.from(dto1));

return Arrays.asList(dto1, dto2);

+ 2
- 5
server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/QualityProfileExportDaoTest.java 查看文件

@@ -75,15 +75,12 @@ public class QualityProfileExportDaoTest {
RuleDefinitionDto customRule = createRule(language, RuleStatus.READY, ruleTemplate.getUuid());
RuleMetadataDto customRuleMetadata = createRuleMetadata(new RuleMetadataDto()
.setRuleUuid(customRule.getUuid())
.setOrganizationUuid(db.getDefaultOrganization().getUuid())
.setNoteData("Extended description")
.setTags(Sets.newHashSet("tag1", "tag2", "tag3")));

RuleDefinitionDto rule = createRule(language, RuleStatus.READY, null);
RuleMetadataDto ruleMetadata = createRuleMetadata(new RuleMetadataDto()
.setRuleUuid(rule.getUuid())
.setOrganizationUuid(db.getDefaultOrganization().getUuid()));

.setRuleUuid(rule.getUuid()));
QProfileDto profile = createProfile(language);

List<ActiveRuleDto> activeRules = activate(profile, customRule, rule);
@@ -225,7 +222,7 @@ public class QualityProfileExportDaoTest {
}

private QProfileDto createProfile(String lanugage) {
return db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(lanugage));
return db.qualityProfiles().insert(p -> p.setLanguage(lanugage));
}

private List<ActiveRuleDto> activate(QProfileDto profile, RuleDefinitionDto... rules) {

+ 77
- 283
server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDaoTest.java 查看文件

@@ -29,7 +29,6 @@ import java.util.Set;
import java.util.function.Consumer;
import org.apache.ibatis.exceptions.PersistenceException;
import org.apache.ibatis.session.ResultHandler;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -43,9 +42,6 @@ import org.sonar.api.utils.DateUtils;
import org.sonar.api.utils.System2;
import org.sonar.db.DbTester;
import org.sonar.db.RowNotFoundException;
import org.sonar.db.es.RuleExtensionId;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.organization.OrganizationTesting;
import org.sonar.db.rule.RuleDto.Scope;

import static com.google.common.collect.Sets.newHashSet;
@@ -59,8 +55,6 @@ import static org.sonar.api.rule.RuleStatus.REMOVED;
import static org.sonar.db.rule.RuleTesting.newRuleMetadata;

public class RuleDaoTest {

private static final String ORGANIZATION_UUID = "org-1";
private static final String UNKNOWN_RULE_UUID = "unknown-uuid";

@Rule
@@ -69,58 +63,35 @@ public class RuleDaoTest {
public DbTester db = DbTester.create(System2.INSTANCE);

private RuleDao underTest = db.getDbClient().ruleDao();
private OrganizationDto organization;

@Before
public void before() {
organization = db.organizations().insert(o -> o.setUuid(ORGANIZATION_UUID));
}

@Test
public void selectByKey() {
RuleDefinitionDto ruleDefinition = db.rules().insert();
OrganizationDto organization = db.organizations().insert();
RuleMetadataDto metadata = newRuleMetadata(ruleDefinition, organization);
RuleMetadataDto metadata = newRuleMetadata(ruleDefinition);
db.rules().insertRule(ruleDefinition, metadata);

assertThat(underTest.selectByKey(db.getSession(), organization.getUuid(), RuleKey.of("foo", "bar")))
assertThat(underTest.selectByKey(db.getSession(), RuleKey.of("foo", "bar")))
.isEmpty();
RuleDto rule = underTest.selectByKey(db.getSession(), organization.getUuid(), ruleDefinition.getKey()).get();
RuleDto rule = underTest.selectByKey(db.getSession(), ruleDefinition.getKey()).get();
assertEquals(rule.getDefinition(), ruleDefinition);
verifyMetadata(rule.getMetadata(), ruleDefinition, metadata);
verifyMetadata(rule.getMetadata(), metadata);
}

@Test
public void selectByKey_return_rule_even_if_organization_does_not_exist() {
public void selectByKey_return_rule() {
RuleDefinitionDto ruleDefinition = db.rules().insert();

assertThat(underTest.selectByKey(db.getSession(), OrganizationTesting.newOrganizationDto().getUuid(), ruleDefinition.getKey()))
.isNotEmpty();
assertThat(underTest.selectByKey(db.getSession(), ruleDefinition.getKey())).isNotEmpty();
}

@Test
public void selectByKey_populates_organizationUuid_even_when_organization_has_no_metadata() {
OrganizationDto organization = db.organizations().insert();
public void selectByKey_returns_metadata() {
RuleDefinitionDto ruleDefinition = db.rules().insert();
RuleMetadataDto ruleMetadata = newRuleMetadata(ruleDefinition);
db.rules().insertRule(ruleDefinition, ruleMetadata);

RuleDto rule = underTest.selectByKey(db.getSession(), organization.getUuid(), ruleDefinition.getKey()).get();
verifyNoMetadata(rule.getMetadata(), organization);
}

@Test
public void selectByKey_returns_metadata_of_specified_organization() {
RuleDefinitionDto ruleDefinition = db.rules().insert();
OrganizationDto organization1 = db.organizations().insert();
RuleMetadataDto expectedOrg1 = newRuleMetadata(ruleDefinition, organization1);
db.rules().insertRule(ruleDefinition, expectedOrg1);
OrganizationDto organization2 = db.organizations().insert();
RuleMetadataDto expectedOrg2 = newRuleMetadata(ruleDefinition, organization2);
db.rules().insertRule(ruleDefinition, expectedOrg2);

RuleDto rule = underTest.selectByKey(db.getSession(), organization1.getUuid(), ruleDefinition.getKey()).get();
verifyMetadata(rule.getMetadata(), ruleDefinition, expectedOrg1);
rule = underTest.selectByKey(db.getSession(), organization2.getUuid(), ruleDefinition.getKey()).get();
verifyMetadata(rule.getMetadata(), ruleDefinition, expectedOrg2);
RuleDto rule = underTest.selectByKey(db.getSession(), ruleDefinition.getKey()).get();
verifyMetadata(rule.getMetadata(), ruleMetadata);
}

@Test
@@ -136,48 +107,14 @@ public class RuleDaoTest {
@Test
public void selectByUuid() {
RuleDefinitionDto ruleDefinition = db.rules().insert();
OrganizationDto organization = db.organizations().insert();
RuleMetadataDto metadata = newRuleMetadata(ruleDefinition, organization);
RuleMetadataDto metadata = newRuleMetadata(ruleDefinition);
RuleDto expected = db.rules().insertRule(ruleDefinition, metadata);

assertThat(underTest.selectByUuid(expected.getUuid() + 500, organization.getUuid(), db.getSession()))
assertThat(underTest.selectByUuid(expected.getUuid() + 500, db.getSession()))
.isEmpty();
RuleDto rule = underTest.selectByUuid(expected.getUuid(), organization.getUuid(), db.getSession()).get();
RuleDto rule = underTest.selectByUuid(expected.getUuid(), db.getSession()).get();
assertEquals(rule.getDefinition(), ruleDefinition);
verifyMetadata(rule.getMetadata(), ruleDefinition, metadata);
}

@Test
public void selectByUuid_return_rule_even_if_organization_does_not_exist() {
RuleDefinitionDto ruleDefinition = db.rules().insert();

assertThat(underTest.selectByUuid(ruleDefinition.getUuid(), "dfdfdf", db.getSession()))
.isNotEmpty();
}

@Test
public void selectByUuid_populates_organizationUuid_even_when_organization_has_no_metadata() {
OrganizationDto organization = db.organizations().insert();
RuleDefinitionDto ruleDefinition = db.rules().insert();

RuleDto rule = underTest.selectByUuid(ruleDefinition.getUuid(), organization.getUuid(), db.getSession()).get();
verifyNoMetadata(rule.getMetadata(), organization);
}

@Test
public void selectByUuid_returns_metadata_of_specified_organization() {
RuleDefinitionDto ruleDefinition = db.rules().insert();
OrganizationDto organization1 = db.organizations().insert();
RuleMetadataDto expectedOrg1 = newRuleMetadata(ruleDefinition, organization1);
db.rules().insertRule(ruleDefinition, expectedOrg1);
OrganizationDto organization2 = db.organizations().insert();
RuleMetadataDto expectedOrg2 = newRuleMetadata(ruleDefinition, organization2);
db.rules().insertRule(ruleDefinition, expectedOrg2);

RuleDto rule = underTest.selectByUuid(ruleDefinition.getUuid(), organization1.getUuid(), db.getSession()).get();
verifyMetadata(rule.getMetadata(), ruleDefinition, expectedOrg1);
rule = underTest.selectByUuid(ruleDefinition.getUuid(), organization2.getUuid(), db.getSession()).get();
verifyMetadata(rule.getMetadata(), ruleDefinition, expectedOrg2);
verifyMetadata(rule.getMetadata(), metadata);
}

@Test
@@ -191,30 +128,18 @@ public class RuleDaoTest {

@Test
public void selectByUuids() {
OrganizationDto organization = db.organizations().insert();
RuleDefinitionDto rule1 = db.rules().insert();
db.rules().insertOrUpdateMetadata(rule1, organization);
db.rules().insertOrUpdateMetadata(rule1);
RuleDefinitionDto rule2 = db.rules().insert();
db.rules().insertOrUpdateMetadata(rule2, organization);
db.rules().insertOrUpdateMetadata(rule2);
RuleDefinitionDto removedRule = db.rules().insert(r -> r.setStatus(REMOVED));
db.rules().insertOrUpdateMetadata(removedRule, organization);

assertThat(underTest.selectByUuids(db.getSession(), organization.getUuid(), singletonList(rule1.getUuid()))).hasSize(1);
assertThat(underTest.selectByUuids(db.getSession(), organization.getUuid(), asList(rule1.getUuid(), rule2.getUuid()))).hasSize(2);
assertThat(underTest.selectByUuids(db.getSession(), organization.getUuid(), asList(rule1.getUuid(), rule2.getUuid(), UNKNOWN_RULE_UUID))).hasSize(2);
assertThat(underTest.selectByUuids(db.getSession(), organization.getUuid(), asList(rule1.getUuid(), rule2.getUuid(), removedRule.getUuid()))).hasSize(3);
assertThat(underTest.selectByUuids(db.getSession(), organization.getUuid(), singletonList(UNKNOWN_RULE_UUID))).isEmpty();
}

@Test
public void selectByUuids_populates_organizationUuid_even_when_organization_has_no_metadata() {
OrganizationDto organization = db.organizations().insert();
RuleDefinitionDto rule1 = db.rules().insert();
RuleDefinitionDto rule2 = db.rules().insert();
db.rules().insertOrUpdateMetadata(removedRule);

assertThat(underTest.selectByUuids(db.getSession(), organization.getUuid(), asList(rule1.getUuid(), rule2.getUuid())))
.extracting(RuleDto::getOrganizationUuid)
.containsExactly(organization.getUuid(), organization.getUuid());
assertThat(underTest.selectByUuids(db.getSession(), singletonList(rule1.getUuid()))).hasSize(1);
assertThat(underTest.selectByUuids(db.getSession(), asList(rule1.getUuid(), rule2.getUuid()))).hasSize(2);
assertThat(underTest.selectByUuids(db.getSession(), asList(rule1.getUuid(), rule2.getUuid(), UNKNOWN_RULE_UUID))).hasSize(2);
assertThat(underTest.selectByUuids(db.getSession(), asList(rule1.getUuid(), rule2.getUuid(), removedRule.getUuid()))).hasSize(3);
assertThat(underTest.selectByUuids(db.getSession(), singletonList(UNKNOWN_RULE_UUID))).isEmpty();
}

@Test
@@ -230,31 +155,19 @@ public class RuleDaoTest {

@Test
public void selectOrFailByKey() {
OrganizationDto organization = db.organizations().insert();
RuleDefinitionDto rule1 = db.rules().insert();
db.rules().insert();

RuleDto rule = underTest.selectOrFailByKey(db.getSession(), organization, rule1.getKey());
RuleDto rule = underTest.selectOrFailByKey(db.getSession(), rule1.getKey());
assertThat(rule.getUuid()).isEqualTo(rule1.getUuid());
}

@Test
public void selectOrFailByKey_fails_if_rule_not_found() {
OrganizationDto organization = db.organizations().insert();

thrown.expect(RowNotFoundException.class);
thrown.expectMessage("Rule with key 'NOT:FOUND' does not exist");

underTest.selectOrFailByKey(db.getSession(), organization, RuleKey.of("NOT", "FOUND"));
}

@Test
public void selectOrFailByKey_populates_organizationUuid_even_when_organization_has_no_metadata() {
OrganizationDto organization = db.organizations().insert();
RuleDefinitionDto rule = db.rules().insert();

assertThat(underTest.selectOrFailByKey(db.getSession(), organization, rule.getKey()).getOrganizationUuid())
.isEqualTo(organization.getUuid());
underTest.selectOrFailByKey(db.getSession(), RuleKey.of("NOT", "FOUND"));
}

@Test
@@ -267,30 +180,19 @@ public class RuleDaoTest {

@Test
public void selectByKeys() {
OrganizationDto organization = db.organizations().insert();
RuleDefinitionDto rule1 = db.rules().insert();
db.rules().insertOrUpdateMetadata(rule1, organization);
db.rules().insertOrUpdateMetadata(rule1);
RuleDefinitionDto rule2 = db.rules().insert();
db.rules().insertOrUpdateMetadata(rule2, organization);
db.rules().insertOrUpdateMetadata(rule2);

assertThat(underTest.selectByKeys(db.getSession(), organization.getUuid(), Collections.emptyList())).isEmpty();
assertThat(underTest.selectByKeys(db.getSession(), organization.getUuid(), singletonList(RuleKey.of("NOT", "FOUND")))).isEmpty();
assertThat(underTest.selectByKeys(db.getSession(), Collections.emptyList())).isEmpty();
assertThat(underTest.selectByKeys(db.getSession(), singletonList(RuleKey.of("NOT", "FOUND")))).isEmpty();

List<RuleDto> rules = underTest.selectByKeys(db.getSession(), organization.getUuid(), asList(rule1.getKey(), RuleKey.of("java", "OTHER")));
List<RuleDto> rules = underTest.selectByKeys(db.getSession(), asList(rule1.getKey(), RuleKey.of("java", "OTHER")));
assertThat(rules).hasSize(1);
assertThat(rules.get(0).getUuid()).isEqualTo(rule1.getUuid());
}

@Test
public void selectByKeys_populates_organizationUuid_even_when_organization_has_no_metadata() {
OrganizationDto organization = db.organizations().insert();
RuleDefinitionDto rule = db.rules().insert();

assertThat(underTest.selectByKeys(db.getSession(), organization.getUuid(), singletonList(rule.getKey())))
.extracting(RuleDto::getOrganizationUuid)
.containsExactly(organization.getUuid());
}

@Test
public void selectDefinitionByKeys() {
RuleDefinitionDto rule = db.rules().insert();
@@ -305,53 +207,25 @@ public class RuleDaoTest {

@Test
public void selectAll() {
OrganizationDto organization = db.organizations().insert();
RuleDto rule1 = db.rules().insertRule(organization);
RuleDto rule2 = db.rules().insertRule(organization);
RuleDto rule3 = db.rules().insertRule(organization);

assertThat(underTest.selectAll(db.getSession(), organization.getUuid()))
.extracting(RuleDto::getUuid)
.containsOnly(rule1.getUuid(), rule2.getUuid(), rule3.getUuid());
}

@Test
public void selectAll_returns_all_rules_even_if_organization_does_not_exist() {
RuleDefinitionDto rule1 = db.rules().insert();
RuleDefinitionDto rule2 = db.rules().insert();
RuleDefinitionDto rule3 = db.rules().insert();
RuleDto rule1 = db.rules().insertRule();
RuleDto rule2 = db.rules().insertRule();
RuleDto rule3 = db.rules().insertRule();

assertThat(underTest.selectAll(db.getSession(), "dfdfdf"))
assertThat(underTest.selectAll(db.getSession()))
.extracting(RuleDto::getUuid)
.containsOnly(rule1.getUuid(), rule2.getUuid(), rule3.getUuid());
}

@Test
public void selectAll_populates_organizationUuid_even_when_organization_has_no_metadata() {
OrganizationDto organization = db.organizations().insert();
RuleDefinitionDto ruleDefinition1 = db.rules().insert();
RuleDefinitionDto ruleDefinition2 = db.rules().insert();

List<RuleDto> rules = underTest.selectAll(db.getSession(), organization.getUuid());
assertThat(rules)
.extracting(RuleDto::getUuid)
.containsOnly(ruleDefinition1.getUuid(), ruleDefinition2.getUuid());
assertThat(rules)
.extracting(RuleDto::getOrganizationUuid)
.containsExactly(organization.getUuid(), organization.getUuid());
}

@Test
public void selectAll_returns_metadata_of_specified_organization() {
public void selectAll_returns_metadata() {
RuleDefinitionDto ruleDefinition = db.rules().insert();
OrganizationDto organization = db.organizations().insert();
RuleMetadataDto expected = newRuleMetadata(ruleDefinition, organization);
RuleMetadataDto expected = newRuleMetadata(ruleDefinition);
db.rules().insertRule(ruleDefinition, expected);

List<RuleDto> rules = underTest.selectAll(db.getSession(), organization.getUuid());
List<RuleDto> rules = underTest.selectAll(db.getSession());
assertThat(rules).hasSize(1);

verifyMetadata(rules.iterator().next().getMetadata(), ruleDefinition, expected);
verifyMetadata(rules.iterator().next().getMetadata(), expected);
}

private void assertEquals(RuleDefinitionDto actual, RuleDefinitionDto expected) {
@@ -379,8 +253,7 @@ public class RuleDaoTest {
assertThat(actual.getType()).isEqualTo(expected.getType());
}

private static void verifyMetadata(RuleMetadataDto metadata, RuleDefinitionDto ruleDefinition, RuleMetadataDto expected) {
assertThat(metadata.getOrganizationUuid()).isEqualTo(expected.getOrganizationUuid());
private static void verifyMetadata(RuleMetadataDto metadata, RuleMetadataDto expected) {
assertThat(metadata.getRemediationBaseEffort()).isEqualTo(expected.getRemediationBaseEffort());
assertThat(metadata.getRemediationFunction()).isEqualTo(expected.getRemediationFunction());
assertThat(metadata.getRemediationGapMultiplier()).isEqualTo(expected.getRemediationGapMultiplier());
@@ -394,21 +267,6 @@ public class RuleDaoTest {
assertThat(metadata.getAdHocType()).isEqualTo(expected.getAdHocType());
}

private static void verifyNoMetadata(RuleMetadataDto metadata, OrganizationDto organization) {
assertThat(metadata.getOrganizationUuid()).isEqualTo(organization.getUuid());
assertThat(metadata.getRemediationBaseEffort()).isNull();
assertThat(metadata.getRemediationFunction()).isNull();
assertThat(metadata.getRemediationGapMultiplier()).isNull();
assertThat(metadata.getTags()).isEmpty();
assertThat(metadata.getNoteData()).isNull();
assertThat(metadata.getNoteCreatedAt()).isNull();
assertThat(metadata.getNoteUpdatedAt()).isNull();
assertThat(metadata.getAdHocName()).isNull();
assertThat(metadata.getAdHocDescription()).isNull();
assertThat(metadata.getAdHocSeverity()).isNull();
assertThat(metadata.getAdHocType()).isNull();
}

@Test
public void selectAllDefinitions() {
RuleDefinitionDto rule1 = db.rules().insert();
@@ -436,156 +294,121 @@ public class RuleDaoTest {

@Test
public void selectByTypeAndLanguages() {
OrganizationDto organization = db.organizations().insert();
OrganizationDto organization2 = db.organizations().insert();

RuleDefinitionDto rule1 = db.rules().insert(
r -> r.setKey(RuleKey.of("java", "S001"))
.setConfigKey("S1")
.setType(RuleType.VULNERABILITY)
.setLanguage("java"));
db.rules().insertOrUpdateMetadata(rule1, organization);
db.rules().insertOrUpdateMetadata(rule1);

RuleDefinitionDto rule2 = db.rules().insert(
r -> r.setKey(RuleKey.of("js", "S002"))
.setType(RuleType.SECURITY_HOTSPOT)
.setLanguage("js"));
db.rules().insertOrUpdateMetadata(rule2, organization);
db.rules().insertOrUpdateMetadata(rule2);

assertThat(underTest.selectByTypeAndLanguages(db.getSession(), organization.getUuid(), singletonList(RuleType.VULNERABILITY.getDbConstant()), singletonList("java")))
.extracting(RuleDto::getOrganizationUuid, RuleDto::getUuid, RuleDto::getLanguage, RuleDto::getType)
.containsExactly(tuple(organization.getUuid(), rule1.getUuid(), "java", RuleType.VULNERABILITY.getDbConstant()));
assertThat(underTest.selectByTypeAndLanguages(db.getSession(), singletonList(RuleType.VULNERABILITY.getDbConstant()), singletonList("java")))
.extracting(RuleDto::getUuid, RuleDto::getLanguage, RuleDto::getType)
.containsExactly(tuple(rule1.getUuid(), "java", RuleType.VULNERABILITY.getDbConstant()));

// Rule available also on organization2
assertThat(underTest.selectByTypeAndLanguages(db.getSession(), organization2.getUuid(), singletonList(RuleType.VULNERABILITY.getDbConstant()), singletonList("java")))
.extracting(RuleDto::getOrganizationUuid, RuleDto::getUuid, RuleDto::getLanguage, RuleDto::getType)
.containsExactly(tuple(organization2.getUuid(), rule1.getUuid(), "java", RuleType.VULNERABILITY.getDbConstant()));
assertThat(underTest.selectByTypeAndLanguages(db.getSession(), singletonList(RuleType.SECURITY_HOTSPOT.getDbConstant()), singletonList("js")))
.extracting(RuleDto::getUuid, RuleDto::getLanguage, RuleDto::getType)
.containsExactly(tuple(rule2.getUuid(), "js", RuleType.SECURITY_HOTSPOT.getDbConstant()));

assertThat(underTest.selectByTypeAndLanguages(db.getSession(), organization.getUuid(), singletonList(RuleType.SECURITY_HOTSPOT.getDbConstant()), singletonList("js")))
.extracting(RuleDto::getOrganizationUuid, RuleDto::getUuid, RuleDto::getLanguage, RuleDto::getType)
.containsExactly(tuple(organization.getUuid(), rule2.getUuid(), "js", RuleType.SECURITY_HOTSPOT.getDbConstant()));

// Rule available also on organization2
assertThat(underTest.selectByTypeAndLanguages(db.getSession(), organization2.getUuid(), singletonList(RuleType.SECURITY_HOTSPOT.getDbConstant()), singletonList("js")))
.extracting(RuleDto::getOrganizationUuid, RuleDto::getUuid, RuleDto::getLanguage, RuleDto::getType)
.containsExactly(tuple(organization2.getUuid(), rule2.getUuid(), "js", RuleType.SECURITY_HOTSPOT.getDbConstant()));

assertThat(underTest.selectByTypeAndLanguages(db.getSession(), organization.getUuid(), singletonList(RuleType.SECURITY_HOTSPOT.getDbConstant()), singletonList("java")))
.isEmpty();
assertThat(underTest.selectByTypeAndLanguages(db.getSession(), organization.getUuid(), singletonList(RuleType.VULNERABILITY.getDbConstant()), singletonList("js")))
.isEmpty();
assertThat(underTest.selectByTypeAndLanguages(db.getSession(), singletonList(RuleType.SECURITY_HOTSPOT.getDbConstant()), singletonList("java"))).isEmpty();
assertThat(underTest.selectByTypeAndLanguages(db.getSession(), singletonList(RuleType.VULNERABILITY.getDbConstant()), singletonList("js"))).isEmpty();
}

@Test
public void selectByTypeAndLanguages_return_nothing_when_no_rule_on_languages() {
OrganizationDto organization = db.organizations().insert();

RuleDefinitionDto rule1 = db.rules().insert(
r -> r.setKey(RuleKey.of("java", "S001"))
.setConfigKey("S1")
.setType(RuleType.VULNERABILITY)
.setLanguage("java"));
db.rules().insertOrUpdateMetadata(rule1, organization);
db.rules().insertOrUpdateMetadata(rule1);

RuleDefinitionDto rule2 = db.rules().insert(
r -> r.setKey(RuleKey.of("js", "S002"))
.setType(RuleType.VULNERABILITY)
.setLanguage("js"));
db.rules().insertOrUpdateMetadata(rule2, organization);
db.rules().insertOrUpdateMetadata(rule2);

assertThat(underTest.selectByTypeAndLanguages(db.getSession(), organization.getUuid(), singletonList(RuleType.VULNERABILITY.getDbConstant()), singletonList("cpp")))
assertThat(underTest.selectByTypeAndLanguages(db.getSession(), singletonList(RuleType.VULNERABILITY.getDbConstant()), singletonList("cpp")))
.isEmpty();
}

@Test
public void selectByTypeAndLanguages_return_nothing_when_no_rule_with_type() {
OrganizationDto organization = db.organizations().insert();

RuleDefinitionDto rule1 = db.rules().insert(
r -> r.setKey(RuleKey.of("java", "S001"))
.setConfigKey("S1")
.setType(RuleType.VULNERABILITY)
.setLanguage("java"));
db.rules().insertOrUpdateMetadata(rule1, organization);
db.rules().insertOrUpdateMetadata(rule1);

RuleDefinitionDto rule2 = db.rules().insert(
r -> r.setKey(RuleKey.of("java", "S002"))
.setType(RuleType.SECURITY_HOTSPOT)
.setLanguage("java"));
db.rules().insertOrUpdateMetadata(rule2, organization);
db.rules().insertOrUpdateMetadata(rule2);

RuleDefinitionDto rule3 = db.rules().insert(
r -> r.setKey(RuleKey.of("java", "S003"))
.setType(RuleType.CODE_SMELL)
.setLanguage("java"));
db.rules().insertOrUpdateMetadata(rule3, organization);
db.rules().insertOrUpdateMetadata(rule3);

assertThat(underTest.selectByTypeAndLanguages(db.getSession(), organization.getUuid(), singletonList(RuleType.BUG.getDbConstant()), singletonList("java")))
assertThat(underTest.selectByTypeAndLanguages(db.getSession(), singletonList(RuleType.BUG.getDbConstant()), singletonList("java")))
.isEmpty();
}

@Test
public void selectByTypeAndLanguages_ignores_external_rules() {
OrganizationDto organization = db.organizations().insert();

RuleDefinitionDto rule1 = db.rules().insert(
r -> r.setKey(RuleKey.of("java", "S001"))
.setConfigKey("S1")
.setType(RuleType.VULNERABILITY)
.setIsExternal(true)
.setLanguage("java"));
db.rules().insertOrUpdateMetadata(rule1, organization);
db.rules().insertOrUpdateMetadata(rule1);

assertThat(underTest.selectByTypeAndLanguages(db.getSession(), organization.getUuid(), singletonList(RuleType.VULNERABILITY.getDbConstant()), singletonList("java")))
.extracting(RuleDto::getOrganizationUuid, RuleDto::getUuid, RuleDto::getLanguage, RuleDto::getType)
assertThat(underTest.selectByTypeAndLanguages(db.getSession(), singletonList(RuleType.VULNERABILITY.getDbConstant()), singletonList("java")))
.extracting(RuleDto::getUuid, RuleDto::getLanguage, RuleDto::getType)
.isEmpty();
}

@Test
public void selectByTypeAndLanguages_ignores_template_rules() {
OrganizationDto organization = db.organizations().insert();

RuleDefinitionDto rule1 = db.rules().insert(
r -> r.setKey(RuleKey.of("java", "S001"))
.setConfigKey("S1")
.setType(RuleType.VULNERABILITY)
.setIsTemplate(true)
.setLanguage("java"));
db.rules().insertOrUpdateMetadata(rule1, organization);
db.rules().insertOrUpdateMetadata(rule1);

assertThat(underTest.selectByTypeAndLanguages(db.getSession(), organization.getUuid(), singletonList(RuleType.VULNERABILITY.getDbConstant()), singletonList("java")))
.extracting(RuleDto::getOrganizationUuid, RuleDto::getUuid, RuleDto::getLanguage, RuleDto::getType)
assertThat(underTest.selectByTypeAndLanguages(db.getSession(),singletonList(RuleType.VULNERABILITY.getDbConstant()), singletonList("java")))
.extracting( RuleDto::getUuid, RuleDto::getLanguage, RuleDto::getType)
.isEmpty();
}

@Test
public void select_by_query() {
OrganizationDto organization = db.organizations().insert();
RuleDefinitionDto rule1 = db.rules().insert(r -> r.setKey(RuleKey.of("java", "S001")).setConfigKey("S1"));
db.rules().insertOrUpdateMetadata(rule1, organization);
db.rules().insertOrUpdateMetadata(rule1);
RuleDefinitionDto rule2 = db.rules().insert(r -> r.setKey(RuleKey.of("java", "S002")));
db.rules().insertOrUpdateMetadata(rule2, organization);
db.rules().insertOrUpdateMetadata(rule2);
RuleDefinitionDto removedRule = db.rules().insert(r -> r.setStatus(REMOVED));

assertThat(underTest.selectByQuery(db.getSession(), organization.getUuid(), RuleQuery.create())).hasSize(2);
assertThat(underTest.selectByQuery(db.getSession(), organization.getUuid(), RuleQuery.create().withKey("S001"))).hasSize(1);
assertThat(underTest.selectByQuery(db.getSession(), organization.getUuid(), RuleQuery.create().withConfigKey("S1"))).hasSize(1);
assertThat(underTest.selectByQuery(db.getSession(), organization.getUuid(), RuleQuery.create().withRepositoryKey("java"))).hasSize(2);
assertThat(underTest.selectByQuery(db.getSession(), organization.getUuid(),
assertThat(underTest.selectByQuery(db.getSession(), RuleQuery.create())).hasSize(2);
assertThat(underTest.selectByQuery(db.getSession(), RuleQuery.create().withKey("S001"))).hasSize(1);
assertThat(underTest.selectByQuery(db.getSession(), RuleQuery.create().withConfigKey("S1"))).hasSize(1);
assertThat(underTest.selectByQuery(db.getSession(), RuleQuery.create().withRepositoryKey("java"))).hasSize(2);
assertThat(underTest.selectByQuery(db.getSession(),
RuleQuery.create().withKey("S001").withConfigKey("S1").withRepositoryKey("java"))).hasSize(1);
}

@Test
public void select_by_query_populates_organizationUuid_even_when_organization_has_no_metadata() {
OrganizationDto organization = db.organizations().insert();
db.rules().insert();
db.rules().insert();

assertThat(underTest.selectByQuery(db.getSession(), organization.getUuid(), RuleQuery.create()))
.extracting(RuleDto::getOrganizationUuid)
.containsExactly(organization.getUuid(), organization.getUuid());
}

@Test
public void insert() {
RuleDefinitionDto newRule = new RuleDefinitionDto()
@@ -703,11 +526,9 @@ public class RuleDaoTest {
@Test
public void update_RuleMetadataDto_inserts_row_in_RULE_METADATA_if_not_exists_yet() {
RuleDefinitionDto rule = db.rules().insert();
String organizationUuid = "org-1";

RuleMetadataDto metadataToUpdate = new RuleMetadataDto()
.setRuleUuid(rule.getUuid())
.setOrganizationUuid(organizationUuid)
.setNoteData("My note")
.setNoteUserUuid("admin")
.setNoteCreatedAt(DateUtils.parseDate("2013-12-19").getTime())
@@ -726,8 +547,7 @@ public class RuleDaoTest {
underTest.insertOrUpdate(db.getSession(), metadataToUpdate);
db.getSession().commit();

OrganizationDto organization = OrganizationTesting.newOrganizationDto().setUuid(organizationUuid);
RuleDto ruleDto = underTest.selectOrFailByKey(db.getSession(), organization, rule.getKey());
RuleDto ruleDto = underTest.selectOrFailByKey(db.getSession(), rule.getKey());
assertThat(ruleDto.getNoteData()).isEqualTo("My note");
assertThat(ruleDto.getNoteUserUuid()).isEqualTo("admin");
assertThat(ruleDto.getNoteCreatedAt()).isNotNull();
@@ -755,16 +575,12 @@ public class RuleDaoTest {
@Test
public void update_RuleMetadataDto_updates_row_in_RULE_METADATA_if_already_exists() {
RuleDefinitionDto rule = db.rules().insert();
String organizationUuid = "org-1";
OrganizationDto organization = OrganizationTesting.newOrganizationDto().setUuid(organizationUuid);
RuleMetadataDto metadataV1 = new RuleMetadataDto()
.setRuleUuid(rule.getUuid())
.setOrganizationUuid(organizationUuid)
.setCreatedAt(3_500_000_000_000L)
.setUpdatedAt(4_000_000_000_000L);
RuleMetadataDto metadataV2 = new RuleMetadataDto()
.setRuleUuid(rule.getUuid())
.setOrganizationUuid(organizationUuid)
.setNoteData("My note")
.setNoteUserUuid("admin")
.setNoteCreatedAt(DateUtils.parseDate("2013-12-19").getTime())
@@ -784,7 +600,7 @@ public class RuleDaoTest {
db.commit();

assertThat(db.countRowsOfTable("RULES_METADATA")).isEqualTo(1);
RuleDto ruleDto = underTest.selectOrFailByKey(db.getSession(), organization, rule.getKey());
RuleDto ruleDto = underTest.selectOrFailByKey(db.getSession(), rule.getKey());
assertThat(ruleDto.getNoteData()).isNull();
assertThat(ruleDto.getNoteUserUuid()).isNull();
assertThat(ruleDto.getNoteCreatedAt()).isNull();
@@ -804,7 +620,7 @@ public class RuleDaoTest {
underTest.insertOrUpdate(db.getSession(), metadataV2);
db.commit();

ruleDto = underTest.selectOrFailByKey(db.getSession(), organization, rule.getKey());
ruleDto = underTest.selectOrFailByKey(db.getSession(), rule.getKey());
assertThat(ruleDto.getNoteData()).isEqualTo("My note");
assertThat(ruleDto.getNoteUserUuid()).isEqualTo("admin");
assertThat(ruleDto.getNoteCreatedAt()).isNotNull();
@@ -1057,42 +873,20 @@ public class RuleDaoTest {
assertThat(accumulator.list).isEmpty();
}

@Test
public void scrollIndexingRuleExtensions() {
Accumulator<RuleExtensionForIndexingDto> accumulator = new Accumulator<>();
RuleDefinitionDto r1 = db.rules().insert();
RuleMetadataDto r1Extension = db.rules().insertOrUpdateMetadata(r1, organization, r -> r.setTagsField("t1,t2"));
RuleDefinitionDto r2 = db.rules().insert();
RuleMetadataDto r2Extension = db.rules().insertOrUpdateMetadata(r2, organization, r -> r.setTagsField("t1,t3"));

underTest.scrollIndexingRuleExtensions(db.getSession(), accumulator);

assertThat(accumulator.list)
.extracting(RuleExtensionForIndexingDto::getRuleUuid,
RuleExtensionForIndexingDto::getRuleKey,
RuleExtensionForIndexingDto::getOrganizationUuid, RuleExtensionForIndexingDto::getTags)
.containsExactlyInAnyOrder(
tuple(r1.getUuid(), r1.getKey(), organization.getUuid(), r1Extension.getTagsAsString()),
tuple(r2.getUuid(), r2.getKey(), organization.getUuid(), r2Extension.getTagsAsString()));
}

@Test
public void scrollIndexingRuleExtensionsByIds() {
Accumulator<RuleExtensionForIndexingDto> accumulator = new Accumulator<>();
RuleDefinitionDto r1 = db.rules().insert();
RuleMetadataDto r1Extension = db.rules().insertOrUpdateMetadata(r1, organization, r -> r.setTagsField("t1,t2"));
RuleExtensionId r1ExtensionId = new RuleExtensionId(organization.getUuid(), r1.getUuid());
RuleMetadataDto r1Extension = db.rules().insertOrUpdateMetadata(r1, r -> r.setTagsField("t1,t2"));
RuleDefinitionDto r2 = db.rules().insert();
db.rules().insertOrUpdateMetadata(r2, organization, r -> r.setTagsField("t1,t3"));
db.rules().insertOrUpdateMetadata(r2, r -> r.setTagsField("t1,t3"));

underTest.scrollIndexingRuleExtensionsByIds(db.getSession(), singletonList(r1ExtensionId), accumulator);
underTest.scrollIndexingRuleExtensionsByIds(db.getSession(), singletonList(r1.getUuid()), accumulator);

assertThat(accumulator.list)
.extracting(RuleExtensionForIndexingDto::getRuleUuid,
RuleExtensionForIndexingDto::getRuleKey,
RuleExtensionForIndexingDto::getOrganizationUuid, RuleExtensionForIndexingDto::getTags)
.extracting(RuleExtensionForIndexingDto::getRuleUuid, RuleExtensionForIndexingDto::getRuleKey, RuleExtensionForIndexingDto::getTags)
.containsExactlyInAnyOrder(
tuple(r1.getUuid(), r1.getKey(), organization.getUuid(), r1Extension.getTagsAsString()));
tuple(r1.getUuid(), r1.getKey(), r1Extension.getTagsAsString()));
}

@Test

+ 0
- 1
server/sonar-db-dao/src/test/java/org/sonar/db/webhook/WebhookDaoTest.java 查看文件

@@ -49,7 +49,6 @@ public class WebhookDaoTest {
private final DbSession dbSession = dbTester.getSession();
private final WebhookDao underTest = dbClient.webhookDao();
private final WebhookDbTester webhookDbTester = dbTester.webhooks();
private final WebhookDeliveryDbTester webhookDeliveryDbTester = dbTester.webhookDelivery();
private final ComponentDbTester componentDbTester = dbTester.components();
private final OrganizationDbTester organizationDbTester = dbTester.organizations();


+ 6
- 0
server/sonar-db-dao/src/testFixtures/java/org/sonar/db/component/ComponentDbTester.java 查看文件

@@ -140,6 +140,12 @@ public class ComponentDbTester {
return getProjectDto(componentDto);
}

public ProjectDto insertPublicProjectDto(Consumer<ComponentDto> dtoPopulator) {
ComponentDto componentDto = insertPublicProject(dtoPopulator);
return getProjectDto(componentDto);
}


public final ProjectDto insertPublicProjectDto(OrganizationDto organization, Consumer<ComponentDto> dtoPopulator) {
ComponentDto componentDto = insertPublicProject(organization, dtoPopulator);
return getProjectDto(componentDto);

+ 4
- 0
server/sonar-db-dao/src/testFixtures/java/org/sonar/db/organization/OrganizationDbTester.java 查看文件

@@ -40,6 +40,10 @@ public class OrganizationDbTester {
this.db = db;
}

public OrganizationDto getDefaultOrganization() {
return db.getDefaultOrganization();
}

/**
* Insert an {@link OrganizationDto} and commit the session
*/

+ 9
- 8
server/sonar-db-dao/src/testFixtures/java/org/sonar/db/qualityprofile/QualityProfileDbTester.java 查看文件

@@ -27,7 +27,6 @@ import org.sonar.core.util.Uuids;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.project.ProjectDto;
import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.db.user.GroupDto;
@@ -41,10 +40,12 @@ import static org.sonar.db.qualityprofile.ActiveRuleDto.createFor;
public class QualityProfileDbTester {
private final DbClient dbClient;
private final DbSession dbSession;
private final DbTester dbTester;

public QualityProfileDbTester(DbTester dbTester) {
this.dbClient = dbTester.getDbClient();
this.dbSession = dbTester.getSession();
this.dbTester = dbTester;
}

public Optional<QProfileDto> selectByUuid(String uuid) {
@@ -54,17 +55,17 @@ public class QualityProfileDbTester {
/**
* Create a profile with random field values on the specified organization.
*/
public QProfileDto insert(OrganizationDto organization) {
return insert(organization, c -> {
public QProfileDto insert() {
return insert(c -> {
});
}


/**
* Create a profile with random field values on the specified organization.
* Create a profile with random field values
*/
public QProfileDto insert(OrganizationDto organization, Consumer<QProfileDto> consumer) {
QProfileDto profile = QualityProfileTesting.newQualityProfileDto()
.setOrganizationUuid(organization.getUuid());
public QProfileDto insert(Consumer<QProfileDto> consumer) {
QProfileDto profile = QualityProfileTesting.newQualityProfileDto();
consumer.accept(profile);

dbClient.qualityProfileDao().insert(dbSession, profile);
@@ -107,7 +108,7 @@ public class QualityProfileDbTester {
public QualityProfileDbTester setAsDefault(QProfileDto profile, QProfileDto... others) {
dbClient.defaultQProfileDao().insertOrUpdate(dbSession, DefaultQProfileDto.from(profile));
for (QProfileDto other : others) {
dbClient.defaultQProfileDao().insertOrUpdate(dbSession, DefaultQProfileDto.from(other));
dbClient.defaultQProfileDao().insertOrUpdate(dbSession, DefaultQProfileDto.from( other));
}
dbSession.commit();
return this;

+ 0
- 1
server/sonar-db-dao/src/testFixtures/java/org/sonar/db/qualityprofile/QualityProfileTesting.java 查看文件

@@ -41,7 +41,6 @@ public class QualityProfileTesting {
return new QProfileDto()
.setKee(uuid)
.setRulesProfileUuid(Uuids.createFast())
.setOrganizationUuid(randomAlphanumeric(40))
.setName(uuid)
.setLanguage(randomAlphanumeric(20))
.setLastUsed(nextLong());

+ 8
- 10
server/sonar-db-dao/src/testFixtures/java/org/sonar/db/rule/RuleDbTester.java 查看文件

@@ -129,15 +129,15 @@ public class RuleDbTester {
}

@SafeVarargs
public final RuleMetadataDto insertOrUpdateMetadata(RuleDefinitionDto rule, OrganizationDto organization, Consumer<RuleMetadataDto>... populaters) {
RuleMetadataDto dto = RuleTesting.newRuleMetadata(rule, organization);
public final RuleMetadataDto insertOrUpdateMetadata(RuleDefinitionDto rule, Consumer<RuleMetadataDto>... populaters) {
RuleMetadataDto dto = RuleTesting.newRuleMetadata(rule);
asList(populaters).forEach(populater -> populater.accept(dto));
return insertOrUpdateMetadata(dto);
}

@SafeVarargs
public final RuleMetadataDto insertOrUpdateMetadata(RuleDefinitionDto rule, UserDto noteUser, OrganizationDto organization, Consumer<RuleMetadataDto>... populaters) {
RuleMetadataDto dto = RuleTesting.newRuleMetadata(rule, noteUser, organization);
public final RuleMetadataDto insertOrUpdateMetadata(RuleDefinitionDto rule, UserDto noteUser, Consumer<RuleMetadataDto>... populaters) {
RuleMetadataDto dto = RuleTesting.newRuleMetadata(rule, noteUser);
asList(populaters).forEach(populater -> populater.accept(dto));
return insertOrUpdateMetadata(dto);
}
@@ -169,10 +169,8 @@ public class RuleDbTester {

insert(ruleDto.getDefinition());
RuleMetadataDto metadata = ruleDto.getMetadata();
if (metadata.getOrganizationUuid() != null) {
db.getDbClient().ruleDao().insertOrUpdate(db.getSession(), metadata.setRuleUuid(ruleDto.getUuid()));
db.commit();
}
db.getDbClient().ruleDao().insertOrUpdate(db.getSession(), metadata.setRuleUuid(ruleDto.getUuid()));
db.commit();
return ruleDto;
}

@@ -185,8 +183,8 @@ public class RuleDbTester {
}

@SafeVarargs
public final RuleDto insertRule(OrganizationDto organization, Consumer<RuleDto>... populaters) {
RuleDto ruleDto = newRuleDto(organization);
public final RuleDto insertRule(Consumer<RuleDto>... populaters) {
RuleDto ruleDto = newRuleDto();
asList(populaters).forEach(populater -> populater.accept(ruleDto));
return insertRule(ruleDto);
}

+ 9
- 64
server/sonar-db-dao/src/testFixtures/java/org/sonar/db/rule/RuleTesting.java 查看文件

@@ -95,7 +95,6 @@ public class RuleTesting {
public static RuleMetadataDto newRuleMetadata() {
return new RuleMetadataDto()
.setRuleUuid("uuid_" + randomAlphanumeric(5))
.setOrganizationUuid("org_" + randomAlphanumeric(5))
.setRemediationBaseEffort(nextInt(10) + "h")
.setRemediationGapMultiplier(nextInt(10) + "h")
.setRemediationFunction("LINEAR_OFFSET")
@@ -112,15 +111,13 @@ public class RuleTesting {
.setUpdatedAt(System.currentTimeMillis() - 50);
}

public static RuleMetadataDto newRuleMetadata(RuleDefinitionDto rule, OrganizationDto organization) {
public static RuleMetadataDto newRuleMetadata(RuleDefinitionDto rule) {
return newRuleMetadata()
.setRuleUuid(rule.getUuid())
.setOrganizationUuid(organization.getUuid());
.setRuleUuid(rule.getUuid());
}

public static RuleMetadataDto newRuleMetadata(RuleDefinitionDto rule, UserDto noteUser, OrganizationDto organization) {
return newRuleMetadata(rule, organization)
.setNoteUserUuid(noteUser.getUuid());
public static RuleMetadataDto newRuleMetadata(RuleDefinitionDto rule, UserDto noteUser) {
return newRuleMetadata(rule).setNoteUserUuid(noteUser.getUuid());
}

public static RuleParamDto newRuleParam(RuleDefinitionDto rule) {
@@ -149,14 +146,6 @@ public class RuleTesting {
return newDto(XOO_X1).setLanguage("xoo");
}

/**
* @deprecated use newRule(...)
*/
@Deprecated
public static RuleDto newXooX1(OrganizationDto organization) {
return newDto(XOO_X1, requireNonNull(organization, "organization can't be null")).setLanguage("xoo");
}

/**
* @deprecated use newRule(...)
*/
@@ -165,14 +154,6 @@ public class RuleTesting {
return newDto(XOO_X2).setLanguage("xoo");
}

/**
* @deprecated use newRule(...)
*/
@Deprecated
public static RuleDto newXooX2(OrganizationDto organization) {
return newDto(XOO_X2, requireNonNull(organization, "organization can't be null")).setLanguage("xoo");
}

/**
* @deprecated use newRule(...)
*/
@@ -181,27 +162,11 @@ public class RuleTesting {
return newDto(XOO_X3).setLanguage("xoo");
}

/**
* @deprecated use newRule(...)
*/
@Deprecated
public static RuleDto newXooX3(OrganizationDto organization) {
return newDto(XOO_X3, requireNonNull(organization, "organization can't be null")).setLanguage("xoo");
}

/**
* @deprecated use newRule(...)
*/
@Deprecated
public static RuleDto newDto(RuleKey ruleKey) {
return newDto(ruleKey, null);
}

/**
* @deprecated use newRule(...)
*/
@Deprecated
public static RuleDto newDto(RuleKey ruleKey, @Nullable OrganizationDto organization) {
RuleDto res = new RuleDto()
.setUuid("uuid_" + Uuids.createFast())
.setRuleKey(ruleKey.rule())
@@ -222,14 +187,11 @@ public class RuleTesting {
.setType(RuleType.CODE_SMELL)
.setCreatedAt(new Date().getTime())
.setUpdatedAt(new Date().getTime())
.setScope(Scope.MAIN);
if (organization != null) {
res
.setOrganizationUuid(organization.getUuid())
.setTags(ImmutableSet.of("tag1", "tag2"))
.setRemediationFunction("LINEAR")
.setRemediationGapMultiplier("1h");
}
.setScope(Scope.MAIN)
.setTags(ImmutableSet.of("tag1", "tag2"))
.setRemediationFunction("LINEAR")
.setRemediationGapMultiplier("1h");

return res;
}

@@ -241,24 +203,11 @@ public class RuleTesting {
return newDto(RuleKey.of(randomAlphanumeric(30), randomAlphanumeric(30)));
}

/**
* @deprecated use newRule(...)
*/
@Deprecated
public static RuleDto newRuleDto(OrganizationDto organization) {
return newDto(RuleKey.of(randomAlphanumeric(30), randomAlphanumeric(30)), organization);
}

public static RuleDto newTemplateRule(RuleKey ruleKey) {
return newDto(ruleKey)
.setIsTemplate(true);
}

public static RuleDto newTemplateRule(RuleKey ruleKey, OrganizationDto organization) {
return newDto(ruleKey, organization)
.setIsTemplate(true);
}

/**
* @deprecated use {@link #newCustomRule(RuleDefinitionDto)}
*/
@@ -343,10 +292,6 @@ public class RuleTesting {
return rule -> rule.setSystemTags(copyOf(tags));
}

public static Consumer<RuleMetadataDto> setOrganization(OrganizationDto organization) {
return rule -> rule.setOrganizationUuid(organization.getUuid());
}

public static Consumer<RuleMetadataDto> setTags(String... tags) {
return rule -> rule.setTags(copyOf(tags));
}

+ 5
- 0
server/sonar-db-dao/src/testFixtures/java/org/sonar/db/user/UserDbTester.java 查看文件

@@ -146,6 +146,11 @@ public class UserDbTester {
return insertGroup(group);
}

public GroupDto insertGroup(String name) {
GroupDto group = GroupTesting.newGroupDto().setName(name).setOrganizationUuid(db.getDefaultOrganization().getUuid());
return insertGroup(group);
}

/**
* Create group in default organization
*/

+ 36
- 0
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v85/AddPrimaryKeyToDefaultQProfiles.java 查看文件

@@ -0,0 +1,36 @@
/*
* SonarQube
* Copyright (C) 2009-2020 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.server.platform.db.migration.version.v85;

import java.sql.SQLException;
import org.sonar.db.Database;
import org.sonar.server.platform.db.migration.step.DdlChange;
import org.sonar.server.platform.db.migration.version.v84.util.AddPrimaryKeyBuilder;

public class AddPrimaryKeyToDefaultQProfiles extends DdlChange {
public AddPrimaryKeyToDefaultQProfiles(Database db) {
super(db);
}

@Override
public void execute(Context context) throws SQLException {
context.execute(new AddPrimaryKeyBuilder("default_qprofiles", "language").build());
}
}

+ 5
- 1
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v85/DbVersion85.java 查看文件

@@ -55,7 +55,11 @@ public class DbVersion85 implements DbVersion {
.add(4024, "Populate 'branch_type' in 'project_branches'", FillProjectBranchesBranchType.class)
.add(4025, "Make 'branch_type' in 'project_branches' not nullable", MakeProjectBranchesBranchTypeNotNullable.class)
.add(4026, "Drop column 'key_type' in table 'project_branches'", DropProjectBranchesKeyType.class)

.add(4027, "Drop organization_uuid from 'quality_profile' table", DropOrganizationFromQualityProfileTable.class)
.add(4028, "Drop primary key of table 'default_qprofiles'", DropDefaultQProfilesPk.class)
.add(4029, "Drop organization_uuid from 'default_qprofiles' table", DropOrganizationFromDefaultQProfiles.class)
.add(4030, "Add primary key to the table 'default_qprofiles", AddPrimaryKeyToDefaultQProfiles.class)
.add(4031, "Drop 'organization_uuid' in 'rules_metadata'", DropOrganizationInRulesMetadata.class)
;
}
}

+ 36
- 0
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v85/DropDefaultQProfilesPk.java 查看文件

@@ -0,0 +1,36 @@
/*
* SonarQube
* Copyright (C) 2009-2020 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.server.platform.db.migration.version.v85;

import java.sql.SQLException;
import org.sonar.db.Database;
import org.sonar.server.platform.db.migration.sql.DropConstraintBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;

public class DropDefaultQProfilesPk extends DdlChange {
public DropDefaultQProfilesPk(Database db) {
super(db);
}

@Override
public void execute(Context context) throws SQLException {
context.execute(new DropConstraintBuilder(getDialect()).setName("pk_default_qprofiles").setTable("default_qprofiles").build());
}
}

+ 36
- 0
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v85/DropOrganizationFromDefaultQProfiles.java 查看文件

@@ -0,0 +1,36 @@
/*
* SonarQube
* Copyright (C) 2009-2020 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.server.platform.db.migration.version.v85;

import java.sql.SQLException;
import org.sonar.db.Database;
import org.sonar.server.platform.db.migration.sql.DropColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;

public class DropOrganizationFromDefaultQProfiles extends DdlChange {
public DropOrganizationFromDefaultQProfiles(Database db) {
super(db);
}

@Override
public void execute(Context context) throws SQLException {
context.execute(new DropColumnsBuilder(getDialect(), "default_qprofiles", "organization_uuid").build());
}
}

+ 37
- 0
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v85/DropOrganizationFromQualityProfileTable.java 查看文件

@@ -0,0 +1,37 @@
/*
* SonarQube
* Copyright (C) 2009-2020 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.server.platform.db.migration.version.v85;

import java.sql.SQLException;
import org.sonar.db.Database;
import org.sonar.server.platform.db.migration.sql.DropColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;

public class DropOrganizationFromQualityProfileTable extends DdlChange {

public DropOrganizationFromQualityProfileTable(Database db) {
super(db);
}

@Override
public void execute(Context context) throws SQLException {
context.execute(new DropColumnsBuilder(getDialect(), "org_qprofiles", "organization_uuid").build());
}
}

+ 42
- 0
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v85/DropOrganizationInRulesMetadata.java 查看文件

@@ -0,0 +1,42 @@
/*
* SonarQube
* Copyright (C) 2009-2020 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.server.platform.db.migration.version.v85;

import java.sql.SQLException;
import org.sonar.db.Database;
import org.sonar.server.platform.db.migration.sql.DropColumnsBuilder;
import org.sonar.server.platform.db.migration.sql.DropConstraintBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
import org.sonar.server.platform.db.migration.version.v84.util.AddPrimaryKeyBuilder;

public class DropOrganizationInRulesMetadata extends DdlChange {
private static final String TABLE_NAME = "rules_metadata";

public DropOrganizationInRulesMetadata(Database db) {
super(db);
}

@Override
public void execute(Context context) throws SQLException {
context.execute(new DropConstraintBuilder(getDialect()).setName("pk_rules_metadata").setTable(TABLE_NAME).build());
context.execute(new DropColumnsBuilder(getDialect(), TABLE_NAME, "organization_uuid").build());
context.execute(new AddPrimaryKeyBuilder(TABLE_NAME, "rule_uuid").build());
}
}

+ 40
- 0
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v85/AddPrimaryKeyToDefaultQProfilesTest.java 查看文件

@@ -0,0 +1,40 @@
/*
* SonarQube
* Copyright (C) 2009-2020 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.server.platform.db.migration.version.v85;

import java.sql.SQLException;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.db.CoreDbTester;
import org.sonar.server.platform.db.migration.step.MigrationStep;

public class AddPrimaryKeyToDefaultQProfilesTest {
@Rule
public CoreDbTester db = CoreDbTester.createForSchema(AddPrimaryKeyToDefaultQProfilesTest.class, "schema.sql");

private MigrationStep underTest = new AddPrimaryKeyToDefaultQProfiles(db.database());

@Test
public void execute() throws SQLException {
db.assertNoPrimaryKey("default_qprofiles");
underTest.execute();
db.assertPrimaryKey("default_qprofiles", "pk_default_qprofiles", "language");
}
}

+ 41
- 0
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v85/DropDefaultQProfilesPkTest.java 查看文件

@@ -0,0 +1,41 @@
/*
* SonarQube
* Copyright (C) 2009-2020 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.server.platform.db.migration.version.v85;

import java.sql.SQLException;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.db.CoreDbTester;
import org.sonar.server.platform.db.migration.step.MigrationStep;

public class DropDefaultQProfilesPkTest {
@Rule
public CoreDbTester db = CoreDbTester.createForSchema(DropDefaultQProfilesPkTest.class, "schema.sql");

private MigrationStep underTest = new DropDefaultQProfilesPk(db.database());

@Test
public void execute() throws SQLException {
db.assertPrimaryKey("default_qprofiles", "pk_default_qprofiles", "organization_uuid", "language");

underTest.execute();
db.assertNoPrimaryKey("default_qprofiles");
}
}

+ 41
- 0
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v85/DropOrganizationFromDefaultQProfilesTest.java 查看文件

@@ -0,0 +1,41 @@
/*
* SonarQube
* Copyright (C) 2009-2020 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.server.platform.db.migration.version.v85;

import java.sql.SQLException;
import java.sql.Types;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.db.CoreDbTester;
import org.sonar.server.platform.db.migration.step.MigrationStep;

public class DropOrganizationFromDefaultQProfilesTest {
@Rule
public CoreDbTester db = CoreDbTester.createForSchema(DropOrganizationFromDefaultQProfilesTest.class, "schema.sql");

private MigrationStep underTest = new DropOrganizationFromDefaultQProfiles(db.database());

@Test
public void execute() throws SQLException {
db.assertColumnDefinition("default_qprofiles", "organization_uuid", Types.VARCHAR, 40, false);
underTest.execute();
db.assertColumnDoesNotExist("default_qprofiles", "organization_uuid");
}
}

+ 40
- 0
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v85/DropOrganizationFromQualityProfileTableTest.java 查看文件

@@ -0,0 +1,40 @@
/*
* SonarQube
* Copyright (C) 2009-2020 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.server.platform.db.migration.version.v85;

import java.sql.SQLException;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.db.CoreDbTester;

public class DropOrganizationFromQualityProfileTableTest {

@Rule
public CoreDbTester dbTester = CoreDbTester.createForSchema(DropOrganizationFromQualityProfileTableTest.class, "schema.sql");

private DropOrganizationFromQualityProfileTable underTest = new DropOrganizationFromQualityProfileTable(dbTester.database());

@Test
public void column_has_been_dropped() throws SQLException {
underTest.execute();
dbTester.assertColumnDoesNotExist("org_qprofiles", "organization_uuid");
}

}

+ 40
- 0
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v85/DropOrganizationInRulesMetadataTest.java 查看文件

@@ -0,0 +1,40 @@
/*
* SonarQube
* Copyright (C) 2009-2020 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.server.platform.db.migration.version.v85;

import java.sql.SQLException;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.db.CoreDbTester;
import org.sonar.server.platform.db.migration.step.MigrationStep;

public class DropOrganizationInRulesMetadataTest {
@Rule
public CoreDbTester dbTester = CoreDbTester.createForSchema(DropOrganizationInRulesMetadataTest.class, "schema.sql");

private MigrationStep underTest = new DropOrganizationInRulesMetadata(dbTester.database());

@Test
public void column_has_been_dropped() throws SQLException {
underTest.execute();
dbTester.assertColumnDoesNotExist("rules_metadata", "organization_uuid");
dbTester.assertPrimaryKey("rules_metadata", "pk_rules_metadata", "rule_uuid");
}
}

+ 7
- 0
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v85/AddPrimaryKeyToDefaultQProfilesTest/schema.sql 查看文件

@@ -0,0 +1,7 @@
CREATE TABLE "DEFAULT_QPROFILES"(
"LANGUAGE" VARCHAR(20) NOT NULL,
"QPROFILE_UUID" VARCHAR(255) NOT NULL,
"CREATED_AT" BIGINT NOT NULL,
"UPDATED_AT" BIGINT NOT NULL
);
CREATE UNIQUE INDEX "UNIQ_DEFAULT_QPROFILES_UUID" ON "DEFAULT_QPROFILES"("QPROFILE_UUID");

+ 9
- 0
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v85/DropDefaultQProfilesPkTest/schema.sql 查看文件

@@ -0,0 +1,9 @@
CREATE TABLE "DEFAULT_QPROFILES"(
"ORGANIZATION_UUID" VARCHAR(40) NOT NULL,
"LANGUAGE" VARCHAR(20) NOT NULL,
"QPROFILE_UUID" VARCHAR(255) NOT NULL,
"CREATED_AT" BIGINT NOT NULL,
"UPDATED_AT" BIGINT NOT NULL
);
ALTER TABLE "DEFAULT_QPROFILES" ADD CONSTRAINT "PK_DEFAULT_QPROFILES" PRIMARY KEY("ORGANIZATION_UUID", "LANGUAGE");
CREATE UNIQUE INDEX "UNIQ_DEFAULT_QPROFILES_UUID" ON "DEFAULT_QPROFILES"("QPROFILE_UUID");

+ 8
- 0
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v85/DropOrganizationFromDefaultQProfilesTest/schema.sql 查看文件

@@ -0,0 +1,8 @@
CREATE TABLE "DEFAULT_QPROFILES"(
"ORGANIZATION_UUID" VARCHAR(40) NOT NULL,
"LANGUAGE" VARCHAR(20) NOT NULL,
"QPROFILE_UUID" VARCHAR(255) NOT NULL,
"CREATED_AT" BIGINT NOT NULL,
"UPDATED_AT" BIGINT NOT NULL
);
CREATE UNIQUE INDEX "UNIQ_DEFAULT_QPROFILES_UUID" ON "DEFAULT_QPROFILES"("QPROFILE_UUID");

+ 14
- 0
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v85/DropOrganizationFromQualityProfileTableTest/schema.sql 查看文件

@@ -0,0 +1,14 @@
CREATE TABLE "ORG_QPROFILES"(
"UUID" VARCHAR(255) NOT NULL,
"ORGANIZATION_UUID" VARCHAR(40) NOT NULL,
"RULES_PROFILE_UUID" VARCHAR(255) NOT NULL,
"PARENT_UUID" VARCHAR(255),
"LAST_USED" BIGINT,
"USER_UPDATED_AT" BIGINT,
"CREATED_AT" BIGINT NOT NULL,
"UPDATED_AT" BIGINT NOT NULL
);
ALTER TABLE "ORG_QPROFILES" ADD CONSTRAINT "PK_ORG_QPROFILES" PRIMARY KEY("UUID");
CREATE INDEX "QPROFILES_ORG_UUID" ON "ORG_QPROFILES"("ORGANIZATION_UUID");
CREATE INDEX "QPROFILES_RP_UUID" ON "ORG_QPROFILES"("RULES_PROFILE_UUID");
CREATE INDEX "ORG_QPROFILES_PARENT_UUID" ON "ORG_QPROFILES"("PARENT_UUID");

+ 19
- 0
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v85/DropOrganizationInRulesMetadataTest/schema.sql 查看文件

@@ -0,0 +1,19 @@
CREATE TABLE "RULES_METADATA"(
"ORGANIZATION_UUID" VARCHAR(40) NOT NULL,
"NOTE_DATA" CLOB,
"NOTE_USER_UUID" VARCHAR(255),
"NOTE_CREATED_AT" BIGINT,
"NOTE_UPDATED_AT" BIGINT,
"REMEDIATION_FUNCTION" VARCHAR(20),
"REMEDIATION_GAP_MULT" VARCHAR(20),
"REMEDIATION_BASE_EFFORT" VARCHAR(20),
"TAGS" VARCHAR(4000),
"AD_HOC_NAME" VARCHAR(200),
"AD_HOC_DESCRIPTION" CLOB,
"AD_HOC_SEVERITY" VARCHAR(10),
"AD_HOC_TYPE" TINYINT,
"CREATED_AT" BIGINT NOT NULL,
"UPDATED_AT" BIGINT NOT NULL,
"RULE_UUID" VARCHAR(40) NOT NULL
);
ALTER TABLE "RULES_METADATA" ADD CONSTRAINT "PK_RULES_METADATA" PRIMARY KEY("RULE_UUID", "ORGANIZATION_UUID");

+ 3
- 11
server/sonar-server-common/src/main/java/org/sonar/server/es/BulkIndexer.java 查看文件

@@ -26,6 +26,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
@@ -288,21 +289,12 @@ public class BulkIndexer {
return false;
}
BulkRequestKey that = (BulkRequestKey) o;
if (!docType.equals(that.docType)) {
return false;
}
if (!index.equals(that.index)) {
return false;
}
return requestType.equals(that.requestType);
return Objects.equals(docType, that.docType) && Objects.equals(index, that.index) && Objects.equals(requestType, that.requestType);
}

@Override
public int hashCode() {
int result = requestType.hashCode();
result = 31 * result + index.hashCode();
result = 31 * result + docType.hashCode();
return result;
return Objects.hash(requestType, index, docType);
}

@Override

+ 2
- 1
server/sonar-server-common/src/main/java/org/sonar/server/es/EsClient.java 查看文件

@@ -126,7 +126,8 @@ public class EsClient implements Closeable {
return new ProxySearchRequestBuilder(nativeClient()).setIndices(index.getName());
}

public SearchRequestBuilder prepareSearch(IndexMainType indexType) {
public SearchRequestBuilder
prepareSearch(IndexMainType indexType) {
return new ProxySearchRequestBuilder(nativeClient())
.setIndices(indexType.getIndex().getName())
.setTypes(indexType.getType());

+ 1
- 1
server/sonar-server-common/src/main/java/org/sonar/server/organization/DefaultOrganizationProviderImpl.java 查看文件

@@ -44,7 +44,7 @@ public class DefaultOrganizationProviderImpl implements DefaultOrganizationProvi
return cache;
}

private static DefaultOrganization getDefaultOrganization(DbClient dbClient) {
public static DefaultOrganization getDefaultOrganization(DbClient dbClient) {
try (DbSession dbSession = dbClient.openSession(false)) {
Optional<String> uuid = dbClient.internalPropertiesDao().selectByKey(dbSession, InternalProperties.DEFAULT_ORGANIZATION);
checkState(uuid.isPresent() && !uuid.get().isEmpty(), "No Default organization uuid configured");

+ 4
- 9
server/sonar-server-common/src/main/java/org/sonar/server/rule/DefaultRuleFinder.java 查看文件

@@ -54,12 +54,10 @@ public class DefaultRuleFinder implements ServerRuleFinder {

private final DbClient dbClient;
private final RuleDao ruleDao;
private final DefaultOrganizationProvider defaultOrganizationProvider;

public DefaultRuleFinder(DbClient dbClient, DefaultOrganizationProvider defaultOrganizationProvider) {
public DefaultRuleFinder(DbClient dbClient) {
this.dbClient = dbClient;
this.ruleDao = dbClient.ruleDao();
this.defaultOrganizationProvider = defaultOrganizationProvider;
}

@Override
@@ -78,10 +76,7 @@ public class DefaultRuleFinder implements ServerRuleFinder {
@CheckForNull
public org.sonar.api.rules.Rule findByKey(RuleKey key) {
try (DbSession dbSession = dbClient.openSession(false)) {
String defaultOrganizationUuid = defaultOrganizationProvider.get().getUuid();
OrganizationDto defaultOrganization = dbClient.organizationDao().selectByUuid(dbSession, defaultOrganizationUuid)
.orElseThrow(() -> new IllegalStateException(String.format("Cannot find default organization '%s'", defaultOrganizationUuid)));
Optional<RuleDto> rule = ruleDao.selectByKey(dbSession, defaultOrganization.getUuid(), key);
Optional<RuleDto> rule = ruleDao.selectByKey(dbSession, key);
if (rule.isPresent() && rule.get().getStatus() != RuleStatus.REMOVED) {
return toRule(rule.get(), ruleDao.selectRuleParamsByRuleKey(dbSession, rule.get().getKey()));
} else {
@@ -99,7 +94,7 @@ public class DefaultRuleFinder implements ServerRuleFinder {
@Override
public final org.sonar.api.rules.Rule find(org.sonar.api.rules.RuleQuery query) {
try (DbSession dbSession = dbClient.openSession(false)) {
List<RuleDto> rules = ruleDao.selectByQuery(dbSession, defaultOrganizationProvider.get().getUuid(), query);
List<RuleDto> rules = ruleDao.selectByQuery(dbSession, query);
if (!rules.isEmpty()) {
RuleDto rule = rules.get(0);
return toRule(rule, ruleDao.selectRuleParamsByRuleKey(dbSession, rule.getKey()));
@@ -111,7 +106,7 @@ public class DefaultRuleFinder implements ServerRuleFinder {
@Override
public final Collection<org.sonar.api.rules.Rule> findAll(org.sonar.api.rules.RuleQuery query) {
try (DbSession dbSession = dbClient.openSession(false)) {
List<RuleDto> rules = ruleDao.selectByQuery(dbSession, defaultOrganizationProvider.get().getUuid(), query);
List<RuleDto> rules = ruleDao.selectByQuery(dbSession, query);
if (rules.isEmpty()) {
return Collections.emptyList();
}

+ 12
- 0
server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleDoc.java 查看文件

@@ -21,10 +21,12 @@ package org.sonar.server.rule.index;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
@@ -196,6 +198,15 @@ public class RuleDoc extends BaseDoc {
return this;
}

public Set<String> getTags() {
return getField(RuleIndexDefinition.FIELD_RULE_TAGS);
}

public RuleDoc setTags(Set<String> tags) {
setField(RuleIndexDefinition.FIELD_RULE_TAGS, tags);
return this;
}

@CheckForNull
public RuleStatus status() {
return RuleStatus.valueOf(getField(RuleIndexDefinition.FIELD_RULE_STATUS));
@@ -287,6 +298,7 @@ public class RuleDoc extends BaseDoc {
.setStatus(dto.getStatus().toString())
.setType(dto.getTypeAsRuleType())
.setCreatedAt(dto.getCreatedAt())
.setTags(Sets.union(dto.getTags(), dto.getSystemTags()))
.setUpdatedAt(dto.getUpdatedAt());

if (dto.getTemplateRuleKey() != null && dto.getTemplateRepository() != null) {

+ 0
- 102
server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleExtensionDoc.java 查看文件

@@ -1,102 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2020 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.server.rule.index;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.sonar.db.rule.RuleExtensionForIndexingDto;
import org.sonar.db.rule.RuleForIndexingDto;
import org.sonar.server.es.BaseDoc;

import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_RULE_EXTENSION;

public class RuleExtensionDoc extends BaseDoc {

public RuleExtensionDoc(Map<String, Object> fields) {
super(TYPE_RULE_EXTENSION, fields);
}

public RuleExtensionDoc() {
super(TYPE_RULE_EXTENSION, new HashMap<>(4));
}

@Override
public String getId() {
return idOf(getRuleUuid(), getScope());
}

public String getRuleUuid() {
return ruleUuidAsString();
}

private String ruleUuidAsString() {
return getField(RuleIndexDefinition.FIELD_RULE_UUID);
}

public RuleExtensionDoc setRuleUuid(String ruleUuid) {
String parent = ruleUuid;
setField(RuleIndexDefinition.FIELD_RULE_UUID, parent);
setParent(parent);
return this;
}

public RuleExtensionScope getScope() {
return RuleExtensionScope.parse(getField(RuleIndexDefinition.FIELD_RULE_EXTENSION_SCOPE));
}

public RuleExtensionDoc setScope(RuleExtensionScope scope) {
setField(RuleIndexDefinition.FIELD_RULE_EXTENSION_SCOPE, scope.getScope());
return this;
}

public Set<String> getTags() {
return getField(RuleIndexDefinition.FIELD_RULE_EXTENSION_TAGS);
}

public RuleExtensionDoc setTags(Set<String> tags) {
setField(RuleIndexDefinition.FIELD_RULE_EXTENSION_TAGS, tags);
return this;
}

public static RuleExtensionDoc of(RuleForIndexingDto rule) {
return new RuleExtensionDoc()
.setRuleUuid(rule.getUuid())
.setScope(RuleExtensionScope.system())
.setTags(rule.getSystemTags());
}

public static RuleExtensionDoc of(RuleExtensionForIndexingDto rule) {
return new RuleExtensionDoc()
.setRuleUuid(rule.getRuleUuid())
.setScope(RuleExtensionScope.organization(rule.getOrganizationUuid()))
.setTags(rule.getTagsAsSet());
}

public static String idOf(String ruleUuid, RuleExtensionScope scope) {
return ruleUuid + "|" + scope.getScope();
}

@Override
public String toString() {
return ReflectionToStringBuilder.toString(this);
}
}

+ 0
- 61
server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleExtensionScope.java 查看文件

@@ -1,61 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2020 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.server.rule.index;

import java.util.Optional;
import javax.annotation.Nullable;
import org.sonar.db.organization.OrganizationDto;

import static com.google.common.base.Preconditions.checkArgument;

public class RuleExtensionScope {

private static final String FAKE_UUID_FOR_SYSTEM = "system";

private final Optional<String> organizationUuid;

private RuleExtensionScope(@Nullable String organizationUuid) {
this.organizationUuid = Optional.ofNullable(organizationUuid);
}

public static RuleExtensionScope system() {
return new RuleExtensionScope(null);
}

public static RuleExtensionScope organization(OrganizationDto organization) {
return organization(organization.getUuid());
}

public static RuleExtensionScope organization(String organizationUuid) {
checkArgument(!FAKE_UUID_FOR_SYSTEM.equals(organizationUuid), "The organization uuid '%s' is reserved for to store system tags in the rules index.", FAKE_UUID_FOR_SYSTEM);
return new RuleExtensionScope(organizationUuid);
}

public String getScope() {
return organizationUuid.orElse(FAKE_UUID_FOR_SYSTEM);
}

public static RuleExtensionScope parse(String scope) {
if (FAKE_UUID_FOR_SYSTEM.equals(scope)) {
return system();
}
return new RuleExtensionScope(scope);
}
}

+ 20
- 55
server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndex.java 查看文件

@@ -20,7 +20,6 @@
package org.sonar.server.rule.index;

import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -39,14 +38,12 @@ import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.Operator;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermsQueryBuilder;
import org.elasticsearch.join.aggregations.JoinAggregationBuilders;
import org.elasticsearch.join.query.HasParentQueryBuilder;
import org.elasticsearch.join.query.JoinQueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.BucketOrder;
import org.elasticsearch.search.aggregations.bucket.filter.FilterAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.terms.IncludeExclude;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
@@ -57,7 +54,6 @@ import org.sonar.api.rule.Severity;
import org.sonar.api.rules.RuleType;
import org.sonar.api.utils.System2;
import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.qualityprofile.QProfileDto;
import org.sonar.server.es.EsClient;
import org.sonar.server.es.EsUtils;
@@ -93,8 +89,6 @@ import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_SEVERITY;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_CREATED_AT;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_CWE;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_EXTENSION_SCOPE;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_EXTENSION_TAGS;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_HTML_DESCRIPTION;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_INTERNAL_KEY;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_IS_EXTERNAL;
@@ -109,12 +103,12 @@ import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_SANS_TO
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_SEVERITY;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_SONARSOURCE_SECURITY;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_STATUS;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_TAGS;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_TEMPLATE_KEY;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_TYPE;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_UPDATED_AT;
import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_ACTIVE_RULE;
import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_RULE;
import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_RULE_EXTENSION;

/**
* The unique entry-point to interact with Elasticsearch index "rules".
@@ -153,8 +147,7 @@ public class RuleIndex {
}

public SearchIdResult<String> search(RuleQuery query, SearchOptions options) {
SearchRequestBuilder esSearch = client
.prepareSearch(TYPE_RULE);
SearchRequestBuilder esSearch = client.prepareSearch(TYPE_RULE);

QueryBuilder qb = buildQuery(query);
Map<String, QueryBuilder> filters = buildFilters(query);
@@ -216,13 +209,13 @@ public class RuleIndex {
BoolQueryBuilder textQuery = boolQuery();
JavaTokenizer.split(queryString)
.stream().map(token -> boolQuery().should(
matchQuery(
SEARCH_GRAMS_ANALYZER.subField(FIELD_RULE_NAME),
StringUtils.left(token, DefaultIndexSettings.MAXIMUM_NGRAM_LENGTH)).boost(20f))
.should(
matchPhraseQuery(
ENGLISH_HTML_ANALYZER.subField(FIELD_RULE_HTML_DESCRIPTION),
token).boost(3f)))
matchQuery(
SEARCH_GRAMS_ANALYZER.subField(FIELD_RULE_NAME),
StringUtils.left(token, DefaultIndexSettings.MAXIMUM_NGRAM_LENGTH)).boost(20f))
.should(
matchPhraseQuery(
ENGLISH_HTML_ANALYZER.subField(FIELD_RULE_HTML_DESCRIPTION),
token).boost(3f)))
.forEach(textQuery::must);
qb.should(textQuery.boost(20f));
}
@@ -316,8 +309,7 @@ public class RuleIndex {
}

if (isNotEmpty(query.getTags())) {
filters.put(FIELD_RULE_EXTENSION_TAGS,
buildTagsFilter(query.getTags(), query.getOrganization()));
filters.put(FIELD_RULE_TAGS, buildTagsFilter(query.getTags()));
}

Collection<RuleType> types = query.getTypes();
@@ -387,14 +379,11 @@ public class RuleIndex {
return filters;
}

private static BoolQueryBuilder buildTagsFilter(Collection<String> tags, OrganizationDto organization) {
private static BoolQueryBuilder buildTagsFilter(Collection<String> tags) {
BoolQueryBuilder q = boolQuery();
tags.stream()
.map(tag -> boolQuery()
.filter(QueryBuilders.termQuery(FIELD_RULE_EXTENSION_TAGS, tag))
.filter(termsQuery(FIELD_RULE_EXTENSION_SCOPE, RuleExtensionScope.system().getScope(), RuleExtensionScope.organization(organization).getScope())))
.map(childQuery -> JoinQueryBuilders.hasChildQuery(TYPE_RULE_EXTENSION.getName(), childQuery, ScoreMode.None))
.forEach(q::should);
for (String tag : tags) {
q.should(boolQuery().filter(QueryBuilders.termQuery(FIELD_RULE_TAGS, tag)));
}
return q;
}

@@ -460,23 +449,8 @@ public class RuleIndex {
}
if (options.getFacets().contains(FACET_TAGS) || options.getFacets().contains(FACET_OLD_DEFAULT)) {
Collection<String> tags = query.getTags();
checkArgument(query.getOrganization() != null, "Cannot use tags facet, if no organization is specified.", query.getTags());

Function<TermsAggregationBuilder, AggregationBuilder> childFeature = termsAggregation -> {

FilterAggregationBuilder scopeAggregation = AggregationBuilders.filter(
"scope_filter_for_" + FACET_TAGS,
termsQuery(FIELD_RULE_EXTENSION_SCOPE,
RuleExtensionScope.system().getScope(),
RuleExtensionScope.organization(query.getOrganization()).getScope()))
.subAggregation(termsAggregation);

return JoinAggregationBuilders.children("children_for_" + termsAggregation.getName(), TYPE_RULE_EXTENSION.getName())
.subAggregation(scopeAggregation);
};

aggregations.put(FACET_TAGS,
stickyFacetBuilder.buildStickyFacet(FIELD_RULE_EXTENSION_TAGS, FACET_TAGS, MAX_FACET_SIZE, childFeature,
stickyFacetBuilder.buildStickyFacet(FIELD_RULE_TAGS, FACET_TAGS, MAX_FACET_SIZE,
(tags == null) ? (new String[0]) : tags.toArray()));
}
if (options.getFacets().contains(FACET_TYPES)) {
@@ -619,24 +593,15 @@ public class RuleIndex {
esSearch.setSize(options.getLimit());
}

public List<String> listTags(@Nullable OrganizationDto organization, @Nullable String query, int size) {
public List<String> listTags(@Nullable String query, int size) {
int maxPageSize = 500;
checkArgument(size <= maxPageSize, "Page size must be lower than or equals to " + maxPageSize);
if (size <= 0) {
return emptyList();
}

ImmutableList.Builder<String> scopes = ImmutableList.<String>builder()
.add(RuleExtensionScope.system().getScope());
if (organization != null) {
scopes.add(RuleExtensionScope.organization(organization).getScope());
}
TermsQueryBuilder scopeFilter = QueryBuilders.termsQuery(
FIELD_RULE_EXTENSION_SCOPE,
scopes.build().toArray(new String[0]));

TermsAggregationBuilder termsAggregation = AggregationBuilders.terms(AGGREGATION_NAME_FOR_TAGS)
.field(FIELD_RULE_EXTENSION_TAGS)
.field(FIELD_RULE_TAGS)
.size(size)
.order(BucketOrder.key(true))
.minDocCount(1);
@@ -647,8 +612,8 @@ public class RuleIndex {
.ifPresent(termsAggregation::includeExclude);

SearchRequestBuilder request = client
.prepareSearch(TYPE_RULE_EXTENSION.getMainType())
.setQuery(boolQuery().filter(scopeFilter))
.prepareSearch(TYPE_RULE.getMainType())
.setQuery(matchAllQuery())
.setSize(0)
.addAggregation(termsAggregation);

@@ -656,7 +621,7 @@ public class RuleIndex {
return EsUtils.termsKeys(esResponse.getAggregations().get(AGGREGATION_NAME_FOR_TAGS));
}

private static boolean isNotEmpty(@Nullable Collection list) {
private static boolean isNotEmpty(@Nullable Collection<?> list) {
return list != null && !list.isEmpty();
}
}

+ 2
- 13
server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndexDefinition.java 查看文件

@@ -64,6 +64,7 @@ public class RuleIndexDefinition implements IndexDefinition {
public static final String FIELD_RULE_OWASP_TOP_10 = "owaspTop10";
public static final String FIELD_RULE_SANS_TOP_25 = "sansTop25";
public static final String FIELD_RULE_SONARSOURCE_SECURITY = "sonarsourceSecurity";
public static final String FIELD_RULE_TAGS = "tags";

public static final Set<String> SORT_FIELDS = ImmutableSet.of(
FIELD_RULE_NAME,
@@ -71,14 +72,6 @@ public class RuleIndexDefinition implements IndexDefinition {
FIELD_RULE_CREATED_AT,
FIELD_RULE_KEY);

// Rule extension fields
public static final IndexRelationType TYPE_RULE_EXTENSION = IndexType.relation(TYPE_RULE, "ruleExtension");
/**
* The uuid of a {@link RuleExtensionScope}
*/
public static final String FIELD_RULE_EXTENSION_SCOPE = "ruleExt_scope";
public static final String FIELD_RULE_EXTENSION_TAGS = "ruleExt_tags";

// Active rule fields
public static final IndexRelationType TYPE_ACTIVE_RULE = IndexType.relation(TYPE_RULE, "activeRule");
public static final String FIELD_ACTIVE_RULE_UUID = "activeRule_uuid";
@@ -137,6 +130,7 @@ public class RuleIndexDefinition implements IndexDefinition {
ruleMapping.keywordFieldBuilder(FIELD_RULE_SEVERITY).disableNorms().build();
ruleMapping.keywordFieldBuilder(FIELD_RULE_STATUS).disableNorms().build();
ruleMapping.keywordFieldBuilder(FIELD_RULE_LANGUAGE).disableNorms().build();
ruleMapping.keywordFieldBuilder(FIELD_RULE_TAGS).build();

ruleMapping.createBooleanField(FIELD_RULE_IS_TEMPLATE);
ruleMapping.createBooleanField(FIELD_RULE_IS_EXTERNAL);
@@ -158,10 +152,5 @@ public class RuleIndexDefinition implements IndexDefinition {
.keywordFieldBuilder(FIELD_ACTIVE_RULE_PROFILE_UUID).disableNorms().build()
.keywordFieldBuilder(FIELD_ACTIVE_RULE_INHERITANCE).disableNorms().build()
.keywordFieldBuilder(FIELD_ACTIVE_RULE_SEVERITY).disableNorms().build();

// Rule extension
index.createTypeMapping(TYPE_RULE_EXTENSION)
.keywordFieldBuilder(FIELD_RULE_EXTENSION_SCOPE).disableNorms().build()
.keywordFieldBuilder(FIELD_RULE_EXTENSION_TAGS).build();
}
}

+ 6
- 67
server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndexer.java 查看文件

@@ -33,8 +33,6 @@ import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.es.EsQueueDto;
import org.sonar.db.es.RuleExtensionId;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.rule.RuleForIndexingDto;
import org.sonar.server.es.BulkIndexer;
import org.sonar.server.es.BulkIndexer.Size;
@@ -47,14 +45,11 @@ import org.sonar.server.es.ResilientIndexer;
import org.sonar.server.rule.HotspotRuleDescription;
import org.sonar.server.security.SecurityStandards;

import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Stream.concat;
import static org.sonar.core.util.stream.MoreCollectors.toHashSet;
import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_RULE;
import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_RULE_EXTENSION;
import static org.sonar.server.security.SecurityStandards.SQ_CATEGORY_KEYS_ORDERING;

public class RuleIndexer implements ResilientIndexer {
@@ -70,7 +65,7 @@ public class RuleIndexer implements ResilientIndexer {

@Override
public Set<IndexType> getIndexTypes() {
return ImmutableSet.of(TYPE_RULE, TYPE_RULE_EXTENSION);
return ImmutableSet.of(TYPE_RULE);
}

@Override
@@ -79,27 +74,15 @@ public class RuleIndexer implements ResilientIndexer {
BulkIndexer bulk = createBulkIndexer(Size.LARGE, IndexingListener.FAIL_ON_ERROR);
bulk.start();

// index all definitions and system extensions
// index all definitions
if (uninitializedIndexTypes.contains(TYPE_RULE)) {
dbClient.ruleDao().scrollIndexingRules(dbSession, dto -> {
bulk.add(ruleDocOf(dto).toIndexRequest());
bulk.add(RuleExtensionDoc.of(dto).toIndexRequest());
});
}

// index all organization extensions
if (uninitializedIndexTypes.contains(TYPE_RULE_EXTENSION)) {
dbClient.ruleDao().scrollIndexingRuleExtensions(dbSession, dto -> bulk.add(RuleExtensionDoc.of(dto).toIndexRequest()));
dbClient.ruleDao().scrollIndexingRules(dbSession, dto -> bulk.add(ruleDocOf(dto).toIndexRequest()));
}

bulk.stop();
}
}

public void commitAndIndex(DbSession dbSession, String ruleUuid) {
commitAndIndex(dbSession, singletonList(ruleUuid));
}

public void commitAndIndex(DbSession dbSession, Collection<String> ruleUuids) {
List<EsQueueDto> items = ruleUuids.stream()
.map(RuleIndexer::createQueueDtoForRule)
@@ -113,8 +96,8 @@ public class RuleIndexer implements ResilientIndexer {
/**
* Commit a change on a rule and its extension on the given organization
*/
public void commitAndIndex(DbSession dbSession, String ruleUuid, OrganizationDto organization) {
List<EsQueueDto> items = asList(createQueueDtoForRule(ruleUuid), createQueueDtoForRuleExtension(ruleUuid, organization));
public void commitAndIndex(DbSession dbSession, String ruleUuid) {
List<EsQueueDto> items = asList(createQueueDtoForRule(ruleUuid));
dbClient.esQueueDao().insert(dbSession, items);
dbSession.commit();
postCommit(dbSession, items);
@@ -133,7 +116,6 @@ public class RuleIndexer implements ResilientIndexer {
if (!items.isEmpty()) {
ListMultimap<String, EsQueueDto> itemsByType = groupItemsByIndexTypeFormat(items);
doIndexRules(dbSession, itemsByType.get(TYPE_RULE.format())).ifPresent(result::add);
doIndexRuleExtensions(dbSession, itemsByType.get(TYPE_RULE_EXTENSION.format())).ifPresent(result::add);
}
return result;
}
@@ -154,49 +136,17 @@ public class RuleIndexer implements ResilientIndexer {
dbClient.ruleDao().scrollIndexingRulesByKeys(dbSession, ruleUuids,
r -> {
bulkIndexer.add(ruleDocOf(r).toIndexRequest());
bulkIndexer.add(RuleExtensionDoc.of(r).toIndexRequest());
ruleUuids.remove(r.getUuid());
});

// the remaining items reference rows that don't exist in db. They must
// be deleted from index.
// the remaining items reference rows that don't exist in db. They must be deleted from index.
ruleUuids.forEach(ruleUuid -> {
bulkIndexer.addDeletion(TYPE_RULE, ruleUuid, ruleUuid);
bulkIndexer.addDeletion(TYPE_RULE_EXTENSION, RuleExtensionDoc.idOf(ruleUuid, RuleExtensionScope.system()), ruleUuid);
});

return Optional.of(bulkIndexer.stop());
}

private Optional<IndexingResult> doIndexRuleExtensions(DbSession dbSession, List<EsQueueDto> items) {
if (items.isEmpty()) {
return Optional.empty();
}

BulkIndexer bulkIndexer = createBulkIndexer(Size.REGULAR, new OneToOneResilientIndexingListener(dbClient, dbSession, items));
bulkIndexer.start();

Set<RuleExtensionId> docIds = items
.stream()
.map(RuleIndexer::explodeRuleExtensionDocId)
.collect(toHashSet(items.size()));

dbClient.ruleDao().scrollIndexingRuleExtensionsByIds(dbSession, docIds,
// only index requests, no deletion requests.
// Deactivated users are not deleted but updated.
r -> {
RuleExtensionId docId = new RuleExtensionId(r.getOrganizationUuid(), r.getRuleUuid());
docIds.remove(docId);
bulkIndexer.add(RuleExtensionDoc.of(r).toIndexRequest());
});

// the remaining items reference rows that don't exist in db. They must
// be deleted from index.
docIds.forEach(docId -> bulkIndexer.addDeletion(TYPE_RULE_EXTENSION, docId.getId(), docId.getRuleUuid()));

return Optional.of(bulkIndexer.stop());
}

private static RuleDoc ruleDocOf(RuleForIndexingDto dto) {
SecurityStandards securityStandards = SecurityStandards.fromSecurityStandards(dto.getSecurityStandards());
if (!securityStandards.getIgnoredSQCategories().isEmpty()) {
@@ -234,19 +184,8 @@ public class RuleIndexer implements ResilientIndexer {
return items.stream().collect(MoreCollectors.index(EsQueueDto::getDocType));
}

private static RuleExtensionId explodeRuleExtensionDocId(EsQueueDto esQueueDto) {
checkArgument(TYPE_RULE_EXTENSION.format().equals(esQueueDto.getDocType()));
return new RuleExtensionId(esQueueDto.getDocId());
}

private static EsQueueDto createQueueDtoForRule(String ruleUuid) {
String docId = ruleUuid;
return EsQueueDto.create(TYPE_RULE.format(), docId, null, docId);
}

private static EsQueueDto createQueueDtoForRuleExtension(String ruleUuid, OrganizationDto organization) {
String docId = RuleExtensionDoc.idOf(ruleUuid, RuleExtensionScope.organization(organization));
return EsQueueDto.create(TYPE_RULE_EXTENSION.format(), docId, null, ruleUuid);
}

}

+ 0
- 10
server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleQuery.java 查看文件

@@ -53,7 +53,6 @@ public class RuleQuery {
private boolean ascendingSort = true;
private String internalKey;
private String ruleKey;
private OrganizationDto organization;
private boolean includeExternal;
private Collection<String> owaspTop10;
private Collection<String> sansTop25;
@@ -279,15 +278,6 @@ public class RuleQuery {
return ruleKey;
}

public OrganizationDto getOrganization() {
return organization;
}

public RuleQuery setOrganization(OrganizationDto o) {
this.organization = o;
return this;
}

@CheckForNull
public QProfileDto getCompareToQProfile() {
return compareToQProfile;

+ 2
- 4
server/sonar-server-common/src/test/java/org/sonar/server/qualityprofile/index/ActiveRuleIndexerTest.java 查看文件

@@ -30,7 +30,6 @@ import org.junit.Test;
import org.sonar.api.utils.System2;
import org.sonar.db.DbTester;
import org.sonar.db.es.EsQueueDto;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.qualityprofile.ActiveRuleDto;
import org.sonar.db.qualityprofile.QProfileDto;
import org.sonar.db.rule.RuleDefinitionDto;
@@ -63,9 +62,8 @@ public class ActiveRuleIndexerTest {
public void before() {
rule1 = db.rules().insert();
rule2 = db.rules().insert();
OrganizationDto org = db.organizations().insert();
profile1 = db.qualityProfiles().insert(org);
profile2 = db.qualityProfiles().insert(org);
profile1 = db.qualityProfiles().insert();
profile2 = db.qualityProfiles().insert();
}

@Test

+ 2
- 5
server/sonar-server-common/src/test/java/org/sonar/server/rule/DefaultRuleFinderTest.java 查看文件

@@ -29,7 +29,6 @@ import org.sonar.api.utils.System2;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.db.rule.RuleDto;
import org.sonar.db.rule.RuleDto.Scope;
@@ -46,7 +45,6 @@ public class DefaultRuleFinderTest {

private DbClient dbClient = dbTester.getDbClient();
private DbSession session = dbTester.getSession();
private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(dbTester);

private RuleDto rule1 = new RuleDto()
.setName("Check Header")
@@ -84,7 +82,7 @@ public class DefaultRuleFinderTest {
.setScope(Scope.MAIN)
.setStatus(RuleStatus.READY);

private DefaultRuleFinder underTest = new DefaultRuleFinder(dbClient, defaultOrganizationProvider);
private DefaultRuleFinder underTest = new DefaultRuleFinder(dbClient);

@Before
public void setup() {
@@ -131,8 +129,7 @@ public class DefaultRuleFinderTest {
public void findByKey_populates_system_tags_but_not_tags() {
RuleDefinitionDto ruleDefinition = dbTester.rules()
.insert(t -> t.setSystemTags(ImmutableSet.of(randomAlphanumeric(5), randomAlphanumeric(6))));
OrganizationDto organization = dbTester.organizations().insert();
dbTester.rules().insertRule(organization);
dbTester.rules().insertRule();

Rule rule = underTest.findByKey(ruleDefinition.getKey());
assertThat(rule.getSystemTags())

+ 1
- 1
server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexDefinitionTest.java 查看文件

@@ -61,7 +61,7 @@ public class RuleIndexDefinitionTest {
.isEqualTo(IndexType.main(Index.withRelations("rules"), "rule"));
assertThat(ruleIndex.getRelationsStream())
.extracting(IndexType.IndexRelationType::getName)
.containsOnly("activeRule", "ruleExtension");
.containsOnly("activeRule");

// no cluster by default
assertThat(ruleIndex.getSetting("index.number_of_shards")).isEqualTo("2");

+ 28
- 98
server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java 查看文件

@@ -31,10 +31,8 @@ import org.junit.rules.ExpectedException;
import org.sonar.api.impl.utils.AlwaysIncreasingSystem2;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.rules.RuleType;
import org.sonar.api.utils.System2;
import org.sonar.db.DbTester;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.qualityprofile.QProfileDto;
import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.db.rule.RuleMetadataDto;
@@ -67,7 +65,6 @@ import static org.sonar.db.rule.RuleTesting.setIsExternal;
import static org.sonar.db.rule.RuleTesting.setIsTemplate;
import static org.sonar.db.rule.RuleTesting.setLanguage;
import static org.sonar.db.rule.RuleTesting.setName;
import static org.sonar.db.rule.RuleTesting.setOrganization;
import static org.sonar.db.rule.RuleTesting.setRepositoryKey;
import static org.sonar.db.rule.RuleTesting.setRuleKey;
import static org.sonar.db.rule.RuleTesting.setSecurityStandards;
@@ -86,7 +83,6 @@ import static org.sonar.server.rule.index.RuleIndex.FACET_TAGS;
import static org.sonar.server.rule.index.RuleIndex.FACET_TYPES;
import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_ACTIVE_RULE;
import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_RULE;
import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_RULE_EXTENSION;
import static org.sonar.server.security.SecurityStandards.SANS_TOP_25_INSECURE_INTERACTION;
import static org.sonar.server.security.SecurityStandards.SANS_TOP_25_RISKY_RESOURCE;

@@ -293,21 +289,19 @@ public class RuleIndexTest {

@Test
public void filter_by_tags() {
OrganizationDto organization = db.organizations().insert();

RuleDefinitionDto rule1 = createRule(setSystemTags("tag1s"));
createRuleMetadata(rule1, organization, setTags("tag1"));
createRuleMetadata(rule1, setTags("tag1"));
RuleDefinitionDto rule2 = createRule(setSystemTags("tag2s"));
createRuleMetadata(rule2, organization, setTags("tag2"));
createRuleMetadata(rule2, setTags("tag2"));
index();

assertThat(es.countDocuments(TYPE_RULE_EXTENSION)).isEqualTo(4);
assertThat(es.countDocuments(TYPE_RULE)).isEqualTo(2);
// tag2s in filter
RuleQuery query = new RuleQuery().setOrganization(organization).setTags(of("tag2s"));
RuleQuery query = new RuleQuery().setTags(of("tag2s"));
verifySearch(query, rule2);

// tag2 in filter
query = new RuleQuery().setOrganization(organization).setTags(of("tag2"));
query = new RuleQuery().setTags(of("tag2"));
verifySearch(query, rule2);

// empty list => no filter
@@ -321,14 +315,11 @@ public class RuleIndexTest {

@Test
public void tags_facet_supports_selected_value_with_regexp_special_characters() {
OrganizationDto organization = db.organizations().insert();

RuleDefinitionDto rule = createRule();
createRuleMetadata(rule, organization, setTags("misra++"));
createRuleMetadata(rule, setTags("misra++"));
index();

RuleQuery query = new RuleQuery()
.setOrganization(organization)
.setTags(singletonList("misra["));
SearchOptions options = new SearchOptions().addFacets(FACET_TAGS);

@@ -507,8 +498,8 @@ public class RuleIndexTest {
@Test
public void compare_to_another_profile() {
String xoo = "xoo";
QProfileDto profile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(xoo));
QProfileDto anotherProfile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(xoo));
QProfileDto profile = db.qualityProfiles().insert(p -> p.setLanguage(xoo));
QProfileDto anotherProfile = db.qualityProfiles().insert(p -> p.setLanguage(xoo));
RuleDefinitionDto commonRule = db.rules().insertRule(r -> r.setLanguage(xoo)).getDefinition();
RuleDefinitionDto profileRule1 = db.rules().insertRule(r -> r.setLanguage(xoo)).getDefinition();
RuleDefinitionDto profileRule2 = db.rules().insertRule(r -> r.setLanguage(xoo)).getDefinition();
@@ -544,8 +535,8 @@ public class RuleIndexTest {
}

@SafeVarargs
private final RuleMetadataDto createRuleMetadata(RuleDefinitionDto rule, OrganizationDto organization, Consumer<RuleMetadataDto>... populaters) {
return db.rules().insertOrUpdateMetadata(rule, organization, populaters);
private final RuleMetadataDto createRuleMetadata(RuleDefinitionDto rule, Consumer<RuleMetadataDto>... populaters) {
return db.rules().insertOrUpdateMetadata(rule, populaters);
}

@Test
@@ -641,16 +632,16 @@ public class RuleIndexTest {
}

private void index() {
ruleIndexer.indexOnStartup(Sets.newHashSet(TYPE_RULE, TYPE_RULE_EXTENSION));
ruleIndexer.indexOnStartup(Sets.newHashSet(TYPE_RULE));
activeRuleIndexer.indexOnStartup(Sets.newHashSet(TYPE_ACTIVE_RULE));
}

private RuleQuery newRuleQuery() {
return new RuleQuery().setOrganization(db.getDefaultOrganization());
return new RuleQuery();
}

private QProfileDto createJavaProfile() {
return db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage("java"));
return db.qualityProfiles().insert(p -> p.setLanguage("java"));
}

@Test
@@ -733,46 +724,24 @@ public class RuleIndexTest {
}

@Test
public void listTags_should_return_both_system_tags_and_organization_specific_tags() {
OrganizationDto organization = db.organizations().insert();

public void listTags_should_return_tags() {
RuleDefinitionDto rule1 = createRule(setSystemTags("sys1", "sys2"));
createRuleMetadata(rule1, organization, setOrganization(organization), setTags("tag1"));
createRuleMetadata(rule1, setTags("tag1"));

RuleDefinitionDto rule2 = createRule(setSystemTags());
createRuleMetadata(rule2, organization, setOrganization(organization), setTags("tag2"));

index();

assertThat(underTest.listTags(organization, null, 10)).containsOnly("tag1", "tag2", "sys1", "sys2");
}

@Test
public void listTags_must_not_return_tags_of_other_organizations() {
OrganizationDto organization1 = db.organizations().insert();
RuleDefinitionDto rule1 = createRule(setSystemTags("sys1"));
createRuleMetadata(rule1, organization1, setOrganization(organization1), setTags("tag1"));
createRuleMetadata(rule2, setTags("tag2"));

OrganizationDto organization2 = db.organizations().insert();
RuleDefinitionDto rule2 = createRule(setSystemTags("sys2"));
createRuleMetadata(rule2, organization2, setOrganization(organization2), setTags("tag2"));

OrganizationDto organization3 = db.organizations().insert();
index();

assertThat(underTest.listTags(organization1, null, 10)).containsOnly("tag1", "sys1", "sys2");
assertThat(underTest.listTags(organization2, null, 10)).containsOnly("tag2", "sys1", "sys2");
assertThat(underTest.listTags(organization3, null, 10)).containsOnly("sys1", "sys2");
assertThat(underTest.listTags(null, 10)).containsOnly("tag1", "tag2", "sys1", "sys2");
}

@Test
public void fail_to_list_tags_when_size_greater_than_500() {
OrganizationDto organization = db.organizations().insert();

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Page size must be lower than or equals to 500");

underTest.listTags(organization, null, 501);
underTest.listTags(null, 501);
}

@Test
@@ -795,17 +764,15 @@ public class RuleIndexTest {

@Test
public void global_facet_on_repositories_and_tags() {
OrganizationDto organization = db.organizations().insert();

createRule(setRepositoryKey("php"), setSystemTags("sysTag"));
RuleDefinitionDto rule1 = createRule(setRepositoryKey("php"), setSystemTags());
createRuleMetadata(rule1, organization, setTags("tag1"));
createRuleMetadata(rule1, setTags("tag1"));
RuleDefinitionDto rule2 = createRule(setRepositoryKey("javascript"), setSystemTags());
createRuleMetadata(rule2, organization, setTags("tag1", "tag2"));
createRuleMetadata(rule2, setTags("tag1", "tag2"));
index();

// should not have any facet!
RuleQuery query = new RuleQuery().setOrganization(organization);
RuleQuery query = new RuleQuery();
SearchIdResult result1 = underTest.search(query, new SearchOptions());
assertThat(result1.getFacets().getAll()).isEmpty();

@@ -859,9 +826,7 @@ public class RuleIndexTest {
@Test
public void sticky_facets_no_filters() {
setupStickyFacets();
OrganizationDto organization = db.organizations().insert();

RuleQuery query = new RuleQuery().setOrganization(organization);
RuleQuery query = new RuleQuery();

SearchIdResult<String> result = underTest.search(query, new SearchOptions().addFacets(asList(FACET_LANGUAGES, FACET_REPOSITORIES,
FACET_TAGS, FACET_TYPES)));
@@ -880,12 +845,9 @@ public class RuleIndexTest {
@Test
public void sticky_facets_with_1_filter() {
setupStickyFacets();
OrganizationDto organization = db.organizations().insert();

RuleQuery query = new RuleQuery().setOrganization(organization).setLanguages(ImmutableList.of("cpp"));
RuleQuery query = new RuleQuery().setLanguages(ImmutableList.of("cpp"));

SearchIdResult<String> result = underTest.search(query, new SearchOptions().addFacets(asList(FACET_LANGUAGES,
FACET_REPOSITORIES, FACET_TAGS)));
SearchIdResult<String> result = underTest.search(query, new SearchOptions().addFacets(asList(FACET_LANGUAGES, FACET_REPOSITORIES, FACET_TAGS)));
assertThat(result.getUuids()).hasSize(3);
assertThat(result.getFacets().getAll()).hasSize(3);
assertThat(result.getFacets().get(FACET_LANGUAGES).keySet()).containsOnly("cpp", "java", "cobol");
@@ -915,12 +877,11 @@ public class RuleIndexTest {

@Test
public void tags_facet_should_find_tags_of_specified_organization() {
OrganizationDto organization = db.organizations().insert();
RuleDefinitionDto rule = createRule(setSystemTags());
createRuleMetadata(rule, organization, setTags("bla"));
createRuleMetadata(rule, setTags("bla"));
index();

RuleQuery query = new RuleQuery().setOrganization(organization);
RuleQuery query = new RuleQuery();
SearchOptions options = new SearchOptions().addFacets(singletonList(FACET_TAGS));

SearchIdResult<String> result = underTest.search(query, options);
@@ -934,8 +895,7 @@ public class RuleIndexTest {
createRule(setSystemTags(tags));
index();

RuleQuery query = new RuleQuery()
.setOrganization(db.getDefaultOrganization());
RuleQuery query = new RuleQuery();
SearchOptions options = new SearchOptions().addFacets(singletonList(FACET_TAGS));
SearchIdResult<String> result = underTest.search(query, options);
assertThat(result.getFacets().get(FACET_TAGS).size()).isEqualTo(100);
@@ -951,7 +911,6 @@ public class RuleIndexTest {
index();

RuleQuery query = new RuleQuery()
.setOrganization(db.getDefaultOrganization())
.setTags(singletonList("tagA"));
SearchOptions options = new SearchOptions().addFacets(singletonList(FACET_TAGS));
SearchIdResult<String> result = underTest.search(query, options);
@@ -964,42 +923,15 @@ public class RuleIndexTest {
entry("tag0", 1L), entry("tag25", 1L), entry("tag99", 1L));
}

@Test
public void tags_facet_should_not_find_tags_of_any_other_organization() {
OrganizationDto organization1 = db.organizations().insert();
OrganizationDto organization2 = db.organizations().insert();
RuleDefinitionDto rule = createRule(setSystemTags());
createRuleMetadata(rule, organization1, setTags("bla1"));
createRuleMetadata(rule, organization2, setTags("bla2"));
index();

RuleQuery query = new RuleQuery().setOrganization(organization2);
SearchOptions options = new SearchOptions().addFacets(singletonList(FACET_TAGS));

SearchIdResult<String> result = underTest.search(query, options);
assertThat(result.getFacets().get(FACET_TAGS).entrySet()).extracting(e -> entry(e.getKey(), e.getValue())).containsExactly(
entry("bla2", 1L));
}

@Test
public void tags_facet_should_be_available_if_organization_is_specified() {
OrganizationDto organization = db.organizations().insert();
RuleQuery query = new RuleQuery().setOrganization(organization);
RuleQuery query = new RuleQuery();
SearchOptions options = new SearchOptions().addFacets(singletonList(FACET_TAGS));

SearchIdResult<String> result = underTest.search(query, options);
assertThat(result.getFacets().get(FACET_TAGS)).isNotNull();
}

@Test
public void tags_facet_should_be_unavailable_if_no_organization_is_specfified() {
RuleQuery query = new RuleQuery();
SearchOptions options = new SearchOptions().addFacets(singletonList(FACET_TAGS));

expectedException.expectMessage("Cannot use tags facet, if no organization is specified.");
underTest.search(query, options);
}

/**
* Facet with 2 filters
* -- lang facet for tag T2
@@ -1011,7 +943,6 @@ public class RuleIndexTest {
setupStickyFacets();

RuleQuery query = new RuleQuery()
.setOrganization(db.getDefaultOrganization())
.setLanguages(ImmutableList.of("cpp"))
.setTags(ImmutableList.of("T2"));

@@ -1037,7 +968,6 @@ public class RuleIndexTest {
setupStickyFacets();

RuleQuery query = new RuleQuery()
.setOrganization(db.getDefaultOrganization())
.setLanguages(ImmutableList.of("cpp", "java"))
.setTags(ImmutableList.of("T2"))
.setTypes(asList(BUG, CODE_SMELL));

+ 6
- 54
server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexerTest.java 查看文件

@@ -44,7 +44,6 @@ import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.db.rule.RuleDto;
import org.sonar.db.rule.RuleDto.Scope;
import org.sonar.db.rule.RuleMetadataDto;
import org.sonar.db.rule.RuleTesting;
import org.sonar.server.es.EsTester;
import org.sonar.server.security.SecurityStandards;
@@ -53,14 +52,11 @@ import org.sonar.server.security.SecurityStandards.SQCategory;
import static com.google.common.collect.Sets.newHashSet;
import static java.lang.String.format;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptySet;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toSet;
import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
import static org.assertj.core.api.Assertions.assertThat;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_RULE;
import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_RULE_EXTENSION;
import static org.sonar.server.security.SecurityStandards.CWES_BY_SQ_CATEGORY;
import static org.sonar.server.security.SecurityStandards.SQ_CATEGORY_KEYS_ORDERING;

@@ -129,50 +125,6 @@ public class RuleIndexerTest {
assertThat(es.countDocuments(TYPE_RULE)).isEqualTo(1);
}

@Test
public void index_rule_extension_with_long_id() {
RuleDefinitionDto rule = dbTester.rules().insert(r -> r.setRuleKey(RuleTesting.randomRuleKeyOfMaximumLength()));
underTest.commitAndIndex(dbTester.getSession(), rule.getUuid());
OrganizationDto organization = dbTester.organizations().insert();
RuleMetadataDto metadata = RuleTesting.newRuleMetadata(rule, organization).setTags(ImmutableSet.of("bla"));
dbTester.getDbClient().ruleDao().insertOrUpdate(dbTester.getSession(), metadata);
underTest.commitAndIndex(dbTester.getSession(), rule.getUuid(), organization);

RuleExtensionDoc doc = new RuleExtensionDoc()
.setRuleUuid(rule.getUuid())
.setScope(RuleExtensionScope.organization(organization.getUuid()));
assertThat(
es.client()
.prepareSearch(TYPE_RULE_EXTENSION.getMainType())
.setQuery(termQuery("_id", doc.getId()))
.get()
.getHits()
.getHits()[0]
.getId()).isEqualTo(doc.getId());
}

@Test
public void delete_rule_extension_from_index_when_setting_rule_tags_to_empty() {
RuleDefinitionDto rule = dbTester.rules().insert(r -> r.setRuleKey(RuleTesting.randomRuleKeyOfMaximumLength()));
underTest.commitAndIndex(dbTester.getSession(), rule.getUuid());
OrganizationDto organization = dbTester.organizations().insert();
RuleMetadataDto metadata = RuleTesting.newRuleMetadata(rule, organization).setTags(ImmutableSet.of("bla"));
dbTester.getDbClient().ruleDao().insertOrUpdate(dbTester.getSession(), metadata);
underTest.commitAndIndex(dbTester.getSession(), rule.getUuid(), organization);

// index tags
RuleExtensionDoc doc = new RuleExtensionDoc()
.setRuleUuid(rule.getUuid())
.setScope(RuleExtensionScope.organization(organization.getUuid()));
assertThat(es.getIds(TYPE_RULE_EXTENSION)).contains(doc.getId());

// update db table "rules_metadata" with empty tags and delete tags from index
metadata = RuleTesting.newRuleMetadata(rule, organization).setTags(emptySet());
dbTester.getDbClient().ruleDao().insertOrUpdate(dbTester.getSession(), metadata);
underTest.commitAndIndex(dbTester.getSession(), rule.getUuid(), organization);
assertThat(es.getIds(TYPE_RULE_EXTENSION)).doesNotContain(doc.getId());
}

@Test
public void index_long_rule_description() {
String description = IntStream.range(0, 100000).map(i -> i % 100).mapToObj(Integer::toString).collect(joining(" "));
@@ -194,7 +146,7 @@ public class RuleIndexerTest {
.setSecurityStandards(standards)
.setDescription(VALID_HOTSPOT_RULE_DESCRIPTION));
OrganizationDto organization = dbTester.organizations().insert();
underTest.commitAndIndex(dbTester.getSession(), rule.getUuid(), organization);
underTest.commitAndIndex(dbTester.getSession(), rule.getUuid());

assertThat(logTester.getLogs()).hasSize(1);
assertThat(logTester.logs(LoggerLevel.WARN).get(0))
@@ -230,7 +182,7 @@ public class RuleIndexerTest {
.setType(RuleType.SECURITY_HOTSPOT)
.setDescription(description));
OrganizationDto organization = dbTester.organizations().insert();
underTest.commitAndIndex(dbTester.getSession(), rule.getUuid(), organization);
underTest.commitAndIndex(dbTester.getSession(), rule.getUuid());

assertThat(logTester.getLogs()).hasSize(1);
assertThat(logTester.logs(LoggerLevel.WARN).get(0))
@@ -253,7 +205,7 @@ public class RuleIndexerTest {
.setType(RuleType.SECURITY_HOTSPOT)
.setDescription(randomAlphabetic(30)));
OrganizationDto organization = dbTester.organizations().insert();
underTest.commitAndIndex(dbTester.getSession(), rule.getUuid(), organization);
underTest.commitAndIndex(dbTester.getSession(), rule.getUuid());

assertThat(logTester.getLogs()).hasSize(1);
assertThat(logTester.logs(LoggerLevel.WARN).get(0))
@@ -270,7 +222,7 @@ public class RuleIndexerTest {
"<h2>Ask Yourself Whether</h2>\n" +
"foo"));
OrganizationDto organization = dbTester.organizations().insert();
underTest.commitAndIndex(dbTester.getSession(), rule.getUuid(), organization);
underTest.commitAndIndex(dbTester.getSession(), rule.getUuid());

assertThat(logTester.getLogs()).hasSize(1);
assertThat(logTester.logs(LoggerLevel.WARN).get(0))
@@ -288,7 +240,7 @@ public class RuleIndexerTest {
"<h2>Recommended Secure Coding Practices</h2>\n" +
"foo"));
OrganizationDto organization = dbTester.organizations().insert();
underTest.commitAndIndex(dbTester.getSession(), rule.getUuid(), organization);
underTest.commitAndIndex(dbTester.getSession(), rule.getUuid());

assertThat(logTester.getLogs()).hasSize(1);
assertThat(logTester.logs(LoggerLevel.WARN).get(0))
@@ -305,7 +257,7 @@ public class RuleIndexerTest {
"<h2>Recommended Secure Coding Practices</h2>\n" +
"foo"));
OrganizationDto organization = dbTester.organizations().insert();
underTest.commitAndIndex(dbTester.getSession(), rule.getUuid(), organization);
underTest.commitAndIndex(dbTester.getSession(), rule.getUuid());

assertThat(logTester.getLogs()).hasSize(1);
assertThat(logTester.logs(LoggerLevel.WARN).get(0))

+ 2
- 2
server/sonar-server-common/src/testFixtures/java/org/sonar/server/organization/TestDefaultOrganizationProvider.java 查看文件

@@ -66,11 +66,11 @@ public class TestDefaultOrganizationProvider implements DefaultOrganizationProvi
}
}

private static final class DbTesterDefaultOrganizationProvider implements DefaultOrganizationProvider {
public static final class DbTesterDefaultOrganizationProvider implements DefaultOrganizationProvider {
private final DbTester dbTester;
private DefaultOrganization defaultOrganization = null;

private DbTesterDefaultOrganizationProvider(DbTester dbTester) {
public DbTesterDefaultOrganizationProvider(DbTester dbTester) {
this.dbTester = dbTester;
}


+ 1
- 6
server/sonar-web/src/main/js/api/quality-profiles.ts 查看文件

@@ -340,7 +340,6 @@ export function bulkDeactivateRules(data: BulkActivateParameters) {

export function activateRule(data: {
key: string;
organization: string | undefined;
params?: T.Dict<string>;
reset?: boolean;
rule: string;
@@ -351,10 +350,6 @@ export function activateRule(data: {
return post('/api/qualityprofiles/activate_rule', { ...data, params }).catch(throwGlobalError);
}

export function deactivateRule(data: {
key: string;
organization: string | undefined;
rule: string;
}) {
export function deactivateRule(data: { key: string; rule: string }) {
return post('/api/qualityprofiles/deactivate_rule', data).catch(throwGlobalError);
}

+ 6
- 6
server/sonar-web/src/main/js/api/rules.ts 查看文件

@@ -39,7 +39,7 @@ export interface SearchRulesResponse {
}

export function searchRules(data: {
organization: string | undefined;
organization?: string;
[x: string]: any;
}): Promise<SearchRulesResponse> {
return getJSON('/api/rules/search', data).catch(throwGlobalError);
@@ -53,13 +53,13 @@ export function takeFacet(response: any, property: string) {
export function getRuleDetails(parameters: {
actives?: boolean;
key: string;
organization: string | undefined;
organization?: string;
}): Promise<{ actives?: T.RuleActivation[]; rule: T.RuleDetails }> {
return getJSON('/api/rules/show', parameters).catch(throwGlobalError);
}

export function getRuleTags(parameters: {
organization: string | undefined;
organization?: string;
ps?: number;
q: string;
}): Promise<string[]> {
@@ -70,7 +70,7 @@ export function createRule(data: {
custom_key: string;
markdown_description: string;
name: string;
organization: string | undefined;
organization?: string;
params?: string;
prevent_reactivation?: boolean;
severity?: string;
@@ -92,7 +92,7 @@ export function createRule(data: {
);
}

export function deleteRule(parameters: { key: string; organization: string | undefined }) {
export function deleteRule(parameters: { key: string; organization?: string }) {
return post('/api/rules/delete', parameters).catch(throwGlobalError);
}

@@ -101,7 +101,7 @@ export function updateRule(data: {
markdown_description?: string;
markdown_note?: string;
name?: string;
organization: string | undefined;
organization?: string;
params?: string;
remediation_fn_base_effort?: string;
remediation_fn_type?: string;

+ 0
- 1
server/sonar-web/src/main/js/app/components/nav/component/projectInformation/meta/MetaQualityProfiles.tsx 查看文件

@@ -75,7 +75,6 @@ export class MetaQualityProfiles extends React.PureComponent<StateProps & OwnPro
loadDeprecatedRulesForProfile(profileKey: string) {
const data = {
activation: 'true',
organization: undefined,
ps: 1,
qprofile: profileKey,
statuses: 'DEPRECATED'

+ 1
- 1
server/sonar-web/src/main/js/apps/about/components/AboutApp.tsx 查看文件

@@ -183,7 +183,7 @@ export class AboutApp extends React.PureComponent<Props, State> {
<AboutQualityGates />
</div>
<div className="flex-column flex-column-half about-page-group-boxes">
<AboutStandards appState={this.props.appState} />
<AboutStandards />
</div>
</div>


+ 6
- 12
server/sonar-web/src/main/js/apps/about/components/AboutStandards.tsx 查看文件

@@ -30,13 +30,7 @@ const owaspTags =
'owasp-a1,owasp-a2,owasp-a3,owasp-a4,owasp-a5,owasp-a6,owasp-a7,owasp-a8,owasp-a9,owasp-a10';
const sans25Tags = 'sans-top25-porous,sans-top25-risky,sans-top25-insecure';

interface Props {
appState: Pick<T.AppState, 'defaultOrganization' | 'organizationsEnabled'>;
}

export default function AboutStandards({ appState }: Props) {
const organization = appState.organizationsEnabled ? appState.defaultOrganization : undefined;

export default function AboutStandards() {
return (
<div className="boxed-group">
<h2>{translate('about_page.standards')}</h2>
@@ -46,31 +40,31 @@ export default function AboutStandards({ appState }: Props) {
<div className="spacer-top">
<ul className="list-inline">
<li>
<Link className="link-with-icon" to={getRulesUrl({ tags: 'misra' }, organization)}>
<Link className="link-with-icon" to={getRulesUrl({ tags: 'misra' })}>
<TagsIcon />
<span className="little-spacer-left">MISRA</span>
</Link>
</li>
<li>
<Link className="link-with-icon" to={getRulesUrl({ tags: 'cert' }, organization)}>
<Link className="link-with-icon" to={getRulesUrl({ tags: 'cert' })}>
<TagsIcon />
<span className="little-spacer-left">CERT</span>
</Link>
</li>
<li>
<Link className="link-with-icon" to={getRulesUrl({ tags: 'cwe' }, organization)}>
<Link className="link-with-icon" to={getRulesUrl({ tags: 'cwe' })}>
<TagsIcon />
<span className="little-spacer-left">CWE</span>
</Link>
</li>
<li>
<Link className="link-with-icon" to={getRulesUrl({ tags: owaspTags }, organization)}>
<Link className="link-with-icon" to={getRulesUrl({ tags: owaspTags })}>
<TagsIcon />
<span className="little-spacer-left">OWASP Top 10</span>
</Link>
</li>
<li>
<Link className="link-with-icon" to={getRulesUrl({ tags: sans25Tags }, organization)}>
<Link className="link-with-icon" to={getRulesUrl({ tags: sans25Tags })}>
<TagsIcon />
<span className="little-spacer-left">SANS Top 25</span>
</Link>

+ 1
- 14
server/sonar-web/src/main/js/apps/about/components/__tests__/__snapshots__/AboutApp-test.tsx.snap 查看文件

@@ -99,20 +99,7 @@ exports[`should render correctly 1`] = `
<div
className="flex-column flex-column-half about-page-group-boxes"
>
<AboutStandards
appState={
Object {
"defaultOrganization": "foo",
"edition": "community",
"productionDatabase": true,
"qualifiers": Array [
"TRK",
],
"settings": Object {},
"version": "1.0",
}
}
/>
<AboutStandards />
</div>
</div>
<AboutScanners />

+ 0
- 2
server/sonar-web/src/main/js/apps/coding-rules/components/ActivationButton.tsx 查看文件

@@ -28,7 +28,6 @@ interface Props {
className?: string;
modalHeader: string;
onDone: (severity: string) => Promise<void>;
organization: string | undefined;
profiles: BaseProfile[];
rule: T.Rule | T.RuleDetails;
}
@@ -64,7 +63,6 @@ export default class ActivationButton extends React.PureComponent<Props, State>
modalHeader={this.props.modalHeader}
onClose={this.handleCloseModal}
onDone={this.props.onDone}
organization={this.props.organization}
profiles={this.props.profiles}
rule={this.props.rule}
/>

+ 0
- 2
server/sonar-web/src/main/js/apps/coding-rules/components/ActivationFormModal.tsx 查看文件

@@ -35,7 +35,6 @@ interface Props {
modalHeader: string;
onClose: () => void;
onDone: (severity: string) => Promise<void>;
organization: string | undefined;
profiles: Profile[];
rule: T.Rule | T.RuleDetails;
}
@@ -106,7 +105,6 @@ export default class ActivationFormModal extends React.PureComponent<Props, Stat
this.setState({ submitting: true });
const data = {
key: this.state.profile,
organization: this.props.organization,
params: this.state.params,
rule: this.props.rule.key,
severity: this.state.severity

+ 0
- 0
server/sonar-web/src/main/js/apps/coding-rules/components/App.tsx 查看文件


部分文件因文件數量過多而無法顯示

Loading…
取消
儲存