Browse Source

SONAR-10313 use rule id as doc key in rules indexes instead of RuleKey

tags/7.5
Sébastien Lesaint 6 years ago
parent
commit
5dd8182a2b
53 changed files with 420 additions and 348 deletions
  1. 12
    19
      server/sonar-db-dao/src/main/java/org/sonar/db/es/RuleExtensionId.java
  2. 5
    0
      server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/IndexedActiveRuleDto.java
  3. 5
    5
      server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDao.java
  4. 9
    0
      server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleExtensionForIndexingDto.java
  5. 1
    1
      server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleMapper.java
  6. 1
    0
      server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/ActiveRuleMapper.xml
  7. 6
    5
      server/sonar-db-dao/src/main/resources/org/sonar/db/rule/RuleMapper.xml
  8. 11
    8
      server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/ActiveRuleDaoTest.java
  9. 15
    10
      server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDaoTest.java
  10. 4
    5
      server/sonar-server/src/main/java/org/sonar/server/organization/ws/EnableSupportAction.java
  11. 7
    8
      server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQProfileUpdateImpl.java
  12. 7
    8
      server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileResetImpl.java
  13. 1
    2
      server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileRules.java
  14. 11
    12
      server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileRulesImpl.java
  15. 5
    6
      server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileTreeImpl.java
  16. 10
    0
      server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivationContext.java
  17. 9
    10
      server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java
  18. 19
    9
      server/sonar-server/src/main/java/org/sonar/server/qualityprofile/index/ActiveRuleDoc.java
  19. 6
    5
      server/sonar-server/src/main/java/org/sonar/server/qualityprofile/index/ActiveRuleIndexer.java
  20. 3
    1
      server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/DeactivateRuleAction.java
  21. 7
    1
      server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileWsSupport.java
  22. 32
    21
      server/sonar-server/src/main/java/org/sonar/server/rule/RegisterRules.java
  23. 9
    13
      server/sonar-server/src/main/java/org/sonar/server/rule/RuleCreator.java
  24. 1
    1
      server/sonar-server/src/main/java/org/sonar/server/rule/RuleUpdater.java
  25. 12
    2
      server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleDoc.java
  26. 20
    5
      server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleExtensionDoc.java
  27. 5
    6
      server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndex.java
  28. 5
    0
      server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndexDefinition.java
  29. 23
    28
      server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndexer.java
  30. 1
    1
      server/sonar-server/src/main/java/org/sonar/server/rule/ws/DeleteAction.java
  31. 6
    8
      server/sonar-server/src/main/java/org/sonar/server/rule/ws/SearchAction.java
  32. 1
    1
      server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexTest.java
  33. 8
    8
      server/sonar-server/src/test/java/org/sonar/server/issue/ws/TagsActionTest.java
  34. 3
    4
      server/sonar-server/src/test/java/org/sonar/server/organization/ws/EnableSupportActionTest.java
  35. 2
    1
      server/sonar-server/src/test/java/org/sonar/server/platform/BackendCleanupTest.java
  36. 10
    10
      server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileComparisonTest.java
  37. 1
    10
      server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileRuleImplTest.java
  38. 2
    1
      server/sonar-server/src/test/java/org/sonar/server/qualityprofile/index/ActiveRuleIndexerTest.java
  39. 6
    6
      server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ChangeParentActionTest.java
  40. 1
    1
      server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CreateActionTest.java
  41. 21
    14
      server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/DeactivateRuleActionTest.java
  42. 3
    3
      server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/InheritanceActionTest.java
  43. 5
    5
      server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest.java
  44. 24
    20
      server/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesTest.java
  45. 3
    3
      server/sonar-server/src/test/java/org/sonar/server/rule/RuleCreatorTest.java
  46. 2
    6
      server/sonar-server/src/test/java/org/sonar/server/rule/RuleUpdaterTest.java
  47. 2
    0
      server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleIndexDefinitionTest.java
  48. 43
    40
      server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java
  49. 7
    6
      server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleIndexerTest.java
  50. 1
    1
      server/sonar-server/src/test/java/org/sonar/server/rule/ws/DeleteActionTest.java
  51. 1
    1
      server/sonar-server/src/test/java/org/sonar/server/rule/ws/SearchActionTest.java
  52. 3
    4
      server/sonar-server/src/test/java/org/sonar/server/rule/ws/ShowActionTest.java
  53. 3
    3
      server/sonar-server/src/test/java/org/sonar/server/rule/ws/TagsActionTest.java

+ 12
- 19
server/sonar-db-dao/src/main/java/org/sonar/db/es/RuleExtensionId.java View File

@@ -27,39 +27,32 @@ import static com.google.common.base.Preconditions.checkArgument;
import static java.lang.String.format;

public class RuleExtensionId {
private final int ruleId;
private final String organizationUuid;
private final String repositoryName;
private final String ruleKey;
private final String id;

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

public RuleExtensionId(String organizationUuid, String repositoryName, String ruleKey) {
public RuleExtensionId(String organizationUuid, int ruleId) {
this.organizationUuid = organizationUuid;
this.repositoryName = repositoryName;
this.ruleKey = ruleKey;
this.id = format("%s:%s|%s",repositoryName,ruleKey,organizationUuid);
this.ruleId = ruleId;
this.id = format("%s|%s", ruleId, organizationUuid);
}

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

public String getOrganizationUuid() {
return organizationUuid;
}

public String getRepositoryName() {
return repositoryName;
public int getRuleId() {
return ruleId;
}

public String getRuleKey() {
return ruleKey;
public String getOrganizationUuid() {
return organizationUuid;
}

public String getId() {

+ 5
- 0
server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/IndexedActiveRuleDto.java View File

@@ -23,6 +23,7 @@ import javax.annotation.CheckForNull;

public class IndexedActiveRuleDto {
private long id;
private int ruleId;
private int severity;
private String inheritance;
private String repository;
@@ -33,6 +34,10 @@ public class IndexedActiveRuleDto {
return id;
}

public int getRuleId() {
return ruleId;
}

public int getSeverity() {
return severity;
}

+ 5
- 5
server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDao.java View File

@@ -186,12 +186,12 @@ public class RuleDao implements Dao {
});
}

public void scrollIndexingRulesByKeys(DbSession dbSession, Collection<RuleKey> ruleKeys, Consumer<RuleForIndexingDto> consumer) {
public void scrollIndexingRulesByKeys(DbSession dbSession, Collection<Integer> ruleIds, Consumer<RuleForIndexingDto> consumer) {
RuleMapper mapper = mapper(dbSession);

executeLargeInputsWithoutOutput(ruleKeys,
pageOfRuleKeys -> mapper
.selectIndexingRulesByKeys(pageOfRuleKeys)
executeLargeInputsWithoutOutput(ruleIds,
pageOfRuleIds -> mapper
.selectIndexingRulesByIds(pageOfRuleIds)
.forEach(consumer));
}

@@ -218,7 +218,7 @@ public class RuleDao implements Dao {
return executeLargeInputs(ruleKeys, mapper(session)::selectParamsByRuleKeys);
}

public List<RuleParamDto> selectRuleParamsByRuleIds(DbSession dbSession, List<Integer> ruleIds) {
public List<RuleParamDto> selectRuleParamsByRuleIds(DbSession dbSession, Collection<Integer> ruleIds) {
return executeLargeInputs(ruleIds, mapper(dbSession)::selectParamsByRuleIds);
}


+ 9
- 0
server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleExtensionForIndexingDto.java View File

@@ -28,6 +28,7 @@ public class RuleExtensionForIndexingDto {

private static final Splitter TAGS_SPLITTER = Splitter.on(',').trimResults().omitEmptyStrings();

private int ruleId;
private String pluginName;
private String pluginRuleKey;
private String organizationUuid;
@@ -51,6 +52,14 @@ public class RuleExtensionForIndexingDto {
return this;
}

public int getRuleId() {
return ruleId;
}

public void setRuleId(int ruleId) {
this.ruleId = ruleId;
}

public String getOrganizationUuid() {
return organizationUuid;
}

+ 1
- 1
server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleMapper.java View File

@@ -55,7 +55,7 @@ public interface RuleMapper {

void scrollIndexingRules(ResultHandler<RuleForIndexingDto> handler);

List<RuleForIndexingDto> selectIndexingRulesByKeys(@Param("ruleKeys") List<RuleKey> keys);
List<RuleForIndexingDto> selectIndexingRulesByIds(@Param("ruleIds") List<Integer> ruleIds);

void scrollIndexingRuleExtensions(ResultHandler<RuleExtensionForIndexingDto> handler);


+ 1
- 0
server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/ActiveRuleMapper.xml View File

@@ -302,6 +302,7 @@
ar.id as "id",
ar.failure_level as "severity",
ar.inheritance as "inheritance",
r.id as "ruleId",
r.plugin_name as "repository",
r.plugin_rule_key as "key",
rp.kee as "ruleProfileUuid"

+ 6
- 5
server/sonar-db-dao/src/main/resources/org/sonar/db/rule/RuleMapper.xml View File

@@ -145,8 +145,7 @@
<include refid="sqlSelectIndexingRuleExtensions" />
and
<foreach collection="ruleExtensionIds" index="index" item="ruleExtId" open="" separator=" or " close="">
( r.plugin_name = #{ruleExtId.repositoryName, jdbcType=VARCHAR} and
r.plugin_rule_key = #{ruleExtId.ruleKey, jdbcType=VARCHAR} and
( r.id = #{ruleExtId.ruleId, jdbcType=INTEGER} and
rm.organization_uuid = #{ruleExtId.organizationUuid, jdbcType=VARCHAR} )
</foreach>
</select>
@@ -157,6 +156,7 @@

<sql id="sqlSelectIndexingRuleExtensions">
select
r.id as "ruleId",
r.plugin_name as "pluginName",
r.plugin_rule_key as "pluginRuleKey",
rm.organization_uuid as "organizationUuid",
@@ -170,6 +170,7 @@

<sql id="sqlSelectIndexingRuleExtensions" databaseId="oracle">
select
r.id as "ruleId",
r.plugin_name as "pluginName",
r.plugin_rule_key as "pluginRuleKey",
rm.organization_uuid as "organizationUuid",
@@ -226,11 +227,11 @@
</foreach>
</select>

<select id="selectIndexingRulesByKeys" parameterType="map" resultType="org.sonar.db.rule.RuleForIndexingDto">
<select id="selectIndexingRulesByIds" parameterType="map" resultType="org.sonar.db.rule.RuleForIndexingDto">
<include refid="sqlSelectIndexingRules"/>
where
<foreach collection="ruleKeys" index="index" item="ruleKey" open="" separator=" or " close="">
(r.plugin_name=#{ruleKey.repository,jdbcType=VARCHAR} and r.plugin_rule_key=#{ruleKey.rule,jdbcType=VARCHAR})
<foreach collection="ruleIds" index="index" item="ruleId" open="" separator=" or " close="">
r.id=#{ruleId,jdbcType=INTEGER}
</foreach>
</select>


+ 11
- 8
server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/ActiveRuleDaoTest.java View File

@@ -632,12 +632,14 @@ public class ActiveRuleDaoTest {
Accumulator accumulator = new Accumulator();
underTest.scrollAllForIndexing(dbSession, accumulator);
assertThat(accumulator.list)
.extracting(IndexedActiveRuleDto::getId, IndexedActiveRuleDto::getRepository, IndexedActiveRuleDto::getKey, IndexedActiveRuleDto::getRuleProfileUuid,
.extracting(IndexedActiveRuleDto::getId,
IndexedActiveRuleDto::getRuleId, IndexedActiveRuleDto::getRepository, IndexedActiveRuleDto::getKey,
IndexedActiveRuleDto::getRuleProfileUuid,
IndexedActiveRuleDto::getSeverity, IndexedActiveRuleDto::getInheritance)
.containsExactlyInAnyOrder(
tuple((long) ar1.getId(), ar1.getRuleKey().repository(), ar1.getRuleKey().rule(), profile1.getRulesProfileUuid(), ar1.getSeverity(), ar1.getInheritance()),
tuple((long) ar2.getId(), ar2.getRuleKey().repository(), ar2.getRuleKey().rule(), profile2.getRulesProfileUuid(), ar2.getSeverity(), ar2.getInheritance()),
tuple((long) ar3.getId(), ar3.getRuleKey().repository(), ar3.getRuleKey().rule(), profile2.getRulesProfileUuid(), ar3.getSeverity(), ar3.getInheritance()));
tuple((long)ar1.getId(), rule1.getId(), ar1.getRuleKey().repository(), ar1.getRuleKey().rule(), profile1.getRulesProfileUuid(), ar1.getSeverity(), ar1.getInheritance()),
tuple((long)ar2.getId(), rule1.getId(), ar2.getRuleKey().repository(), ar2.getRuleKey().rule(), profile2.getRulesProfileUuid(), ar2.getSeverity(), ar2.getInheritance()),
tuple((long)ar3.getId(), rule2.getId(), ar3.getRuleKey().repository(), ar3.getRuleKey().rule(), profile2.getRulesProfileUuid(), ar3.getSeverity(), ar3.getInheritance()));
}

@Test
@@ -649,11 +651,12 @@ public class ActiveRuleDaoTest {
Accumulator accumulator = new Accumulator();
underTest.scrollByIdsForIndexing(dbSession, asList((long) ar1.getId(), (long) ar2.getId()), accumulator);
assertThat(accumulator.list)
.extracting(IndexedActiveRuleDto::getId, IndexedActiveRuleDto::getRepository, IndexedActiveRuleDto::getKey, IndexedActiveRuleDto::getRuleProfileUuid,
IndexedActiveRuleDto::getSeverity)
.extracting(IndexedActiveRuleDto::getId,
IndexedActiveRuleDto::getRuleId, IndexedActiveRuleDto::getRepository, IndexedActiveRuleDto::getKey,
IndexedActiveRuleDto::getRuleProfileUuid, IndexedActiveRuleDto::getSeverity)
.containsExactlyInAnyOrder(
tuple((long) ar1.getId(), ar1.getRuleKey().repository(), ar1.getRuleKey().rule(), profile1.getRulesProfileUuid(), ar1.getSeverity()),
tuple((long) ar2.getId(), ar2.getRuleKey().repository(), ar2.getRuleKey().rule(), profile2.getRulesProfileUuid(), ar2.getSeverity()));
tuple((long)ar1.getId(), rule1.getId(), ar1.getRuleKey().repository(), ar1.getRuleKey().rule(), profile1.getRulesProfileUuid(), ar1.getSeverity()),
tuple((long)ar2.getId(), rule1.getId(), ar2.getRuleKey().repository(), ar2.getRuleKey().rule(), profile2.getRulesProfileUuid(), ar2.getSeverity()));
}

@Test

+ 15
- 10
server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDaoTest.java View File

@@ -700,7 +700,7 @@ public class RuleDaoTest {
RuleDefinitionDto r1 = db.rules().insert();
db.rules().insert();

underTest.scrollIndexingRulesByKeys(db.getSession(), singletonList(r1.getKey()), accumulator);
underTest.scrollIndexingRulesByKeys(db.getSession(), singletonList(r1.getId()), accumulator);

assertThat(accumulator.list)
.extracting(RuleForIndexingDto::getId, RuleForIndexingDto::getRuleKey)
@@ -713,7 +713,7 @@ public class RuleDaoTest {
RuleDefinitionDto r1 = db.rules().insert();
RuleDefinitionDto r2 = db.rules().insert(rule -> rule.setTemplateId(r1.getId()));

underTest.scrollIndexingRulesByKeys(db.getSession(), Arrays.asList(r1.getKey(), r2.getKey()), accumulator);
underTest.scrollIndexingRulesByKeys(db.getSession(), Arrays.asList(r1.getId(), r2.getId()), accumulator);

assertThat(accumulator.list).hasSize(2);
RuleForIndexingDto firstRule = accumulator.list.stream().filter(t -> t.getId().equals(r1.getId())).findFirst().get();
@@ -752,8 +752,9 @@ public class RuleDaoTest {
public void scrollIndexingRulesByKeys_scrolls_nothing_if_key_does_not_exist() {
Accumulator<RuleForIndexingDto> accumulator = new Accumulator<>();
db.rules().insert();
int nonExistingRuleId = 42;

underTest.scrollIndexingRulesByKeys(db.getSession(), singletonList(RuleKey.of("does", "not exist")), accumulator);
underTest.scrollIndexingRulesByKeys(db.getSession(), singletonList(nonExistingRuleId), accumulator);

assertThat(accumulator.list).isEmpty();
}
@@ -769,10 +770,12 @@ public class RuleDaoTest {
underTest.scrollIndexingRuleExtensions(db.getSession(), accumulator);

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

@Test
@@ -780,16 +783,18 @@ public class RuleDaoTest {
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.getRepositoryKey(), r1.getRuleKey());
RuleExtensionId r1ExtensionId = new RuleExtensionId(organization.getUuid(), r1.getId());
RuleDefinitionDto r2 = db.rules().insert();
db.rules().insertOrUpdateMetadata(r2, organization, r -> r.setTagsField("t1,t3"));

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

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

@Test
@@ -889,7 +894,7 @@ public class RuleDaoTest {
.setOldRuleKey(ruleKey));
}

private static class Accumulator<T> implements Consumer<T> {
private static class Accumulator<T> implements Consumer<T> {
private final List<T> list = new ArrayList<>();

@Override

+ 4
- 5
server/sonar-server/src/main/java/org/sonar/server/organization/ws/EnableSupportAction.java View File

@@ -20,7 +20,6 @@
package org.sonar.server.organization.ws;

import java.util.List;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.server.ws.Change;
import org.sonar.api.server.ws.Request;
@@ -87,9 +86,9 @@ public class EnableSupportAction implements OrganizationsWsAction {
if (isSupportDisabled(dbSession)) {
flagCurrentUserAsRoot(dbSession);
createDefaultMembersGroup(dbSession);
List<RuleKey> disabledTemplateAndCustomRuleKeys = disableTemplateRulesAndCustomRules(dbSession);
List<Integer> disabledTemplateAndCustomRuleIds = disableTemplateRulesAndCustomRules(dbSession);
enableFeature(dbSession);
ruleIndexer.commitAndIndex(dbSession, disabledTemplateAndCustomRuleKeys);
ruleIndexer.commitAndIndex(dbSession, disabledTemplateAndCustomRuleIds);
}
}
response.noContent();
@@ -140,7 +139,7 @@ public class EnableSupportAction implements OrganizationsWsAction {
permissionTemplateGroup.getTemplateId(), membersGroup.getId(), permissionTemplateGroup.getPermission()));
}

public List<RuleKey> disableTemplateRulesAndCustomRules(DbSession dbSession) {
public List<Integer> disableTemplateRulesAndCustomRules(DbSession dbSession) {
List<RuleDefinitionDto> rules = dbClient.ruleDao().selectAllDefinitions(dbSession).stream()
.filter(r -> r.isTemplate() || r.isCustomRule())
.collect(toList());
@@ -148,7 +147,7 @@ public class EnableSupportAction implements OrganizationsWsAction {
r.setStatus(RuleStatus.REMOVED);
dbClient.ruleDao().update(dbSession, r);
});
return rules.stream().map(RuleDefinitionDto::getKey).collect(toList());
return rules.stream().map(RuleDefinitionDto::getId).collect(toList());
}

private void enableFeature(DbSession dbSession) {

+ 7
- 8
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQProfileUpdateImpl.java View File

@@ -25,7 +25,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition;
import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.DbClient;
@@ -50,14 +49,14 @@ public class BuiltInQProfileUpdateImpl implements BuiltInQProfileUpdate {

public List<ActiveRuleChange> update(DbSession dbSession, BuiltInQProfile builtIn, RulesProfileDto rulesProfile) {
// Keep reference to all the activated rules before update
Set<RuleKey> deactivatedKeys = dbClient.activeRuleDao().selectByRuleProfile(dbSession, rulesProfile)
Set<Integer> deactivatedRuleIds = dbClient.activeRuleDao().selectByRuleProfile(dbSession, rulesProfile)
.stream()
.map(ActiveRuleDto::getRuleKey)
.map(ActiveRuleDto::getRuleId)
.collect(MoreCollectors.toHashSet());

Set<RuleKey> ruleKeys = Stream.concat(
deactivatedKeys.stream(),
builtIn.getActiveRules().stream().map(BuiltInQProfile.ActiveRule::getRuleKey))
Set<Integer> ruleKeys = Stream.concat(
deactivatedRuleIds.stream(),
builtIn.getActiveRules().stream().map(BuiltInQProfile.ActiveRule::getRuleId))
.collect(toSet());
RuleActivationContext context = ruleActivator.createContextForBuiltInProfile(dbSession, rulesProfile, ruleKeys);

@@ -65,7 +64,7 @@ public class BuiltInQProfileUpdateImpl implements BuiltInQProfileUpdate {
for (BuiltInQProfile.ActiveRule ar : builtIn.getActiveRules()) {
RuleActivation activation = convert(ar);
activations.add(activation);
deactivatedKeys.remove(activation.getRuleKey());
deactivatedRuleIds.remove(activation.getRuleId());
}

List<ActiveRuleChange> changes = new ArrayList<>();
@@ -74,7 +73,7 @@ public class BuiltInQProfileUpdateImpl implements BuiltInQProfileUpdate {
}

// these rules are not part of the built-in profile anymore
deactivatedKeys.forEach(ruleKey -> changes.addAll(ruleActivator.deactivate(dbSession, context, ruleKey, false)));
deactivatedRuleIds.forEach(ruleKey -> changes.addAll(ruleActivator.deactivate(dbSession, context, ruleKey, false)));

activeRuleIndexer.commitAndIndex(dbSession, changes);
return changes;

+ 7
- 8
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileResetImpl.java View File

@@ -24,7 +24,6 @@ import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.server.ServerSide;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
@@ -55,22 +54,22 @@ public class QProfileResetImpl implements QProfileReset {
checkArgument(!profile.isBuiltIn(), "Operation forbidden for built-in Quality Profile '%s'", profile.getKee());

BulkChangeResult result = new BulkChangeResult();
Set<RuleKey> rulesToBeDeactivated = new HashSet<>();
Set<Integer> rulesToBeDeactivated = new HashSet<>();
// Keep reference to all the activated rules before backup restore
for (ActiveRuleDto activeRuleDto : db.activeRuleDao().selectByProfile(dbSession, profile)) {
if (activeRuleDto.getInheritance() == null) {
// inherited rules can't be deactivated
rulesToBeDeactivated.add(activeRuleDto.getRuleKey());
rulesToBeDeactivated.add(activeRuleDto.getRuleId());
}
}
Set<RuleKey> ruleKeys = new HashSet<>(rulesToBeDeactivated);
activations.forEach(a -> ruleKeys.add(a.getRuleKey()));
Set<Integer> ruleKeys = new HashSet<>(rulesToBeDeactivated);
activations.forEach(a -> ruleKeys.add(a.getRuleId()));
RuleActivationContext context = activator.createContextForUserProfile(dbSession, profile, ruleKeys);

for (RuleActivation activation : activations) {
try {
List<ActiveRuleChange> changes = activator.activate(dbSession, activation, context);
rulesToBeDeactivated.remove(activation.getRuleKey());
rulesToBeDeactivated.remove(activation.getRuleId());
result.incrementSucceeded();
result.addChanges(changes);
} catch (BadRequestException e) {
@@ -80,9 +79,9 @@ public class QProfileResetImpl implements QProfileReset {
}

List<ActiveRuleChange> changes = new ArrayList<>(result.getChanges());
for (RuleKey ruleKey : rulesToBeDeactivated) {
for (Integer ruleId : rulesToBeDeactivated) {
try {
changes.addAll(activator.deactivate(dbSession, context, ruleKey, false));
changes.addAll(activator.deactivate(dbSession, context, ruleId, false));
} catch (BadRequestException e) {
// ignore, probably a rule inherited from parent that can't be deactivated
}

+ 1
- 2
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileRules.java View File

@@ -22,7 +22,6 @@ package org.sonar.server.qualityprofile;
import java.util.Collection;
import java.util.List;
import javax.annotation.Nullable;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.server.ServerSide;
import org.sonar.db.DbSession;
import org.sonar.db.qualityprofile.QProfileDto;
@@ -54,7 +53,7 @@ public interface QProfileRules {
*/
BulkChangeResult bulkActivateAndCommit(DbSession dbSession, QProfileDto profile, RuleQuery ruleQuery, @Nullable String severity);

List<ActiveRuleChange> deactivateAndCommit(DbSession dbSession, QProfileDto profile, Collection<RuleKey> ruleKeys);
List<ActiveRuleChange> deactivateAndCommit(DbSession dbSession, QProfileDto profile, Collection<Integer> ruleIds);

BulkChangeResult bulkDeactivateAndCommit(DbSession dbSession, QProfileDto profile, RuleQuery ruleQuery);


+ 11
- 12
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileRulesImpl.java View File

@@ -26,7 +26,6 @@ import java.util.List;
import java.util.Set;
import java.util.function.BiFunction;
import javax.annotation.Nullable;
import org.sonar.api.rule.RuleKey;
import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
@@ -57,8 +56,8 @@ public class QProfileRulesImpl implements QProfileRules {
public List<ActiveRuleChange> activateAndCommit(DbSession dbSession, QProfileDto profile, Collection<RuleActivation> activations) {
verifyNotBuiltIn(profile);

Set<RuleKey> ruleKeys = activations.stream().map(RuleActivation::getRuleKey).collect(MoreCollectors.toHashSet(activations.size()));
RuleActivationContext context = ruleActivator.createContextForUserProfile(dbSession, profile, ruleKeys);
Set<Integer> ruleIds = activations.stream().map(RuleActivation::getRuleId).collect(MoreCollectors.toHashSet(activations.size()));
RuleActivationContext context = ruleActivator.createContextForUserProfile(dbSession, profile, ruleIds);

List<ActiveRuleChange> changes = new ArrayList<>();
for (RuleActivation activation : activations) {
@@ -78,13 +77,13 @@ public class QProfileRulesImpl implements QProfileRules {
}

@Override
public List<ActiveRuleChange> deactivateAndCommit(DbSession dbSession, QProfileDto profile, Collection<RuleKey> ruleKeys) {
public List<ActiveRuleChange> deactivateAndCommit(DbSession dbSession, QProfileDto profile, Collection<Integer> ruleIds) {
verifyNotBuiltIn(profile);
RuleActivationContext context = ruleActivator.createContextForUserProfile(dbSession, profile, ruleKeys);
RuleActivationContext context = ruleActivator.createContextForUserProfile(dbSession, profile, ruleIds);

List<ActiveRuleChange> changes = new ArrayList<>();
for (RuleKey ruleKey : ruleKeys) {
changes.addAll(ruleActivator.deactivate(dbSession, context, ruleKey, false));
for (Integer ruleId : ruleIds) {
changes.addAll(ruleActivator.deactivate(dbSession, context, ruleId, false));
}
activeRuleIndexer.commitAndIndex(dbSession, changes);
return changes;
@@ -93,7 +92,7 @@ public class QProfileRulesImpl implements QProfileRules {
@Override
public BulkChangeResult bulkDeactivateAndCommit(DbSession dbSession, QProfileDto profile, RuleQuery ruleQuery) {
verifyNotBuiltIn(profile);
return doBulk(dbSession, profile, ruleQuery, (context, ruleDefinition) -> ruleActivator.deactivate(dbSession, context, ruleDefinition.getKey(), false));
return doBulk(dbSession, profile, ruleQuery, (context, ruleDefinition) -> ruleActivator.deactivate(dbSession, context, ruleDefinition.getId(), false));
}

@Override
@@ -117,12 +116,12 @@ public class QProfileRulesImpl implements QProfileRules {

private BulkChangeResult doBulk(DbSession dbSession, QProfileDto profile, RuleQuery ruleQuery, BiFunction<RuleActivationContext, RuleDefinitionDto, List<ActiveRuleChange>> fn) {
BulkChangeResult result = new BulkChangeResult();
Collection<RuleKey> ruleKeys = Sets.newHashSet(ruleIndex.searchAll(ruleQuery));
RuleActivationContext context = ruleActivator.createContextForUserProfile(dbSession, profile, ruleKeys);
Collection<Integer> ruleIds = Sets.newHashSet(ruleIndex.searchAll(ruleQuery));
RuleActivationContext context = ruleActivator.createContextForUserProfile(dbSession, profile, ruleIds);

for (RuleKey ruleKey : ruleKeys) {
for (Integer ruleId : ruleIds) {
try {
context.reset(ruleKey);
context.reset(ruleId);
RuleDefinitionDto ruleDefinition = context.getRule().get();
List<ActiveRuleChange> changes = fn.apply(context, ruleDefinition);
result.addChanges(changes);

+ 5
- 6
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileTreeImpl.java View File

@@ -23,7 +23,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.annotation.Nullable;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.utils.System2;
import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.DbClient;
@@ -81,8 +80,8 @@ public class QProfileTreeImpl implements QProfileTree {
db.qualityProfileDao().update(dbSession, profile);

List<OrgActiveRuleDto> parentActiveRules = db.activeRuleDao().selectByProfile(dbSession, parent);
Collection<RuleKey> ruleKeys = parentActiveRules.stream().map(ActiveRuleDto::getRuleKey).collect(MoreCollectors.toArrayList());
RuleActivationContext context = ruleActivator.createContextForUserProfile(dbSession, profile, ruleKeys);
Collection<Integer> ruleIds = parentActiveRules.stream().map(ActiveRuleDto::getRuleId).collect(MoreCollectors.toArrayList());
RuleActivationContext context = ruleActivator.createContextForUserProfile(dbSession, profile, ruleIds);

for (ActiveRuleDto parentActiveRule : parentActiveRules) {
try {
@@ -106,12 +105,12 @@ public class QProfileTreeImpl implements QProfileTree {
db.qualityProfileDao().update(dbSession, profile);

List<OrgActiveRuleDto> activeRules = db.activeRuleDao().selectByProfile(dbSession, profile);
Collection<RuleKey> ruleKeys = activeRules.stream().map(ActiveRuleDto::getRuleKey).collect(MoreCollectors.toArrayList());
RuleActivationContext context = ruleActivator.createContextForUserProfile(dbSession, profile, ruleKeys);
Collection<Integer> ruleIds = activeRules.stream().map(ActiveRuleDto::getRuleId).collect(MoreCollectors.toArrayList());
RuleActivationContext context = ruleActivator.createContextForUserProfile(dbSession, profile, ruleIds);

for (OrgActiveRuleDto activeRule : activeRules) {
if (ActiveRuleDto.INHERITED.equals(activeRule.getInheritance())) {
changes.addAll(ruleActivator.deactivate(dbSession, context, activeRule.getRuleKey(), true));
changes.addAll(ruleActivator.deactivate(dbSession, context, activeRule.getRuleId(), true));

} else if (ActiveRuleDto.OVERRIDES.equals(activeRule.getInheritance())) {
context.reset(activeRule.getRuleKey());

+ 10
- 0
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivationContext.java View File

@@ -66,6 +66,7 @@ class RuleActivationContext {

// the rules
private final Map<RuleKey, RuleWrapper> rulesByKey;
private final Map<Integer, RuleWrapper> rulesById;
private final Map<ActiveRuleKey, ActiveRuleWrapper> activeRulesByKey;

// cursor, moved in the tree of profiles
@@ -85,10 +86,12 @@ class RuleActivationContext {

// rules
this.rulesByKey = Maps.newHashMapWithExpectedSize(builder.rules.size());
this.rulesById = Maps.newHashMapWithExpectedSize(builder.rules.size());
ListMultimap<Integer, RuleParamDto> paramsByRuleId = builder.ruleParams.stream().collect(index(RuleParamDto::getRuleId));
for (RuleDefinitionDto rule : builder.rules) {
RuleWrapper wrapper = new RuleWrapper(rule, paramsByRuleId.get(rule.getId()));
rulesByKey.put(rule.getKey(), wrapper);
rulesById.put(rule.getId(), wrapper);
}

// profiles
@@ -174,6 +177,13 @@ class RuleActivationContext {
doSwitch(this.baseProfile, this.baseRulesProfile, ruleKey);
}

public void reset(Integer ruleId) {
this.cascading = false;
RuleWrapper ruleWrapper = rulesById.get(ruleId);
checkRequest(ruleWrapper != null, "Rule not found: %s", ruleId);
doSwitch(this.baseProfile, this.baseRulesProfile, ruleWrapper.get().getKey());
}

/**
* Moves cursor to a child profile
*/

+ 9
- 10
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java View File

@@ -29,7 +29,6 @@ import java.util.stream.Stream;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.server.ServerSide;
import org.sonar.api.server.rule.RuleParamType;
@@ -319,8 +318,8 @@ public class RuleActivator {
return activeRule.get();
}

public List<ActiveRuleChange> deactivate(DbSession dbSession, RuleActivationContext context, RuleKey ruleKey, boolean force) {
context.reset(ruleKey);
public List<ActiveRuleChange> deactivate(DbSession dbSession, RuleActivationContext context, int ruleId, boolean force) {
context.reset(ruleId);
return doDeactivate(dbSession, context, force);
}

@@ -364,13 +363,13 @@ public class RuleActivator {
return value;
}

public RuleActivationContext createContextForBuiltInProfile(DbSession dbSession, RulesProfileDto builtInProfile, Collection<RuleKey> ruleKeys) {
public RuleActivationContext createContextForBuiltInProfile(DbSession dbSession, RulesProfileDto builtInProfile, Collection<Integer> ruleIds) {
checkArgument(builtInProfile.isBuiltIn(), "Rules profile with UUID %s is not built-in", builtInProfile.getKee());

RuleActivationContext.Builder builder = new RuleActivationContext.Builder();

// load rules
List<RuleDefinitionDto> rules = completeWithRules(dbSession, builder, ruleKeys);
List<RuleDefinitionDto> rules = completeWithRules(dbSession, builder, ruleIds);

// load profiles
List<QProfileDto> aliasedBuiltInProfiles = db.qualityProfileDao().selectQProfilesByRuleProfile(dbSession, builtInProfile);
@@ -388,12 +387,12 @@ public class RuleActivator {
return builder.build();
}

public RuleActivationContext createContextForUserProfile(DbSession dbSession, QProfileDto profile, Collection<RuleKey> ruleKeys) {
public RuleActivationContext createContextForUserProfile(DbSession dbSession, QProfileDto profile, Collection<Integer> ruleIds) {
checkArgument(!profile.isBuiltIn(), "Profile with UUID %s is built-in", profile.getKee());
RuleActivationContext.Builder builder = new RuleActivationContext.Builder();

// load rules
List<RuleDefinitionDto> rules = completeWithRules(dbSession, builder, ruleKeys);
List<RuleDefinitionDto> rules = completeWithRules(dbSession, builder, ruleIds);

// load descendant profiles
List<QProfileDto> profiles = new ArrayList<>(db.qualityProfileDao().selectDescendants(dbSession, singleton(profile)));
@@ -413,10 +412,10 @@ public class RuleActivator {
return builder.build();
}

private List<RuleDefinitionDto> completeWithRules(DbSession dbSession, RuleActivationContext.Builder builder, Collection<RuleKey> ruleKeys) {
List<RuleDefinitionDto> rules = db.ruleDao().selectDefinitionByKeys(dbSession, ruleKeys);
private List<RuleDefinitionDto> completeWithRules(DbSession dbSession, RuleActivationContext.Builder builder, Collection<Integer> ruleIds) {
List<RuleDefinitionDto> rules = db.ruleDao().selectDefinitionByIds(dbSession, ruleIds);
builder.setRules(rules);
builder.setRuleParams(db.ruleDao().selectRuleParamsByRuleKeys(dbSession, ruleKeys));
builder.setRuleParams(db.ruleDao().selectRuleParamsByRuleIds(dbSession, ruleIds));
return rules;
}


+ 19
- 9
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/index/ActiveRuleDoc.java View File

@@ -31,6 +31,7 @@ import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_INHERITANCE;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_PROFILE_UUID;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_REPOSITORY;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_RULE_ID;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_RULE_KEY;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_SEVERITY;

@@ -41,7 +42,7 @@ public class ActiveRuleDoc extends BaseDoc {
setField(FIELD_ACTIVE_RULE_ID, String.valueOf(id));
}

public ActiveRuleDoc(Map<String,Object> source) {
public ActiveRuleDoc(Map<String, Object> source) {
super(source);
}

@@ -52,12 +53,12 @@ public class ActiveRuleDoc extends BaseDoc {

@Override
public String getRouting() {
return getRuleKeyAsString();
return getRuleIdAsString();
}

@Override
public String getParent() {
return getRuleKey().toString();
return getRuleIdAsString();
}

RuleKey getRuleKey() {
@@ -72,6 +73,21 @@ public class ActiveRuleDoc extends BaseDoc {
return getField(FIELD_ACTIVE_RULE_REPOSITORY);
}

ActiveRuleDoc setRuleKey(RuleKey ruleKey) {
setField(FIELD_ACTIVE_RULE_RULE_KEY, ruleKey.toString());
setField(FIELD_ACTIVE_RULE_REPOSITORY, ruleKey.repository());
return this;
}

private String getRuleIdAsString() {
return getField(FIELD_ACTIVE_RULE_RULE_ID);
}

ActiveRuleDoc setRuleId(int ruleId) {
setField(FIELD_ACTIVE_RULE_RULE_ID, String.valueOf(ruleId));
return this;
}

String getSeverity() {
return getNullableField(FIELD_ACTIVE_RULE_SEVERITY);
}
@@ -81,12 +97,6 @@ public class ActiveRuleDoc extends BaseDoc {
return this;
}

ActiveRuleDoc setRuleKey(RuleKey ruleKey) {
setField(FIELD_ACTIVE_RULE_RULE_KEY, ruleKey.toString());
setField(FIELD_ACTIVE_RULE_REPOSITORY, ruleKey.repository());
return this;
}

String getRuleProfileUuid() {
return getField(FIELD_ACTIVE_RULE_PROFILE_UUID);
}

+ 6
- 5
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/index/ActiveRuleIndexer.java View File

@@ -88,7 +88,7 @@ public class ActiveRuleIndexer implements ResilientIndexer {
public void commitAndIndex(DbSession dbSession, Collection<ActiveRuleChange> changes) {
List<EsQueueDto> items = changes.stream()
.map(ActiveRuleChange::getActiveRule)
.map(ar -> newQueueDto(String.valueOf(ar.getId()), ID_TYPE_ACTIVE_RULE_ID, ar.getRuleKey().toString()))
.map(ar -> newQueueDto(String.valueOf(ar.getId()), ID_TYPE_ACTIVE_RULE_ID, String.valueOf(ar.getRuleId())))
.collect(toArrayList());

dbClient.esQueueDao().insert(dbSession, items);
@@ -207,10 +207,11 @@ public class ActiveRuleIndexer implements ResilientIndexer {
}

private static IndexRequest newIndexRequest(IndexedActiveRuleDto dto) {
ActiveRuleDoc doc = new ActiveRuleDoc(dto.getId());
doc.setRuleProfileUuid(dto.getRuleProfileUuid());
doc.setSeverity(SeverityUtil.getSeverityFromOrdinal(dto.getSeverity()));
doc.setRuleKey(RuleKey.of(dto.getRepository(), dto.getKey()));
ActiveRuleDoc doc = new ActiveRuleDoc(dto.getId())
.setRuleId(dto.getRuleId())
.setRuleProfileUuid(dto.getRuleProfileUuid())
.setSeverity(SeverityUtil.getSeverityFromOrdinal(dto.getSeverity()))
.setRuleKey(RuleKey.of(dto.getRepository(), dto.getKey()));
// all the fields must be present, even if value is null
String inheritance = dto.getInheritance();
doc.setInheritance(inheritance == null ? ActiveRule.Inheritance.NONE.name() : inheritance);

+ 3
- 1
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/DeactivateRuleAction.java View File

@@ -27,6 +27,7 @@ import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.qualityprofile.QProfileDto;
import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.server.qualityprofile.QProfileRules;
import org.sonar.server.user.UserSession;

@@ -82,10 +83,11 @@ public class DeactivateRuleAction implements QProfileWsAction {
String qualityProfileKey = request.mandatoryParam(PARAM_KEY);
userSession.checkLoggedIn();
try (DbSession dbSession = dbClient.openSession(false)) {
RuleDefinitionDto rule = wsSupport.getRule(dbSession, ruleKey);
QProfileDto profile = wsSupport.getProfile(dbSession, QProfileReference.fromKey(qualityProfileKey));
OrganizationDto organization = wsSupport.getOrganization(dbSession, profile);
wsSupport.checkCanEdit(dbSession, organization, profile);
ruleActivator.deactivateAndCommit(dbSession, profile, singletonList(ruleKey));
ruleActivator.deactivateAndCommit(dbSession, profile, singletonList(rule.getId()));
}
response.noContent();
}

+ 7
- 1
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileWsSupport.java View File

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

import java.util.Optional;
import javax.annotation.Nullable;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.server.ServerSide;
import org.sonar.api.server.ws.WebService.NewAction;
import org.sonar.api.server.ws.WebService.NewParam;
@@ -29,6 +30,7 @@ import org.sonar.db.DbSession;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.permission.OrganizationPermission;
import org.sonar.db.qualityprofile.QProfileDto;
import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.db.user.GroupDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.organization.DefaultOrganizationProvider;
@@ -81,6 +83,11 @@ public class QProfileWsSupport {
"No organization with key '%s'", organizationOrDefaultKey);
}

public RuleDefinitionDto getRule(DbSession dbSession, RuleKey ruleKey) {
Optional<RuleDefinitionDto> ruleDefinitionDto = dbClient.ruleDao().selectDefinitionByKey(dbSession, ruleKey);
return checkFoundWithOptional(ruleDefinitionDto, "Rule with key '%s' not found", ruleKey);
}

/**
* Get the Quality profile specified by the reference {@code ref}.
*
@@ -153,5 +160,4 @@ public class QProfileWsSupport {
checkArgument(dbClient.organizationMemberDao().select(dbSession, organization.getUuid(), user.getId()).isPresent(),
"User '%s' is not member of organization '%s'", user.getLogin(), organization.getKey());
}

}

+ 32
- 21
server/sonar-server/src/main/java/org/sonar/server/rule/RegisterRules.java View File

@@ -108,13 +108,13 @@ public class RegisterRules implements Startable {
Profiler profiler = Profiler.create(LOG).startInfo("Register rules");
try (DbSession dbSession = dbClient.openSession(false)) {
Map<RuleKey, RuleDefinitionDto> allRules = loadRules(dbSession);
List<Integer> ruleIdsToIndex = new ArrayList<>();
Map<Integer, Set<SingleDeprecatedRuleKey>> existingDeprecatedRuleKeys = loadDeprecatedRuleKeys(dbSession);

RulesDefinition.Context context = defLoader.load();

List<RulesDefinition.ExtendedRepository> repositories = getRepositories(context);

List<RuleKey> keysToIndex = new ArrayList<>();
boolean orgsEnabled = organizationFlags.isEnabled(dbSession);

for (RulesDefinition.ExtendedRepository repoDef : repositories) {
@@ -132,10 +132,9 @@ public class RegisterRules implements Startable {
}
continue;
}
boolean relevantForIndex = registerRule(ruleDef, allRules, existingDeprecatedRuleKeys, dbSession);
if (relevantForIndex) {
keysToIndex.add(ruleKey);
}

registerRule(ruleDef, allRules, existingDeprecatedRuleKeys, dbSession)
.ifPresent(ruleIdsToIndex::add);
}
dbSession.commit();
}
@@ -144,12 +143,12 @@ public class RegisterRules implements Startable {
List<RuleDefinitionDto> removedRules = processRemainingDbRules(allRules.values(), dbSession);
List<ActiveRuleChange> changes = removeActiveRulesOnStillExistingRepositories(dbSession, removedRules, context);
dbSession.commit();
keysToIndex.addAll(removedRules.stream().map(RuleDefinitionDto::getKey).collect(Collectors.toList()));
ruleIdsToIndex.addAll(removedRules.stream().map(RuleDefinitionDto::getId).collect(Collectors.toList()));

persistRepositories(dbSession, context.repositories());
// FIXME lack of resiliency, active rules index is corrupted if rule index fails
// to be updated. Only a single DB commit should be executed.
ruleIndexer.commitAndIndex(dbSession, keysToIndex);
ruleIndexer.commitAndIndex(dbSession, ruleIdsToIndex);
activeRuleIndexer.commitAndIndex(dbSession, changes);
profiler.stopDebug();

@@ -172,8 +171,11 @@ public class RegisterRules implements Startable {
dbSession.commit();
}

private boolean registerRule(RulesDefinition.Rule ruleDef, Map<RuleKey, RuleDefinitionDto> allRules, Map<Integer,
Set<SingleDeprecatedRuleKey>> existingDeprecatedRuleKeys, DbSession session) {
/**
* @return the id of the rule if it's just been created or if it's been updated.
*/
private Optional<Integer> registerRule(RulesDefinition.Rule ruleDef, Map<RuleKey, RuleDefinitionDto> allRules,
Map<Integer, Set<SingleDeprecatedRuleKey>> existingDeprecatedRuleKeys, DbSession session) {
RuleKey ruleKey = RuleKey.of(ruleDef.repository().key(), ruleDef.key());

RuleDefinitionDto existingRule = allRules.remove(ruleKey);
@@ -187,9 +189,18 @@ public class RegisterRules implements Startable {
newRule = false;
}

boolean executeUpdate = mergeRule(ruleDef, rule);
executeUpdate |= mergeDebtDefinitions(ruleDef, rule);
executeUpdate |= mergeTags(ruleDef, rule);
boolean executeUpdate = false;
if (mergeRule(ruleDef, rule)) {
executeUpdate = true;
}

if (mergeDebtDefinitions(ruleDef, rule)) {
executeUpdate = true;
}

if (mergeTags(ruleDef, rule)) {
executeUpdate = true;
}

if (executeUpdate) {
update(session, rule);
@@ -197,7 +208,10 @@ public class RegisterRules implements Startable {

mergeParams(ruleDef, rule, session);
updateDeprecatedKeys(ruleDef, rule, existingDeprecatedRuleKeys, session);
return newRule || executeUpdate;
if (newRule || executeUpdate) {
return Optional.of(rule.getId());
}
return Optional.empty();
}

private Map<RuleKey, RuleDefinitionDto> loadRules(DbSession session) {
@@ -215,7 +229,6 @@ public class RegisterRules implements Startable {
.collect(Collectors.groupingBy(SingleDeprecatedRuleKey::getRuleId, toSet()));
}


private List<RulesDefinition.ExtendedRepository> getRepositories(RulesDefinition.Context context) {
List<RulesDefinition.ExtendedRepository> repositories = new ArrayList<>();
for (RulesDefinition.Repository repoDef : context.repositories()) {
@@ -466,13 +479,11 @@ public class RegisterRules implements Startable {

deprecatedRuleKeysToBeCreated
.forEach(r -> dbClient.ruleDao().insert(dbSession, new DeprecatedRuleKeyDto()
.setUuid(uuidFactory.create())
.setRuleId(rule.getId())
.setOldRepositoryKey(r.getOldRepositoryKey())
.setOldRuleKey(r.getOldRuleKey())
.setCreatedAt(system2.now())
)
);
.setUuid(uuidFactory.create())
.setRuleId(rule.getId())
.setOldRepositoryKey(r.getOldRepositoryKey())
.setOldRuleKey(r.getOldRuleKey())
.setCreatedAt(system2.now())));
}

private List<RuleDefinitionDto> processRemainingDbRules(Collection<RuleDefinitionDto> existingRules, DbSession session) {

+ 9
- 13
server/sonar-server/src/main/java/org/sonar/server/rule/RuleCreator.java View File

@@ -81,15 +81,11 @@ public class RuleCreator {
validateCustomRule(newRule, dbSession, templateKey);

RuleKey customRuleKey = RuleKey.of(templateRule.getRepositoryKey(), newRule.ruleKey());
Optional<RuleDefinitionDto> definition = loadRule(dbSession, customRuleKey);
int customRuleId = definition.map(d -> updateExistingRule(d, newRule, dbSession))
.orElseGet(() -> createCustomRule(customRuleKey, newRule, templateRule, dbSession));

Optional<RuleDefinitionDto> definition = loadRule(customRuleKey, dbSession);
if (definition.isPresent()) {
updateExistingRule(definition.get(), newRule, dbSession);
} else {
createCustomRule(customRuleKey, newRule, templateRule, dbSession);
}

ruleIndexer.commitAndIndex(dbSession, customRuleKey);
ruleIndexer.commitAndIndex(dbSession, customRuleId);
return customRuleKey;
}

@@ -151,11 +147,11 @@ public class RuleCreator {
}
}

private Optional<RuleDefinitionDto> loadRule(RuleKey ruleKey, DbSession dbSession) {
private Optional<RuleDefinitionDto> loadRule(DbSession dbSession, RuleKey ruleKey) {
return dbClient.ruleDao().selectDefinitionByKey(dbSession, ruleKey);
}

private RuleKey createCustomRule(RuleKey ruleKey, NewCustomRule newRule, RuleDto templateRuleDto, DbSession dbSession) {
private int createCustomRule(RuleKey ruleKey, NewCustomRule newRule, RuleDto templateRuleDto, DbSession dbSession) {
RuleDefinitionDto ruleDefinition = new RuleDefinitionDto()
.setRuleKey(ruleKey)
.setPluginKey(templateRuleDto.getPluginKey())
@@ -193,7 +189,7 @@ public class RuleCreator {
String customRuleParamValue = Strings.emptyToNull(newRule.parameter(templateRuleParamDto.getName()));
createCustomRuleParams(customRuleParamValue, ruleDefinition, templateRuleParamDto, dbSession);
}
return ruleKey;
return ruleDefinition.getId();
}

private void createCustomRuleParams(@Nullable String paramValue, RuleDefinitionDto ruleDto, RuleParamDto templateRuleParam, DbSession dbSession) {
@@ -205,7 +201,7 @@ public class RuleCreator {
dbClient.ruleDao().insertRuleParam(dbSession, ruleDto, ruleParamDto);
}

private RuleKey updateExistingRule(RuleDefinitionDto ruleDto, NewCustomRule newRule, DbSession dbSession) {
private int updateExistingRule(RuleDefinitionDto ruleDto, NewCustomRule newRule, DbSession dbSession) {
if (ruleDto.getStatus().equals(RuleStatus.REMOVED)) {
if (newRule.isPreventReactivation()) {
throw new ReactivationException(format("A removed rule with the key '%s' already exists", ruleDto.getKey().rule()), ruleDto.getKey());
@@ -217,7 +213,7 @@ public class RuleCreator {
} else {
throw new IllegalArgumentException(format("A rule with the key '%s' already exists", ruleDto.getKey().rule()));
}
return ruleDto.getKey();
return ruleDto.getId();
}

}

+ 1
- 1
server/sonar-server/src/main/java/org/sonar/server/rule/RuleUpdater.java View File

@@ -81,7 +81,7 @@ public class RuleUpdater {
apply(update, rule, userSession);
update(dbSession, rule);
updateParameters(dbSession, organization, update, rule);
ruleIndexer.commitAndIndex(dbSession, rule.getKey(), organization);
ruleIndexer.commitAndIndex(dbSession, rule.getId(), organization);

return true;
}

+ 12
- 2
server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleDoc.java View File

@@ -47,12 +47,21 @@ public class RuleDoc extends BaseDoc {

@Override
public String getId() {
return key().toString();
return idAsString();
}

private String idAsString() {
return getField(RuleIndexDefinition.FIELD_RULE_ID);
}

public RuleDoc setId(int ruleId) {
setField(RuleIndexDefinition.FIELD_RULE_ID, String.valueOf(ruleId));
return this;
}

@Override
public String getRouting() {
return keyAsString();
return idAsString();
}

@Override
@@ -206,6 +215,7 @@ public class RuleDoc extends BaseDoc {

public static RuleDoc of(RuleForIndexingDto dto) {
RuleDoc ruleDoc = new RuleDoc()
.setId(dto.getId())
.setKey(dto.getRuleKey().toString())
.setRepository(dto.getRepository())
.setInternalKey(dto.getInternalKey())

+ 20
- 5
server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleExtensionDoc.java View File

@@ -40,17 +40,30 @@ public class RuleExtensionDoc extends BaseDoc {

@Override
public String getId() {
return idOf(getRuleKey(), getScope());
return idOf(getRuleId(), getScope());
}

@Override
public String getRouting() {
return getRuleKey().toString();
return ruleIdAsString();
}

@Override
public String getParent() {
return getRuleKey().toString();
return ruleIdAsString();
}

public int getRuleId() {
return Integer.valueOf(ruleIdAsString());
}

private String ruleIdAsString() {
return getField(RuleIndexDefinition.FIELD_RULE_EXTENSION_RULE_ID);
}

public RuleExtensionDoc setRuleId(int ruleId) {
setField(RuleIndexDefinition.FIELD_RULE_EXTENSION_RULE_ID, String.valueOf(ruleId));
return this;
}

public RuleKey getRuleKey() {
@@ -82,6 +95,7 @@ public class RuleExtensionDoc extends BaseDoc {

public static RuleExtensionDoc of(RuleForIndexingDto rule) {
return new RuleExtensionDoc()
.setRuleId(rule.getId())
.setRuleKey(rule.getRuleKey())
.setScope(RuleExtensionScope.system())
.setTags(rule.getSystemTagsAsSet());
@@ -89,13 +103,14 @@ public class RuleExtensionDoc extends BaseDoc {

public static RuleExtensionDoc of(RuleExtensionForIndexingDto rule) {
return new RuleExtensionDoc()
.setRuleId(rule.getRuleId())
.setRuleKey(rule.getRuleKey())
.setScope(RuleExtensionScope.organization(rule.getOrganizationUuid()))
.setTags(rule.getTagsAsSet());
}

public static String idOf(RuleKey ruleKey, RuleExtensionScope scope) {
return ruleKey + "|" + scope.getScope();
public static String idOf(int ruleId, RuleExtensionScope scope) {
return ruleId + "|" + scope.getScope();
}

@Override

+ 5
- 6
server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndex.java View File

@@ -52,7 +52,6 @@ import org.elasticsearch.search.aggregations.bucket.terms.support.IncludeExclude
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.rule.Severity;
import org.sonar.api.rules.RuleType;
@@ -140,7 +139,7 @@ public class RuleIndex {
this.system2 = system2;
}

public SearchIdResult<RuleKey> search(RuleQuery query, SearchOptions options) {
public SearchIdResult<Integer> search(RuleQuery query, SearchOptions options) {
SearchRequestBuilder esSearch = client
.prepareSearch(INDEX_TYPE_RULE);

@@ -162,13 +161,13 @@ public class RuleIndex {
}

esSearch.setQuery(boolQuery().must(qb).filter(fb));
return new SearchIdResult<>(esSearch.get(), RuleKey::parse, system2.getDefaultTimeZone());
return new SearchIdResult<>(esSearch.get(), Integer::parseInt, system2.getDefaultTimeZone());
}

/**
* Return all keys matching the search query, without pagination nor facets
* Return all rule ids matching the search query, without pagination nor facets
*/
public Iterator<RuleKey> searchAll(RuleQuery query) {
public Iterator<Integer> searchAll(RuleQuery query) {
SearchRequestBuilder esSearch = client
.prepareSearch(INDEX_TYPE_RULE)
.setScroll(TimeValue.timeValueMinutes(SCROLL_TIME_IN_MINUTES));
@@ -184,7 +183,7 @@ public class RuleIndex {

esSearch.setQuery(boolQuery().must(qb).filter(fb));
SearchResponse response = esSearch.get();
return scrollIds(client, response, RuleKey::parse);
return scrollIds(client, response, Integer::parseInt);
}

/* Build main query (search based) */

+ 5
- 0
server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndexDefinition.java View File

@@ -42,6 +42,7 @@ public class RuleIndexDefinition implements IndexDefinition {
static final String INDEX = "rules";

public static final IndexType INDEX_TYPE_RULE = new IndexType(INDEX, "rule");
public static final String FIELD_RULE_ID = "id";
public static final String FIELD_RULE_KEY = "key";
public static final String FIELD_RULE_REPOSITORY = "repo";
public static final String FIELD_RULE_RULE_KEY = "ruleKey";
@@ -67,12 +68,14 @@ public class RuleIndexDefinition implements IndexDefinition {
public static final IndexType INDEX_TYPE_RULE_EXTENSION = new IndexType(INDEX, "ruleExtension");
/** The uuid of a {@link RuleExtensionScope} */
public static final String FIELD_RULE_EXTENSION_SCOPE = "scope";
public static final String FIELD_RULE_EXTENSION_RULE_ID = "ruleId";
public static final String FIELD_RULE_EXTENSION_RULE_KEY = "ruleKey";
public static final String FIELD_RULE_EXTENSION_TAGS = "tags";

// Active rule fields
public static final IndexType INDEX_TYPE_ACTIVE_RULE = new IndexType(INDEX, "activeRule");
public static final String FIELD_ACTIVE_RULE_ID = "id";
public static final String FIELD_ACTIVE_RULE_RULE_ID = "ruleId";
public static final String FIELD_ACTIVE_RULE_REPOSITORY = "repo";
public static final String FIELD_ACTIVE_RULE_INHERITANCE = "inheritance";
public static final String FIELD_ACTIVE_RULE_PROFILE_UUID = "ruleProfile";
@@ -118,6 +121,7 @@ public class RuleIndexDefinition implements IndexDefinition {
activeRuleMapping.setAttribute("_parent", ImmutableMap.of("type", INDEX_TYPE_RULE.getType()));

activeRuleMapping.keywordFieldBuilder(FIELD_ACTIVE_RULE_ID).disableNorms().build();
activeRuleMapping.keywordFieldBuilder(FIELD_ACTIVE_RULE_RULE_ID).disableNorms().build();
activeRuleMapping.keywordFieldBuilder(FIELD_ACTIVE_RULE_RULE_KEY).addSubFields(SORTABLE_ANALYZER).build();
activeRuleMapping.keywordFieldBuilder(FIELD_ACTIVE_RULE_REPOSITORY).build();
activeRuleMapping.keywordFieldBuilder(FIELD_ACTIVE_RULE_PROFILE_UUID).disableNorms().build();
@@ -137,6 +141,7 @@ public class RuleIndexDefinition implements IndexDefinition {
NewIndex.NewIndexType ruleMapping = index.createType(INDEX_TYPE_RULE.getType());
ruleMapping.setEnableSource(enableSource);

ruleMapping.keywordFieldBuilder(FIELD_RULE_ID).disableNorms().build();
ruleMapping.keywordFieldBuilder(FIELD_RULE_KEY).addSubFields(SORTABLE_ANALYZER).build();
ruleMapping.keywordFieldBuilder(FIELD_RULE_RULE_KEY).addSubFields(SORTABLE_ANALYZER).build();
ruleMapping.keywordFieldBuilder(FIELD_RULE_REPOSITORY).build();

+ 23
- 28
server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndexer.java View File

@@ -26,7 +26,6 @@ import java.util.List;
import java.util.Objects;
import java.util.Set;
import org.elasticsearch.action.index.IndexRequest;
import org.sonar.api.rule.RuleKey;
import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
@@ -82,21 +81,19 @@ public class RuleIndexer implements ResilientIndexer {

// index all organization extensions
if (uninitializedIndexTypes.contains(INDEX_TYPE_RULE_EXTENSION)) {
dbClient.ruleDao().scrollIndexingRuleExtensions(dbSession, dto ->
bulk.add(newRuleExtensionDocIndexRequest(dto))
);
dbClient.ruleDao().scrollIndexingRuleExtensions(dbSession, dto -> bulk.add(newRuleExtensionDocIndexRequest(dto)));
}

bulk.stop();
}
}

public void commitAndIndex(DbSession dbSession, RuleKey ruleKey) {
commitAndIndex(dbSession, singletonList(ruleKey));
public void commitAndIndex(DbSession dbSession, int ruleId) {
commitAndIndex(dbSession, singletonList(ruleId));
}

public void commitAndIndex(DbSession dbSession, Collection<RuleKey> ruleKeys) {
List<EsQueueDto> items = ruleKeys.stream()
public void commitAndIndex(DbSession dbSession, Collection<Integer> ruleIds) {
List<EsQueueDto> items = ruleIds.stream()
.map(RuleIndexer::createQueueDtoForRule)
.collect(MoreCollectors.toArrayList());

@@ -108,8 +105,8 @@ public class RuleIndexer implements ResilientIndexer {
/**
* Commit a change on a rule and its extension on the given organization
*/
public void commitAndIndex(DbSession dbSession, RuleKey ruleKey, OrganizationDto organization) {
List<EsQueueDto> items = asList(createQueueDtoForRule(ruleKey), createQueueDtoForRuleExtension(ruleKey, organization));
public void commitAndIndex(DbSession dbSession, int ruleId, OrganizationDto organization) {
List<EsQueueDto> items = asList(createQueueDtoForRule(ruleId), createQueueDtoForRuleExtension(ruleId, organization));
dbClient.esQueueDao().insert(dbSession, items);
dbSession.commit();
postCommit(dbSession, items);
@@ -137,23 +134,23 @@ public class RuleIndexer implements ResilientIndexer {
BulkIndexer bulkIndexer = createBulkIndexer(Size.REGULAR, new OneToOneResilientIndexingListener(dbClient, dbSession, items));
bulkIndexer.start();

Set<RuleKey> ruleKeys = items
Set<Integer> ruleIds = items
.stream()
.map(i -> RuleKey.parse(i.getDocId()))
.map(i -> Integer.parseInt(i.getDocId()))
.collect(toHashSet(items.size()));

dbClient.ruleDao().scrollIndexingRulesByKeys(dbSession, ruleKeys,
dbClient.ruleDao().scrollIndexingRulesByKeys(dbSession, ruleIds,
r -> {
bulkIndexer.add(newRuleDocIndexRequest(r));
bulkIndexer.add(newRuleExtensionDocIndexRequest(r));
ruleKeys.remove(r.getRuleKey());
ruleIds.remove(r.getId());
});

// the remaining items reference rows that don't exist in db. They must
// be deleted from index.
ruleKeys.forEach(ruleKey -> {
bulkIndexer.addDeletion(INDEX_TYPE_RULE, ruleKey.toString(), ruleKey.toString());
bulkIndexer.addDeletion(INDEX_TYPE_RULE_EXTENSION, RuleExtensionDoc.idOf(ruleKey, RuleExtensionScope.system()), ruleKey.toString());
ruleIds.forEach(ruleId -> {
bulkIndexer.addDeletion(INDEX_TYPE_RULE, ruleId.toString(), ruleId.toString());
bulkIndexer.addDeletion(INDEX_TYPE_RULE_EXTENSION, RuleExtensionDoc.idOf(ruleId, RuleExtensionScope.system()), ruleId.toString());
});

return bulkIndexer.stop();
@@ -172,17 +169,14 @@ public class RuleIndexer implements ResilientIndexer {
// only index requests, no deletion requests.
// Deactivated users are not deleted but updated.
r -> {
RuleExtensionId docId = new RuleExtensionId(r.getOrganizationUuid(), r.getPluginName(), r.getPluginRuleKey());
RuleExtensionId docId = new RuleExtensionId(r.getOrganizationUuid(), r.getRuleId());
docIds.remove(docId);
bulkIndexer.add(newRuleExtensionDocIndexRequest(r));
});

// the remaining items reference rows that don't exist in db. They must
// be deleted from index.
docIds.forEach(docId -> {
RuleKey ruleKey = RuleKey.of(docId.getRepositoryName(), docId.getRuleKey());
bulkIndexer.addDeletion(INDEX_TYPE_RULE_EXTENSION, docId.getId(), ruleKey.toString());
});
docIds.forEach(docId -> bulkIndexer.addDeletion(INDEX_TYPE_RULE_EXTENSION, docId.getId(), docId.getId()));

return bulkIndexer.stop();
}
@@ -191,7 +185,7 @@ public class RuleIndexer implements ResilientIndexer {
RuleDoc doc = RuleDoc.of(ruleForIndexingDto);

return new IndexRequest(INDEX_TYPE_RULE.getIndex(), INDEX_TYPE_RULE.getType())
.id(doc.key().toString())
.id(doc.getId())
.routing(doc.getRouting())
.source(doc.getFields());
}
@@ -228,13 +222,14 @@ public class RuleIndexer implements ResilientIndexer {
return new RuleExtensionId(esQueueDto.getDocId());
}

private static EsQueueDto createQueueDtoForRule(RuleKey ruleKey) {
return EsQueueDto.create("rules/rule", ruleKey.toString(), null, ruleKey.toString());
private static EsQueueDto createQueueDtoForRule(int ruleId) {
String docId = String.valueOf(ruleId);
return EsQueueDto.create("rules/rule", docId, null, docId);
}

private static EsQueueDto createQueueDtoForRuleExtension(RuleKey ruleKey, OrganizationDto organization) {
String docId = RuleExtensionDoc.idOf(ruleKey, RuleExtensionScope.organization(organization));
return EsQueueDto.create("rules/ruleExtension", docId, null, ruleKey.toString());
private static EsQueueDto createQueueDtoForRuleExtension(int ruleId, OrganizationDto organization) {
String docId = RuleExtensionDoc.idOf(ruleId, RuleExtensionScope.organization(organization));
return EsQueueDto.create("rules/ruleExtension", docId, null, String.valueOf(ruleId));
}

}

+ 1
- 1
server/sonar-server/src/main/java/org/sonar/server/rule/ws/DeleteAction.java View File

@@ -86,7 +86,7 @@ public class DeleteAction implements RulesWsAction {
rule.setUpdatedAt(system2.now());
dbClient.ruleDao().update(dbSession, rule);

ruleIndexer.commitAndIndex(dbSession, ruleKey);
ruleIndexer.commitAndIndex(dbSession, rule.getId());
}
}
}

+ 6
- 8
server/sonar-server/src/main/java/org/sonar/server/rule/ws/SearchAction.java View File

@@ -36,7 +36,6 @@ import java.util.Objects;
import java.util.Set;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.rule.Severity;
import org.sonar.api.rules.RuleType;
@@ -352,19 +351,18 @@ public class SearchAction implements RulesWsAction {
}

private SearchResult doSearch(DbSession dbSession, RuleQuery query, SearchOptions context) {
SearchIdResult<RuleKey> result = ruleIndex.search(query, context);
List<RuleKey> ruleKeys = result.getIds();
SearchIdResult<Integer> result = ruleIndex.search(query, context);
List<Integer> ruleIds = result.getIds();
// rule order is managed by ES
Map<RuleKey, RuleDto> rulesByRuleKey = Maps.uniqueIndex(
dbClient.ruleDao().selectByKeys(dbSession, query.getOrganization(), ruleKeys), RuleDto::getKey);
Map<Integer, RuleDto> rulesByRuleKey = Maps.uniqueIndex(
dbClient.ruleDao().selectByIds(dbSession, query.getOrganization().getUuid(), ruleIds), RuleDto::getId);
List<RuleDto> rules = new ArrayList<>();
for (RuleKey ruleKey : ruleKeys) {
RuleDto rule = rulesByRuleKey.get(ruleKey);
for (Integer ruleId : ruleIds) {
RuleDto rule = rulesByRuleKey.get(ruleId);
if (rule != null) {
rules.add(rule);
}
}
List<Integer> ruleIds = rules.stream().map(RuleDto::getId).collect(MoreCollectors.toList());
List<Integer> templateRuleIds = rules.stream()
.map(RuleDto::getTemplateId)
.filter(Objects::nonNull)

+ 1
- 1
server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexTest.java View File

@@ -1199,7 +1199,7 @@ public class IssueIndexTest {
public void list_tags() {
RuleDefinitionDto r1 = db.rules().insert();
RuleDefinitionDto r2 = db.rules().insert();
ruleIndexer.commitAndIndex(db.getSession(), asList(r1.getKey(), r2.getKey()));
ruleIndexer.commitAndIndex(db.getSession(), asList(r1.getId(), r2.getId()));

OrganizationDto org = db.organizations().insert();
OrganizationDto anotherOrg = db.organizations().insert();

+ 8
- 8
server/sonar-server/src/test/java/org/sonar/server/issue/ws/TagsActionTest.java View File

@@ -93,14 +93,14 @@ public class TagsActionTest {
public void return_tags_from_rules() {
userSession.logIn();
RuleDefinitionDto r = dbTester.rules().insert(setSystemTags("tag1"));
ruleIndexer.commitAndIndex(dbTester.getSession(), r.getKey());
ruleIndexer.commitAndIndex(dbTester.getSession(), r.getId());
dbTester.rules().insertOrUpdateMetadata(r, organization, setTags("tag2"));
ruleIndexer.commitAndIndex(dbTester.getSession(), r.getKey(), organization);
ruleIndexer.commitAndIndex(dbTester.getSession(), r.getId(), organization);

RuleDefinitionDto r2 = dbTester.rules().insert(setSystemTags("tag3"));
ruleIndexer.commitAndIndex(dbTester.getSession(), r2.getKey());
ruleIndexer.commitAndIndex(dbTester.getSession(), r2.getId());
dbTester.rules().insertOrUpdateMetadata(r2, organization, setTags("tag4", "tag5"));
ruleIndexer.commitAndIndex(dbTester.getSession(), r2.getKey(), organization);
ruleIndexer.commitAndIndex(dbTester.getSession(), r2.getId(), organization);

String result = ws.newRequest()
.setParam("organization", organization.getKey())
@@ -115,9 +115,9 @@ public class TagsActionTest {
insertIssueWithBrowsePermission(insertRuleWithoutTags(), "tag3", "tag4", "tag5");

RuleDefinitionDto r = dbTester.rules().insert(setSystemTags("tag6"));
ruleIndexer.commitAndIndex(dbTester.getSession(), r.getKey());
ruleIndexer.commitAndIndex(dbTester.getSession(), r.getId());
dbTester.rules().insertOrUpdateMetadata(r, organization, setTags("tag7"));
ruleIndexer.commitAndIndex(dbTester.getSession(), r.getKey(), organization);
ruleIndexer.commitAndIndex(dbTester.getSession(), r.getId(), organization);

String result = ws.newRequest()
.setParam("organization", organization.getKey())
@@ -190,9 +190,9 @@ public class TagsActionTest {
insertIssueWithBrowsePermission(insertRuleWithoutTags(), "convention");

RuleDefinitionDto r = dbTester.rules().insert(setSystemTags("cwe"));
ruleIndexer.commitAndIndex(dbTester.getSession(), r.getKey());
ruleIndexer.commitAndIndex(dbTester.getSession(), r.getId());
dbTester.rules().insertOrUpdateMetadata(r, organization, setTags("security"));
ruleIndexer.commitAndIndex(dbTester.getSession(), r.getKey(), organization);
ruleIndexer.commitAndIndex(dbTester.getSession(), r.getId(), organization);

String result = ws.newRequest()
.setParam("organization", organization.getKey())

+ 3
- 4
server/sonar-server/src/test/java/org/sonar/server/organization/ws/EnableSupportActionTest.java View File

@@ -28,7 +28,6 @@ import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.ArgumentCaptor;
import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.server.ws.WebService;
import org.sonar.db.DbTester;
@@ -194,10 +193,10 @@ public class EnableSupportActionTest {
tuple(custom.getKey(), RuleStatus.REMOVED));

@SuppressWarnings("unchecked")
Class<ArrayList<RuleKey>> listClass = (Class<ArrayList<RuleKey>>) (Class) ArrayList.class;
ArgumentCaptor<ArrayList<RuleKey>> indexedRuleKeys = ArgumentCaptor.forClass(listClass);
Class<ArrayList<Integer>> listClass = (Class<ArrayList<Integer>>) (Class) ArrayList.class;
ArgumentCaptor<ArrayList<Integer>> indexedRuleKeys = ArgumentCaptor.forClass(listClass);
verify(ruleIndexer).commitAndIndex(any(), indexedRuleKeys.capture());
assertThat(indexedRuleKeys.getValue()).containsExactlyInAnyOrder(template.getKey(), custom.getKey());
assertThat(indexedRuleKeys.getValue()).containsExactlyInAnyOrder(template.getId(), custom.getId());
}

@Test

+ 2
- 1
server/sonar-server/src/test/java/org/sonar/server/platform/BackendCleanupTest.java View File

@@ -19,6 +19,7 @@
*/
package org.sonar.server.platform;

import java.util.Random;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -137,7 +138,7 @@ public class BackendCleanupTest {
}

private static RuleDoc newRuleDoc() {
return new RuleDoc().setKey(RuleTesting.XOO_X1.toString()).setRepository(RuleTesting.XOO_X1.repository());
return new RuleDoc().setId(new Random().nextInt(942)).setKey(RuleTesting.XOO_X1.toString()).setRepository(RuleTesting.XOO_X1.repository());
}

private ComponentDoc newComponentDoc() {

+ 10
- 10
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileComparisonTest.java View File

@@ -34,7 +34,7 @@ import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.qualityprofile.QProfileDto;
import org.sonar.db.rule.RuleDto;
import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.db.rule.RuleParamDto;
import org.sonar.db.rule.RuleTesting;
import org.sonar.server.es.EsTester;
@@ -65,8 +65,8 @@ public class QProfileComparisonTest {
private QProfileRules qProfileRules;
private QProfileComparison comparison;

private RuleDto xooRule1;
private RuleDto xooRule2;
private RuleDefinitionDto xooRule1;
private RuleDefinitionDto xooRule2;
private QProfileDto left;
private QProfileDto right;

@@ -80,13 +80,13 @@ public class QProfileComparisonTest {
qProfileRules = new QProfileRulesImpl(db, ruleActivator, ruleIndex, activeRuleIndexer);
comparison = new QProfileComparison(db);

xooRule1 = RuleTesting.newXooX1().setSeverity("MINOR");
xooRule2 = RuleTesting.newXooX2().setSeverity("MAJOR");
db.ruleDao().insert(dbSession, xooRule1.getDefinition());
db.ruleDao().insert(dbSession, xooRule2.getDefinition());
db.ruleDao().insertRuleParam(dbSession, xooRule1.getDefinition(), RuleParamDto.createFor(xooRule1.getDefinition())
xooRule1 = RuleTesting.newXooX1().setSeverity("MINOR").getDefinition();
xooRule2 = RuleTesting.newXooX2().setSeverity("MAJOR").getDefinition();
db.ruleDao().insert(dbSession, xooRule1);
db.ruleDao().insert(dbSession, xooRule2);
db.ruleDao().insertRuleParam(dbSession, xooRule1, RuleParamDto.createFor(xooRule1)
.setName("max").setType(RuleParamType.INTEGER.type()));
db.ruleDao().insertRuleParam(dbSession, xooRule1.getDefinition(), RuleParamDto.createFor(xooRule1.getDefinition())
db.ruleDao().insertRuleParam(dbSession, xooRule1, RuleParamDto.createFor(xooRule1)
.setName("min").setType(RuleParamType.INTEGER.type()));

left = QProfileTesting.newXooP1("org-123");
@@ -177,7 +177,7 @@ public class QProfileComparisonTest {
@Test
public void compare_modified_severity() {
qProfileRules.activateAndCommit(dbSession, left, singleton(RuleActivation.create(xooRule1.getId(), xooRule1.getKey(), Severity.CRITICAL, null)));
qProfileRules.activateAndCommit(dbSession, right, singleton(RuleActivation.create(xooRule2.getId(), xooRule1.getKey(), Severity.BLOCKER, null)));
qProfileRules.activateAndCommit(dbSession, right, singleton(RuleActivation.create(xooRule1.getId(), xooRule1.getKey(), Severity.BLOCKER, null)));

QProfileComparisonResult result = comparison.compare(dbSession, left, right);
assertThat(result.left().getKee()).isEqualTo(left.getKee());

+ 1
- 10
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileRuleImplTest.java View File

@@ -437,15 +437,6 @@ public class QProfileRuleImplTest {
assertThat(changes).hasSize(0);
}

@Test
public void deactivation_fails_if_rule_does_not_exist() {
RuleDefinitionDto rule = createRule();
QProfileDto profile = createProfile(rule);
RuleKey ruleKey = RuleKey.parse("unknown:xxx");

expectFailure("Rule not found: " + ruleKey, () -> underTest.deactivateAndCommit(db.getSession(), profile, singleton(ruleKey)));
}

@Test
public void deactivate_rule_that_has_REMOVED_status() {
RuleDefinitionDto rule = createRule();
@@ -883,7 +874,7 @@ public class QProfileRuleImplTest {
}

private List<ActiveRuleChange> deactivate(QProfileDto profile, RuleDefinitionDto rule) {
return underTest.deactivateAndCommit(db.getSession(), profile, singleton(rule.getKey()));
return underTest.deactivateAndCommit(db.getSession(), profile, singleton(rule.getId()));
}

private List<ActiveRuleChange> activate(QProfileDto profile, RuleActivation activation) {

+ 2
- 1
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/index/ActiveRuleIndexerTest.java View File

@@ -39,6 +39,7 @@ import org.sonar.server.es.EsTester;
import org.sonar.server.qualityprofile.ActiveRuleChange;
import org.sonar.server.rule.index.RuleIndexDefinition;

import static java.lang.String.valueOf;
import static java.util.Arrays.asList;
import static java.util.Arrays.stream;
import static java.util.Collections.emptySet;
@@ -124,7 +125,7 @@ public class ActiveRuleIndexerTest {

commitAndIndex(rule1, ar);

EsQueueDto expectedItem = EsQueueDto.create(INDEX_TYPE_ACTIVE_RULE.format(), "" + ar.getId(), "activeRuleId", ar.getRuleKey().toString());
EsQueueDto expectedItem = EsQueueDto.create(INDEX_TYPE_ACTIVE_RULE.format(), "" + ar.getId(), "activeRuleId", valueOf(ar.getRuleId()));
assertThatEsQueueContainsExactly(expectedItem);
}


+ 6
- 6
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ChangeParentActionTest.java View File

@@ -146,7 +146,7 @@ public class ChangeParentActionTest {

RuleDefinitionDto rule1 = createRule();
createActiveRule(rule1, parent1);
ruleIndexer.commitAndIndex(dbSession, rule1.getKey());
ruleIndexer.commitAndIndex(dbSession, rule1.getId());
activeRuleIndexer.indexOnStartup(emptySet());

assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, child.getKee())).isEmpty();
@@ -176,7 +176,7 @@ public class ChangeParentActionTest {
RuleDefinitionDto rule2 = createRule();
createActiveRule(rule1, parent1);
createActiveRule(rule2, parent2);
ruleIndexer.commitAndIndex(dbSession, asList(rule1.getKey(), rule2.getKey()));
ruleIndexer.commitAndIndex(dbSession, asList(rule1.getId(), rule2.getId()));
activeRuleIndexer.indexOnStartup(emptySet());

// Set parent 1
@@ -204,7 +204,7 @@ public class ChangeParentActionTest {

RuleDefinitionDto rule1 = createRule();
createActiveRule(rule1, parent);
ruleIndexer.commitAndIndex(dbSession, rule1.getKey());
ruleIndexer.commitAndIndex(dbSession, rule1.getId());
activeRuleIndexer.indexOnStartup(emptySet());

// Set parent
@@ -232,7 +232,7 @@ public class ChangeParentActionTest {
RuleDefinitionDto rule2 = createRule();
createActiveRule(rule1, parent1);
createActiveRule(rule2, parent2);
ruleIndexer.commitAndIndex(dbSession, rule1.getKey());
ruleIndexer.commitAndIndex(dbSession, rule1.getId());
activeRuleIndexer.indexOnStartup(emptySet());

assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, child.getKee())).isEmpty();
@@ -291,7 +291,7 @@ public class ChangeParentActionTest {

RuleDefinitionDto rule1 = createRule();
createActiveRule(rule1, parent);
ruleIndexer.commitAndIndex(dbSession, rule1.getKey());
ruleIndexer.commitAndIndex(dbSession, rule1.getId());
activeRuleIndexer.indexOnStartup(emptySet());

assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, child.getKee())).isEmpty();
@@ -321,7 +321,7 @@ public class ChangeParentActionTest {
RuleDefinitionDto rule2 = createRule();
createActiveRule(rule1, parent1);
createActiveRule(rule2, parent2);
ruleIndexer.commitAndIndex(dbSession, asList(rule1.getKey(), rule2.getKey()));
ruleIndexer.commitAndIndex(dbSession, asList(rule1.getId(), rule2.getId()));
activeRuleIndexer.indexOnStartup(emptySet());
// Set parent 1
qProfileTree.setParentAndCommit(dbSession, child, parent1);

+ 1
- 1
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CreateActionTest.java View File

@@ -251,7 +251,7 @@ public class CreateActionTest {
private void insertRule(RuleDefinitionDto ruleDto) {
dbClient.ruleDao().insert(dbSession, ruleDto);
dbSession.commit();
ruleIndexer.commitAndIndex(dbSession, ruleDto.getKey());
ruleIndexer.commitAndIndex(dbSession, ruleDto.getId());
}

private CreateWsResponse executeRequest(String name, String language) {

+ 21
- 14
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/DeactivateRuleActionTest.java View File

@@ -34,6 +34,7 @@ import org.sonar.db.DbTester;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.permission.OrganizationPermission;
import org.sonar.db.qualityprofile.QProfileDto;
import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.db.rule.RuleTesting;
import org.sonar.db.user.UserDto;
import org.sonar.server.exceptions.BadRequestException;
@@ -95,20 +96,19 @@ public class DeactivateRuleActionTest {
public void deactivate_rule_in_default_organization() {
userSession.logIn(db.users().insertUser()).addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, defaultOrganization);
QProfileDto qualityProfile = db.qualityProfiles().insert(defaultOrganization);
RuleKey ruleKey = RuleTesting.randomRuleKey();
RuleDefinitionDto rule = db.rules().insert(RuleTesting.randomRuleKey());
TestRequest request = ws.newRequest()
.setMethod("POST")
.setParam(PARAM_RULE, ruleKey.toString())
.setParam(PARAM_RULE, rule.getKey().toString())
.setParam(PARAM_KEY, qualityProfile.getKee());

TestResponse response = request.execute();

assertThat(response.getStatus()).isEqualTo(HttpURLConnection.HTTP_NO_CONTENT);
Class<Collection<RuleKey>> collectionClass = (Class<Collection<RuleKey>>) (Class) Collection.class;
ArgumentCaptor<Collection<RuleKey>> ruleKeyCaptor = ArgumentCaptor.forClass(collectionClass);
ArgumentCaptor<Collection<Integer>> ruleIdCaptor = ruleIdCollectionCaptor();
ArgumentCaptor<QProfileDto> qProfileDtoCaptor = ArgumentCaptor.forClass(QProfileDto.class);
verify(qProfileRules).deactivateAndCommit(any(DbSession.class), qProfileDtoCaptor.capture(), ruleKeyCaptor.capture());
assertThat(ruleKeyCaptor.getValue()).containsExactly(ruleKey);
verify(qProfileRules).deactivateAndCommit(any(DbSession.class), qProfileDtoCaptor.capture(), ruleIdCaptor.capture());
assertThat(ruleIdCaptor.getValue()).containsExactly(rule.getId());
assertThat(qProfileDtoCaptor.getValue().getKee()).isEqualTo(qualityProfile.getKee());
}

@@ -116,21 +116,20 @@ public class DeactivateRuleActionTest {
public void deactivate_rule_in_specific_organization() {
userSession.logIn(db.users().insertUser()).addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, organization);
QProfileDto qualityProfile = db.qualityProfiles().insert(organization);
RuleKey ruleKey = RuleTesting.randomRuleKey();
RuleDefinitionDto rule = db.rules().insert(RuleTesting.randomRuleKey());
TestRequest request = ws.newRequest()
.setMethod("POST")
.setParam("organization", organization.getKey())
.setParam(PARAM_RULE, ruleKey.toString())
.setParam(PARAM_RULE, rule.getKey().toString())
.setParam(PARAM_KEY, qualityProfile.getKee());

TestResponse response = request.execute();

assertThat(response.getStatus()).isEqualTo(HttpURLConnection.HTTP_NO_CONTENT);
Class<Collection<RuleKey>> collectionClass = (Class<Collection<RuleKey>>) (Class) Collection.class;
ArgumentCaptor<Collection<RuleKey>> ruleKeyCaptor = ArgumentCaptor.forClass(collectionClass);
ArgumentCaptor<Collection<Integer>> ruleIdCaptor = ruleIdCollectionCaptor();
ArgumentCaptor<QProfileDto> qProfileDtoCaptor = ArgumentCaptor.forClass(QProfileDto.class);
verify(qProfileRules).deactivateAndCommit(any(DbSession.class), qProfileDtoCaptor.capture(), ruleKeyCaptor.capture());
assertThat(ruleKeyCaptor.getValue()).containsExactly(ruleKey);
verify(qProfileRules).deactivateAndCommit(any(DbSession.class), qProfileDtoCaptor.capture(), ruleIdCaptor.capture());
assertThat(ruleIdCaptor.getValue()).containsExactly(rule.getId());
assertThat(qProfileDtoCaptor.getValue().getKee()).isEqualTo(qualityProfile.getKee());
}

@@ -141,6 +140,7 @@ public class DeactivateRuleActionTest {
db.qualityProfiles().addUserPermission(qualityProfile, user);
userSession.logIn(user);
RuleKey ruleKey = RuleTesting.randomRuleKey();
db.rules().insert(ruleKey);

ws.newRequest()
.setMethod("POST")
@@ -166,11 +166,12 @@ public class DeactivateRuleActionTest {

@Test
public void fail_if_not_organization_quality_profile_administrator() {
RuleDefinitionDto rule = db.rules().insert();
userSession.logIn(db.users().insertUser()).addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, defaultOrganization);
QProfileDto qualityProfile = db.qualityProfiles().insert(organization);
TestRequest request = ws.newRequest()
.setMethod("POST")
.setParam(PARAM_RULE, RuleTesting.newRuleDto().getKey().toString())
.setParam(PARAM_RULE, rule.getKey().toString())
.setParam(PARAM_KEY, qualityProfile.getKee());

expectedException.expect(ForbiddenException.class);
@@ -180,16 +181,22 @@ public class DeactivateRuleActionTest {

@Test
public void fail_deactivate_if_built_in_profile() {
RuleDefinitionDto rule = db.rules().insert();
userSession.logIn(db.users().insertUser()).addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, defaultOrganization);

QProfileDto qualityProfile = db.qualityProfiles().insert(defaultOrganization, profile -> profile.setIsBuiltIn(true));
TestRequest request = ws.newRequest()
.setMethod("POST")
.setParam(PARAM_RULE, RuleTesting.newRuleDto().getKey().toString())
.setParam(PARAM_RULE, rule.getKey().toString())
.setParam(PARAM_KEY, qualityProfile.getKee());

expectedException.expect(BadRequestException.class);

request.execute();
}

private static ArgumentCaptor<Collection<Integer>> ruleIdCollectionCaptor() {
Class<Collection<Integer>> collectionClass = (Class<Collection<Integer>>) (Class) Collection.class;
return ArgumentCaptor.forClass(collectionClass);
}
}

+ 3
- 3
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/InheritanceActionTest.java View File

@@ -158,7 +158,7 @@ public class InheritanceActionTest {
RuleDefinitionDto rule1 = dbTester.rules().insert();
RuleDefinitionDto rule2 = dbTester.rules().insert();
RuleDefinitionDto rule3 = dbTester.rules().insert();
ruleIndexer.commitAndIndex(dbTester.getSession(), asList(rule1.getKey(), rule2.getKey(), rule3.getKey()));
ruleIndexer.commitAndIndex(dbTester.getSession(), asList(rule1.getId(), rule2.getId(), rule3.getId()));

QProfileDto parent = dbTester.qualityProfiles().insert(organization);
dbTester.qualityProfiles().activateRule(parent, rule1);
@@ -190,7 +190,7 @@ public class InheritanceActionTest {
@Test
public void inheritance_ignores_removed_rules() throws Exception {
RuleDefinitionDto rule = dbTester.rules().insert(r -> r.setStatus(RuleStatus.REMOVED));
ruleIndexer.commitAndIndex(dbTester.getSession(), rule.getKey());
ruleIndexer.commitAndIndex(dbTester.getSession(), rule.getId());

QProfileDto profile = dbTester.qualityProfiles().insert(organization);
dbTester.qualityProfiles().activateRule(profile, rule);
@@ -265,7 +265,7 @@ public class InheritanceActionTest {
.setUpdatedAt(now)
.setCreatedAt(now);
dbClient.ruleDao().insert(dbSession, rule);
ruleIndexer.commitAndIndex(dbSession, rule.getKey());
ruleIndexer.commitAndIndex(dbSession, rule.getId());
return rule;
}


+ 5
- 5
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest.java View File

@@ -112,7 +112,7 @@ public class QProfilesWsMediumTest {
QProfileDto profile = createProfile("java");
RuleDefinitionDto rule = createRule(profile.getLanguage(), "toto");
createActiveRule(rule, profile);
ruleIndexer.commitAndIndex(dbSession, rule.getKey());
ruleIndexer.commitAndIndex(dbSession, rule.getId());
activeRuleIndexer.indexOnStartup(activeRuleIndexer.getIndexTypes());

// 0. Assert No Active Rule for profile
@@ -211,7 +211,7 @@ public class QProfilesWsMediumTest {
public void activate_rule() {
QProfileDto profile = createProfile("java");
RuleDefinitionDto rule = createRule(profile.getLanguage(), "toto");
ruleIndexer.commitAndIndex(dbSession, rule.getKey());
ruleIndexer.commitAndIndex(dbSession, rule.getId());

// 0. Assert No Active Rule for profile
assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
@@ -231,7 +231,7 @@ public class QProfilesWsMediumTest {
public void activate_rule_diff_languages() {
QProfileDto profile = createProfile("java");
RuleDefinitionDto rule = createRule("php", "toto");
ruleIndexer.commitAndIndex(dbSession, rule.getKey());
ruleIndexer.commitAndIndex(dbSession, rule.getId());

// 0. Assert No Active Rule for profile
assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
@@ -253,7 +253,7 @@ public class QProfilesWsMediumTest {
public void activate_rule_override_severity() {
QProfileDto profile = createProfile("java");
RuleDefinitionDto rule = createRule(profile.getLanguage(), "toto");
ruleIndexer.commitAndIndex(dbSession, rule.getKey());
ruleIndexer.commitAndIndex(dbSession, rule.getId());

// 0. Assert No Active Rule for profile
assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
@@ -458,7 +458,7 @@ public class QProfilesWsMediumTest {
.setSeverity(Severity.BLOCKER)
.setStatus(RuleStatus.READY);
dbClient.ruleDao().insert(dbSession, rule);
ruleIndexer.commitAndIndex(dbSession, rule.getKey());
ruleIndexer.commitAndIndex(dbSession, rule.getId());
return rule;
}


+ 24
- 20
server/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesTest.java View File

@@ -63,6 +63,7 @@ import org.sonar.server.rule.index.RuleIndexer;
import org.sonar.server.rule.index.RuleQuery;

import static com.google.common.collect.Sets.newHashSet;
import static java.lang.String.valueOf;
import static java.util.Collections.singletonList;
import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
import static org.assertj.core.api.Assertions.assertThat;
@@ -144,7 +145,8 @@ public class RegisterRulesTest {
assertThat(param.getDefaultValue()).isEqualTo("default1");

// verify index
assertThat(ruleIndex.search(new RuleQuery(), new SearchOptions()).getIds()).containsOnly(RULE_KEY1, RULE_KEY2);
RuleDto rule2 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), dbTester.getDefaultOrganization(), RULE_KEY2);
assertThat(ruleIndex.search(new RuleQuery(), new SearchOptions()).getIds()).containsOnly(rule1.getId(), rule2.getId());

// verify repositories
assertThat(dbClient.ruleRepositoryDao().selectAll(dbTester.getSession())).extracting(RuleRepositoryDto::getKey).containsOnly("fake");
@@ -156,7 +158,7 @@ public class RegisterRulesTest {

// register one rule
execute(context -> {
NewRepository repo = context.createRepository("fake", "java");
RulesDefinition.NewRepository repo = context.createRepository("fake", "java");
repo.createRule(ruleKey)
.setName(randomAlphanumeric(5))
.setHtmlDescription(randomAlphanumeric(20));
@@ -164,15 +166,16 @@ public class RegisterRulesTest {
});

// verify db
assertThat(dbClient.ruleDao().selectAllDefinitions(dbTester.getSession()))
List<RuleDefinitionDto> rules = dbClient.ruleDao().selectAllDefinitions(dbTester.getSession());
assertThat(rules)
.extracting(RuleDefinitionDto::getKey)
.extracting(RuleKey::rule)
.containsExactly(ruleKey);
RuleDefinitionDto rule = rules.iterator().next();

// verify index
assertThat(ruleIndex.search(new RuleQuery(), new SearchOptions()).getIds())
.extracting(RuleKey::rule)
.containsExactly(ruleKey);
.containsExactly(rule.getId());

// register no rule
execute(context -> context.createRepository("fake", "java").done());
@@ -188,7 +191,6 @@ public class RegisterRulesTest {

// verify index
assertThat(ruleIndex.search(new RuleQuery(), new SearchOptions()).getIds())
.extracting(RuleKey::rule)
.isEmpty();
}

@@ -249,11 +251,11 @@ public class RegisterRulesTest {
public void update_and_remove_rules_on_changes() {
execute(new FakeRepositoryV1());
assertThat(dbClient.ruleDao().selectAllDefinitions(dbTester.getSession())).hasSize(2);
assertThat(esTester.getIds(RuleIndexDefinition.INDEX_TYPE_RULE)).containsOnly(RULE_KEY1.toString(), RULE_KEY2.toString());
RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RULE_KEY1);
RuleDto rule2 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RULE_KEY2);
assertThat(esTester.getIds(RuleIndexDefinition.INDEX_TYPE_RULE)).containsOnly(valueOf(rule1.getId()), valueOf(rule2.getId()));

// user adds tags and sets markdown note
OrganizationDto defaultOrganization = dbTester.getDefaultOrganization();
RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RULE_KEY1);
rule1.setTags(newHashSet("usertag1", "usertag2"));
rule1.setNoteData("user *note*");
rule1.setNoteUserLogin("marius");
@@ -286,7 +288,7 @@ public class RegisterRulesTest {
assertThat(param.getDefaultValue()).isEqualTo("default1 v2");

// rule2 has been removed -> status set to REMOVED but db row is not deleted
RuleDto rule2 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RULE_KEY2);
rule2 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RULE_KEY2);
assertThat(rule2.getStatus()).isEqualTo(RuleStatus.REMOVED);
assertThat(rule2.getUpdatedAt()).isEqualTo(DATE2.getTime());

@@ -296,7 +298,7 @@ public class RegisterRulesTest {
assertThat(rule3.getStatus()).isEqualTo(RuleStatus.READY);

// verify index
assertThat(ruleIndex.search(new RuleQuery(), new SearchOptions()).getIds()).containsOnly(RULE_KEY1, RULE_KEY3);
assertThat(ruleIndex.search(new RuleQuery(), new SearchOptions()).getIds()).containsOnly(rule1.getId(), rule3.getId());

// verify repositories
assertThat(dbClient.ruleRepositoryDao().selectAll(dbTester.getSession())).extracting(RuleRepositoryDto::getKey).containsOnly("fake");
@@ -428,23 +430,25 @@ public class RegisterRulesTest {
public void do_not_update_already_removed_rules() {
execute(new FakeRepositoryV1());
assertThat(dbClient.ruleDao().selectAllDefinitions(dbTester.getSession())).hasSize(2);
assertThat(esTester.getIds(RuleIndexDefinition.INDEX_TYPE_RULE)).containsOnly(RULE_KEY1.toString(), RULE_KEY2.toString());

RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RULE_KEY1);
RuleDto rule2 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RULE_KEY2);
assertThat(esTester.getIds(RuleIndexDefinition.INDEX_TYPE_RULE)).containsOnly(valueOf(rule1.getId()), valueOf(rule2.getId()));

assertThat(rule2.getStatus()).isEqualTo(RuleStatus.READY);

when(system.now()).thenReturn(DATE2.getTime());
execute(new FakeRepositoryV2());

// On MySQL, need to update a rule otherwise rule2 will be seen as READY, but why ???
dbClient.ruleDao().update(dbTester.getSession(), dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RULE_KEY1).getDefinition());
dbClient.ruleDao().update(dbTester.getSession(), rule1.getDefinition());
dbTester.getSession().commit();

// rule2 is removed
rule2 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RULE_KEY2);
RuleDto rule3 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RULE_KEY3);
assertThat(rule2.getStatus()).isEqualTo(RuleStatus.REMOVED);

assertThat(ruleIndex.search(new RuleQuery(), new SearchOptions()).getIds()).containsOnly(RULE_KEY1, RULE_KEY3);
assertThat(ruleIndex.search(new RuleQuery(), new SearchOptions()).getIds()).containsOnly(rule1.getId(), rule3.getId());

when(system.now()).thenReturn(DATE3.getTime());
execute(new FakeRepositoryV2());
@@ -455,7 +459,7 @@ public class RegisterRulesTest {
assertThat(rule2.getStatus()).isEqualTo(RuleStatus.REMOVED);
assertThat(rule2.getUpdatedAt()).isEqualTo(DATE2.getTime());

assertThat(ruleIndex.search(new RuleQuery(), new SearchOptions()).getIds()).containsOnly(RULE_KEY1, RULE_KEY3);
assertThat(ruleIndex.search(new RuleQuery(), new SearchOptions()).getIds()).containsOnly(rule1.getId(), rule3.getId());
}

@Test
@@ -635,7 +639,7 @@ public class RegisterRulesTest {
@Override
public void define(Context context) {
NewRepository repo = context.createRepository("fake", "java");
NewRule rule1 = repo.createRule("rule1")
NewRule rule1 = repo.createRule(RULE_KEY1.rule())
.setName("One")
.setHtmlDescription("Description of One")
.setSeverity(BLOCKER)
@@ -650,7 +654,7 @@ public class RegisterRulesTest {
rule1.createParam("param1").setDescription("parameter one").setDefaultValue("default1");
rule1.createParam("param2").setDescription("parameter two").setDefaultValue("default2");

repo.createRule("rule2")
repo.createRule(RULE_KEY2.rule())
.setName("Two")
.setHtmlDescription("Minimal rule");
repo.done();
@@ -666,7 +670,7 @@ public class RegisterRulesTest {
NewRepository repo = context.createRepository("fake", "java");

// almost all the attributes of rule1 are changed
NewRule rule1 = repo.createRule("rule1")
NewRule rule1 = repo.createRule(RULE_KEY1.rule())
.setName("One v2")
.setHtmlDescription("Description of One v2")
.setSeverity(INFO)
@@ -681,7 +685,7 @@ public class RegisterRulesTest {
rule1.createParam("param2").setDescription("parameter two v2").setDefaultValue("default2 v2");

// rule2 is dropped, rule3 is new
repo.createRule("rule3")
repo.createRule(RULE_KEY3.rule())
.setName("Three")
.setHtmlDescription("Rule Three");
repo.done();

+ 3
- 3
server/sonar-server/src/test/java/org/sonar/server/rule/RuleCreatorTest.java View File

@@ -117,7 +117,7 @@ public class RuleCreatorTest {
// From user
assertThat(param.getDefaultValue()).isEqualTo("a.*");

assertThat(ruleIndex.search(new RuleQuery(), new SearchOptions()).getIds()).containsOnly(customRuleKey, templateRule.getKey());
assertThat(ruleIndex.search(new RuleQuery(), new SearchOptions()).getIds()).containsOnly(rule.getId(), templateRule.getId());
}

@Test
@@ -475,7 +475,7 @@ public class RuleCreatorTest {
dbTester.rules().insert(templateRule.getDefinition());
dbTester.rules().insertOrUpdateMetadata(templateRule.getMetadata().setRuleId(templateRule.getId()));
dbTester.rules().insertRuleParam(templateRule.getDefinition(), param -> param.setName("regex").setType("STRING").setDescription("Reg ex").setDefaultValue(".*"));
ruleIndexer.commitAndIndex(dbTester.getSession(), templateRule.getDefinition().getKey());
ruleIndexer.commitAndIndex(dbTester.getSession(), templateRule.getDefinition().getId());
return templateRule;
}

@@ -493,7 +493,7 @@ public class RuleCreatorTest {
dbTester.rules().insert(templateRule);
dbTester.rules().insertRuleParam(templateRule,
param -> param.setName("myIntegers").setType("INTEGER,multiple=true,values=1;2;3").setDescription("My Integers").setDefaultValue("1"));
ruleIndexer.commitAndIndex(dbTester.getSession(), templateRule.getKey());
ruleIndexer.commitAndIndex(dbTester.getSession(), templateRule.getId());
return templateRule;
}


+ 2
- 6
server/sonar-server/src/test/java/org/sonar/server/rule/RuleUpdaterTest.java View File

@@ -27,7 +27,6 @@ import com.google.common.collect.Sets;
import java.util.List;
import java.util.Map;
import javax.annotation.Nonnull;
import org.assertj.core.api.ThrowableAssertAlternative;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -50,7 +49,6 @@ import org.sonar.db.rule.RuleParamDto;
import org.sonar.db.rule.RuleTesting;
import org.sonar.server.es.EsTester;
import org.sonar.server.es.SearchOptions;
import org.sonar.server.organization.TestDefaultOrganizationProvider;
import org.sonar.server.qualityprofile.QProfileTesting;
import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.rule.index.RuleIndexDefinition;
@@ -59,9 +57,7 @@ import org.sonar.server.rule.index.RuleQuery;
import org.sonar.server.tester.UserSessionRule;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.sonar.api.rule.RuleStatus.REMOVED;
import static org.sonar.api.rule.Severity.CRITICAL;
import static org.sonar.db.rule.RuleTesting.newRule;
import static org.sonar.server.rule.RuleUpdate.createForCustomRule;
@@ -387,8 +383,8 @@ public class RuleUpdaterTest {
assertThat(params).extracting(RuleParamDto::getDefaultValue).containsOnly("b.*", null);

// Verify in index
assertThat(ruleIndex.search(new RuleQuery().setQueryText("New name"), new SearchOptions()).getIds()).containsOnly(customRule.getKey());
assertThat(ruleIndex.search(new RuleQuery().setQueryText("New description"), new SearchOptions()).getIds()).containsOnly(customRule.getKey());
assertThat(ruleIndex.search(new RuleQuery().setQueryText("New name"), new SearchOptions()).getIds()).containsOnly(customRule.getId());
assertThat(ruleIndex.search(new RuleQuery().setQueryText("New description"), new SearchOptions()).getIds()).containsOnly(customRule.getId());

assertThat(ruleIndex.search(new RuleQuery().setQueryText("Old name"), new SearchOptions()).getTotal()).isZero();
assertThat(ruleIndex.search(new RuleQuery().setQueryText("Old description"), new SearchOptions()).getTotal()).isZero();

+ 2
- 0
server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleIndexDefinitionTest.java View File

@@ -35,6 +35,7 @@ import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_ENABLED;
import static org.sonar.server.es.DefaultIndexSettingsElement.ENGLISH_HTML_ANALYZER;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_HTML_DESCRIPTION;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_ID;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_KEY;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_REPOSITORY;
import static org.sonar.server.rule.index.RuleIndexDefinition.INDEX_TYPE_RULE;
@@ -82,6 +83,7 @@ public class RuleIndexDefinitionTest {

// the following method fails if PUT fails
tester.putDocuments(INDEX_TYPE_RULE, new RuleDoc(ImmutableMap.of(
FIELD_RULE_ID, "123",
FIELD_RULE_HTML_DESCRIPTION, longText,
FIELD_RULE_REPOSITORY, "squid",
FIELD_RULE_KEY, "squid:S001")));

+ 43
- 40
server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java View File

@@ -25,6 +25,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import org.elasticsearch.search.SearchHit;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -134,7 +135,7 @@ public class RuleIndexTest {

// key
RuleQuery query = new RuleQuery().setQueryText("X001");
assertThat(underTest.search(query, new SearchOptions()).getIds()).containsOnly(js1.getKey(), cobol1.getKey());
assertThat(underTest.search(query, new SearchOptions()).getIds()).containsOnly(js1.getId(), cobol1.getId());

// partial key does not match
query = new RuleQuery().setQueryText("X00");
@@ -142,7 +143,7 @@ public class RuleIndexTest {

// repo:key -> nice-to-have !
query = new RuleQuery().setQueryText("javascript:X001");
assertThat(underTest.search(query, new SearchOptions()).getIds()).containsOnly(js1.getKey());
assertThat(underTest.search(query, new SearchOptions()).getIds()).containsOnly(js1.getId());
}

@Test
@@ -153,7 +154,7 @@ public class RuleIndexTest {
index();

RuleQuery query = new RuleQuery().setQueryText("x001");
assertThat(underTest.search(query, new SearchOptions()).getIds()).containsOnly(ruleDto.getKey());
assertThat(underTest.search(query, new SearchOptions()).getIds()).containsOnly(ruleDto.getId());
}

@Test
@@ -207,8 +208,8 @@ public class RuleIndexTest {
index();

RuleQuery protectedCharsQuery = new RuleQuery().setQueryText(rule.getName());
List<RuleKey> results = underTest.search(protectedCharsQuery, new SearchOptions()).getIds();
assertThat(results).containsOnly(rule.getKey());
List<Integer> results = underTest.search(protectedCharsQuery, new SearchOptions()).getIds();
assertThat(results).containsOnly(rule.getId());
}

@Test
@@ -223,18 +224,18 @@ public class RuleIndexTest {
index();

// partial match at word boundary
assertThat(underTest.search(new RuleQuery().setQueryText("CWE"), new SearchOptions()).getIds()).containsExactlyInAnyOrder(rule1.getKey(), rule2.getKey(), rule3.getKey());
assertThat(underTest.search(new RuleQuery().setQueryText("CWE"), new SearchOptions()).getIds()).containsExactlyInAnyOrder(rule1.getId(), rule2.getId(), rule3.getId());

// full match
assertThat(underTest.search(new RuleQuery().setQueryText("CWE-123"), new SearchOptions()).getIds()).containsExactly(rule1.getKey());
assertThat(underTest.search(new RuleQuery().setQueryText("CWE-123"), new SearchOptions()).getIds()).containsExactly(rule1.getId());

// match somewhere else in the text
assertThat(underTest.search(new RuleQuery().setQueryText("CWE-1000"), new SearchOptions()).getIds()).containsExactly(rule3.getKey());
assertThat(underTest.search(new RuleQuery().setQueryText("CWE 1000"), new SearchOptions()).getIds()).containsExactlyInAnyOrder(rule3.getKey(), rule1.getKey());
assertThat(underTest.search(new RuleQuery().setQueryText("CWE-1000"), new SearchOptions()).getIds()).containsExactly(rule3.getId());
assertThat(underTest.search(new RuleQuery().setQueryText("CWE 1000"), new SearchOptions()).getIds()).containsExactlyInAnyOrder(rule3.getId(), rule1.getId());

// several words
assertThat(underTest.search(new RuleQuery().setQueryText("great rule"), new SearchOptions()).getIds()).containsExactlyInAnyOrder(rule1.getKey(), rule2.getKey(), rule3.getKey());
assertThat(underTest.search(new RuleQuery().setQueryText("rule Another"), new SearchOptions()).getIds()).containsExactlyInAnyOrder(rule2.getKey(), rule3.getKey());
assertThat(underTest.search(new RuleQuery().setQueryText("great rule"), new SearchOptions()).getIds()).containsExactlyInAnyOrder(rule1.getId(), rule2.getId(), rule3.getId());
assertThat(underTest.search(new RuleQuery().setQueryText("rule Another"), new SearchOptions()).getIds()).containsExactlyInAnyOrder(rule2.getId(), rule3.getId());

// no matches
assertThat(underTest.search(new RuleQuery().setQueryText("unexisting"), new SearchOptions()).getIds()).isEmpty();
@@ -247,14 +248,14 @@ public class RuleIndexTest {
// html
assertThat(underTest.search(new RuleQuery().setQueryText("h1"), new SearchOptions()).getIds()).isEmpty();
assertThat(underTest.search(new RuleQuery().setQueryText("style"), new SearchOptions()).getIds()).isEmpty();
assertThat(underTest.search(new RuleQuery().setQueryText("special"), new SearchOptions()).getIds()).containsExactlyInAnyOrder(rule4.getKey());
assertThat(underTest.search(new RuleQuery().setQueryText("geeks formatting inside tables"), new SearchOptions()).getIds()).containsExactlyInAnyOrder(rule4.getKey());
assertThat(underTest.search(new RuleQuery().setQueryText("special"), new SearchOptions()).getIds()).containsExactlyInAnyOrder(rule4.getId());
assertThat(underTest.search(new RuleQuery().setQueryText("geeks formatting inside tables"), new SearchOptions()).getIds()).containsExactlyInAnyOrder(rule4.getId());

// long words
assertThat(underTest.search(new RuleQuery().setQueryText("missunderstand"), new SearchOptions()).getIds()).containsExactlyInAnyOrder(rule5.getKey());
assertThat(underTest.search(new RuleQuery().setQueryText("missunderstandings"), new SearchOptions()).getIds()).containsExactlyInAnyOrder(rule5.getKey());
assertThat(underTest.search(new RuleQuery().setQueryText("alsdkjfnadklsjfnadkdfnsksdjfn"), new SearchOptions()).getIds()).containsExactlyInAnyOrder(rule5.getKey());
assertThat(underTest.search(new RuleQuery().setQueryText("internationalization"), new SearchOptions()).getIds()).containsExactlyInAnyOrder(rule5.getKey());
assertThat(underTest.search(new RuleQuery().setQueryText("missunderstand"), new SearchOptions()).getIds()).containsExactlyInAnyOrder(rule5.getId());
assertThat(underTest.search(new RuleQuery().setQueryText("missunderstandings"), new SearchOptions()).getIds()).containsExactlyInAnyOrder(rule5.getId());
assertThat(underTest.search(new RuleQuery().setQueryText("alsdkjfnadklsjfnadkdfnsksdjfn"), new SearchOptions()).getIds()).containsExactlyInAnyOrder(rule5.getId());
assertThat(underTest.search(new RuleQuery().setQueryText("internationalization"), new SearchOptions()).getIds()).containsExactlyInAnyOrder(rule5.getId());
assertThat(underTest.search(new RuleQuery().setQueryText("internationalizationBlaBla"), new SearchOptions()).getIds()).isEmpty();
}

@@ -270,7 +271,7 @@ public class RuleIndexTest {

RuleQuery query = new RuleQuery().setRepositories(asList("checkstyle", "pmd"));
SearchIdResult results = underTest.search(query, new SearchOptions());
assertThat(results.getIds()).containsExactly(pmd.getKey());
assertThat(results.getIds()).containsExactly(pmd.getId());

// no results
query = new RuleQuery().setRepositories(singletonList("checkstyle"));
@@ -278,7 +279,7 @@ public class RuleIndexTest {

// empty list => no filter
query = new RuleQuery().setRepositories(emptyList());
assertThat(underTest.search(query, new SearchOptions()).getIds()).containsOnly(findbugs.getKey(), pmd.getKey());
assertThat(underTest.search(query, new SearchOptions()).getIds()).containsOnly(findbugs.getId(), pmd.getId());
}

@Test
@@ -340,10 +341,10 @@ public class RuleIndexTest {

// type3 in filter
query = new RuleQuery().setTypes(of(VULNERABILITY));
assertThat(underTest.search(query, new SearchOptions()).getIds()).containsOnly(vulnerability.getKey());
assertThat(underTest.search(query, new SearchOptions()).getIds()).containsOnly(vulnerability.getId());

query = new RuleQuery().setTypes(of(BUG));
assertThat(underTest.search(query, new SearchOptions()).getIds()).containsOnly(bug1.getKey(), bug2.getKey());
assertThat(underTest.search(query, new SearchOptions()).getIds()).containsOnly(bug1.getId(), bug2.getId());

// types in query => nothing
query = new RuleQuery().setQueryText("code smell bug vulnerability");
@@ -372,17 +373,17 @@ public class RuleIndexTest {
// Only template
query = new RuleQuery().setIsTemplate(true);
results = underTest.search(query, new SearchOptions());
assertThat(results.getIds()).containsOnly(ruleIsTemplate.getKey());
assertThat(results.getIds()).containsOnly(ruleIsTemplate.getId());

// Only not template
query = new RuleQuery().setIsTemplate(false);
results = underTest.search(query, new SearchOptions());
assertThat(results.getIds()).containsOnly(ruleNoTemplate.getKey());
assertThat(results.getIds()).containsOnly(ruleNoTemplate.getId());

// null => no filter
query = new RuleQuery().setIsTemplate(null);
results = underTest.search(query, new SearchOptions());
assertThat(results.getIds()).containsOnly(ruleIsTemplate.getKey(), ruleNoTemplate.getKey());
assertThat(results.getIds()).containsOnly(ruleIsTemplate.getId(), ruleNoTemplate.getId());
}

@Test
@@ -399,7 +400,7 @@ public class RuleIndexTest {
// Only custom rule
query = new RuleQuery().setTemplateKey(template.getKey().toString());
results = underTest.search(query, new SearchOptions());
assertThat(results.getIds()).containsOnly(customRule.getKey());
assertThat(results.getIds()).containsOnly(customRule.getId());

// null => no filter
query = new RuleQuery().setTemplateKey(null);
@@ -414,7 +415,7 @@ public class RuleIndexTest {

RuleQuery query = new RuleQuery().setLanguages(asList("cobol", "js"));
SearchIdResult results = underTest.search(query, new SearchOptions());
assertThat(results.getIds()).containsOnly(javascript.getKey());
assertThat(results.getIds()).containsOnly(javascript.getId());

// no results
query = new RuleQuery().setLanguages(singletonList("cpp"));
@@ -481,7 +482,7 @@ public class RuleIndexTest {

RuleQuery query = new RuleQuery().setSeverities(asList(INFO, MINOR));
SearchIdResult results = underTest.search(query, new SearchOptions());
assertThat(results.getIds()).containsOnly(info.getKey());
assertThat(results.getIds()).containsOnly(info.getId());

// no results
query = new RuleQuery().setSeverities(singletonList(MINOR));
@@ -503,8 +504,8 @@ public class RuleIndexTest {
index();

RuleQuery query = new RuleQuery().setStatuses(asList(RuleStatus.DEPRECATED, RuleStatus.READY));
SearchIdResult<RuleKey> results = underTest.search(query, new SearchOptions());
assertThat(results.getIds()).containsOnly(ready.getKey());
SearchIdResult<Integer> results = underTest.search(query, new SearchOptions());
assertThat(results.getIds()).containsOnly(ready.getId());

// no results
query = new RuleQuery().setStatuses(singletonList(RuleStatus.DEPRECATED));
@@ -557,11 +558,11 @@ public class RuleIndexTest {
}

private void verifySearch(RuleQuery query, RuleDefinitionDto... expectedRules) {
SearchIdResult<RuleKey> result = underTest.search(query, new SearchOptions());
SearchIdResult<Integer> result = underTest.search(query, new SearchOptions());
assertThat(result.getTotal()).isEqualTo((long) expectedRules.length);
assertThat(result.getIds()).hasSize(expectedRules.length);
for (RuleDefinitionDto expectedRule : expectedRules) {
assertThat(result.getIds()).contains(expectedRule.getKey());
assertThat(result.getIds()).contains(expectedRule.getId());
}
}

@@ -647,13 +648,13 @@ public class RuleIndexTest {
}

private void verifyFacet(RuleQuery query, String facet, Map.Entry<String, Long>... expectedBuckets) {
SearchIdResult<RuleKey> result = underTest.search(query, new SearchOptions().addFacets(facet));
SearchIdResult<Integer> result = underTest.search(query, new SearchOptions().addFacets(facet));
assertThat(result.getFacets().get(facet))
.containsOnly(expectedBuckets);
}

private void verifyNoFacet(RuleQuery query, String facet) {
SearchIdResult<RuleKey> result = underTest.search(query, new SearchOptions().addFacets(facet));
SearchIdResult<Integer> result = underTest.search(query, new SearchOptions().addFacets(facet));
assertThat(result.getFacets().get(facet)).isNull();
}

@@ -967,13 +968,13 @@ public class RuleIndexTest {

// ascending
RuleQuery query = new RuleQuery().setSortField(RuleIndexDefinition.FIELD_RULE_NAME);
SearchIdResult<RuleKey> results = underTest.search(query, new SearchOptions());
assertThat(results.getIds()).containsExactly(abc.getKey(), abcd.getKey(), fgh.getKey());
SearchIdResult<Integer> results = underTest.search(query, new SearchOptions());
assertThat(results.getIds()).containsExactly(abc.getId(), abcd.getId(), fgh.getId());

// descending
query = new RuleQuery().setSortField(RuleIndexDefinition.FIELD_RULE_NAME).setAscendingSort(false);
results = underTest.search(query, new SearchOptions());
assertThat(results.getIds()).containsExactly(fgh.getKey(), abcd.getKey(), abc.getKey());
assertThat(results.getIds()).containsExactly(fgh.getId(), abcd.getId(), abc.getId());
}

@Test
@@ -983,8 +984,8 @@ public class RuleIndexTest {
RuleDefinitionDto older = createRule(setCreatedAt(1000L), setUpdatedAt(2000L));
index();

SearchIdResult<RuleKey> results = underTest.search(new RuleQuery(), new SearchOptions());
assertThat(results.getIds()).containsExactly(oldest.getKey(), older.getKey(), old.getKey());
SearchIdResult<Integer> results = underTest.search(new RuleQuery(), new SearchOptions());
assertThat(results.getIds()).containsExactly(oldest.getId(), older.getId(), old.getId());
}

@Test
@@ -1061,11 +1062,13 @@ public class RuleIndexTest {
index();

// inactive rules on profile
List<SearchHit> ruleDocs = es.getDocuments(INDEX_TYPE_RULE);
List<SearchHit> activeRuleDocs = es.getDocuments(INDEX_TYPE_ACTIVE_RULE);
assertThat(underTest.searchAll(new RuleQuery().setActivation(false).setQProfile(profile2)))
.containsOnly(rule2.getKey(), rule3.getKey());
.containsOnly(rule2.getId(), rule3.getId());

// active rules on profile
assertThat(underTest.searchAll(new RuleQuery().setActivation(true).setQProfile(profile2)))
.containsOnly(rule1.getKey());
.containsOnly(rule1.getId());
}
}

+ 7
- 6
server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleIndexerTest.java View File

@@ -80,7 +80,7 @@ public class RuleIndexerTest {
@Test
public void index() {
dbClient.ruleDao().insert(dbSession, rule);
underTest.commitAndIndex(dbSession, rule.getKey());
underTest.commitAndIndex(dbSession, rule.getId());

assertThat(esTester.countDocuments(RuleIndexDefinition.INDEX_TYPE_RULE)).isEqualTo(1);
}
@@ -90,12 +90,12 @@ public class RuleIndexerTest {
// Create and Index rule
dbClient.ruleDao().insert(dbSession, rule.setStatus(RuleStatus.READY));
dbSession.commit();
underTest.commitAndIndex(dbTester.getSession(), rule.getKey());
underTest.commitAndIndex(dbTester.getSession(), rule.getId());
assertThat(esTester.countDocuments(RuleIndexDefinition.INDEX_TYPE_RULE)).isEqualTo(1);

// Remove rule
dbTester.getDbClient().ruleDao().update(dbTester.getSession(), rule.setStatus(RuleStatus.READY).setUpdatedAt(2000000000000L));
underTest.commitAndIndex(dbTester.getSession(), rule.getKey());
underTest.commitAndIndex(dbTester.getSession(), rule.getId());

assertThat(esTester.countDocuments(RuleIndexDefinition.INDEX_TYPE_RULE)).isEqualTo(1);
}
@@ -103,12 +103,13 @@ public class RuleIndexerTest {
@Test
public void index_rule_extension_with_long_id() {
RuleDefinitionDto rule = dbTester.rules().insert(r -> r.setRuleKey(RuleTesting.randomRuleKeyOfMaximumLength()));
underTest.commitAndIndex(dbTester.getSession(), rule.getKey());
underTest.commitAndIndex(dbTester.getSession(), rule.getId());
OrganizationDto organization = dbTester.organizations().insert();
dbTester.rules().insertOrUpdateMetadata(rule, organization, m -> m.setTags(ImmutableSet.of("bla")));
underTest.commitAndIndex(dbTester.getSession(), rule.getKey(), organization);
underTest.commitAndIndex(dbTester.getSession(), rule.getId(), organization);

RuleExtensionDoc doc = new RuleExtensionDoc()
.setRuleId(rule.getId())
.setRuleKey(rule.getKey())
.setScope(RuleExtensionScope.organization(organization.getUuid()));
assertThat(
@@ -125,7 +126,7 @@ public class RuleIndexerTest {
public void index_long_rule_description() {
String description = IntStream.range(0, 100000).map(i -> i % 100).mapToObj(Integer::toString).collect(Collectors.joining(" "));
RuleDefinitionDto rule = dbTester.rules().insert(r -> r.setDescription(description));
underTest.commitAndIndex(dbTester.getSession(), rule.getKey());
underTest.commitAndIndex(dbTester.getSession(), rule.getId());

assertThat(esTester.countDocuments(RuleIndexDefinition.INDEX_TYPE_RULE)).isEqualTo(1);
}

+ 1
- 1
server/sonar-server/src/test/java/org/sonar/server/rule/ws/DeleteActionTest.java View File

@@ -87,7 +87,7 @@ public class DeleteActionTest {
.setParam("key", customRule.getKey().toString())
.execute();

verify(ruleIndexer).commitAndIndex(any(), eq(customRule.getKey()));
verify(ruleIndexer).commitAndIndex(any(), eq(customRule.getId()));

// Verify custom rule has status REMOVED
RuleDefinitionDto customRuleReloaded = dbClient.ruleDao().selectOrFailDefinitionByKey(dbSession, customRule.getKey());

+ 1
- 1
server/sonar-server/src/test/java/org/sonar/server/rule/ws/SearchActionTest.java View File

@@ -926,7 +926,7 @@ public class SearchActionTest {
@SafeVarargs
private final RuleMetadataDto insertMetadata(OrganizationDto organization, RuleDefinitionDto rule, Consumer<RuleMetadataDto>... populaters) {
RuleMetadataDto metadata = db.rules().insertOrUpdateMetadata(rule, organization, populaters);
ruleIndexer.commitAndIndex(db.getSession(), rule.getKey(), organization);
ruleIndexer.commitAndIndex(db.getSession(), rule.getId(), organization);
return metadata;
}


+ 3
- 4
server/sonar-server/src/test/java/org/sonar/server/rule/ws/ShowActionTest.java View File

@@ -19,7 +19,6 @@
*/
package org.sonar.server.rule.ws;

import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.function.Consumer;
@@ -449,7 +448,7 @@ public class ShowActionTest {
DbSession session = dbTester.getSession();
ruleDao.insert(session, ruleDto);
session.commit();
ruleIndexer.commitAndIndex(session, ruleDto.getKey());
ruleIndexer.commitAndIndex(session, ruleDto.getId());
RuleParamDto regexParam = RuleParamDto.createFor(ruleDto).setName("regex").setType("STRING").setDescription("Reg *exp*").setDefaultValue(".*");
ruleDao.insertRuleParam(session, ruleDto, regexParam);

@@ -502,14 +501,14 @@ public class ShowActionTest {

private RuleDefinitionDto insertRule() {
RuleDefinitionDto rule = dbTester.rules().insert();
ruleIndexer.commitAndIndex(dbTester.getSession(), rule.getKey());
ruleIndexer.commitAndIndex(dbTester.getSession(), rule.getId());
return rule;
}

@SafeVarargs
private final RuleMetadataDto insertMetadata(OrganizationDto organization, RuleDefinitionDto rule, Consumer<RuleMetadataDto>... populaters) {
RuleMetadataDto metadata = dbTester.rules().insertOrUpdateMetadata(rule, organization, populaters);
ruleIndexer.commitAndIndex(dbTester.getSession(), rule.getKey(), organization);
ruleIndexer.commitAndIndex(dbTester.getSession(), rule.getId(), organization);
return metadata;
}
}

+ 3
- 3
server/sonar-server/src/test/java/org/sonar/server/rule/ws/TagsActionTest.java View File

@@ -100,7 +100,7 @@ public class TagsActionTest {
@Test
public void system_tag() {
RuleDefinitionDto r = db.rules().insert(setSystemTags("tag"));
ruleIndexer.commitAndIndex(db.getSession(), r.getKey());
ruleIndexer.commitAndIndex(db.getSession(), r.getId());

String result = ws.newRequest().execute().getInput();
assertJson(result).isSimilarTo("{\"tags\":[\"tag\"]}");
@@ -109,9 +109,9 @@ public class TagsActionTest {
@Test
public void tag() {
RuleDefinitionDto r = db.rules().insert(setSystemTags());
ruleIndexer.commitAndIndex(db.getSession(), r.getKey());
ruleIndexer.commitAndIndex(db.getSession(), r.getId());
db.rules().insertOrUpdateMetadata(r, organization, setTags("tag"));
ruleIndexer.commitAndIndex(db.getSession(), r.getKey(), organization);
ruleIndexer.commitAndIndex(db.getSession(), r.getId(), organization);

String result = ws.newRequest().setParam("organization", organization.getKey()).execute().getInput();
assertJson(result).isSimilarTo("{\"tags\":[\"tag\"]}");

Loading…
Cancel
Save