diff options
author | Aurelien Poscia <aurelien.poscia@sonarsource.com> | 2022-04-23 14:21:23 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2022-05-06 20:02:43 +0000 |
commit | c333b3ae6984bf1b402d3398fa71de7f0a75b817 (patch) | |
tree | 7f7746ef734959e0c73c94b405fb1dec7d93eb0c /server | |
parent | c063d9205ddfbca5ebd6136e1506d8dc6974ff35 (diff) | |
download | sonarqube-c333b3ae6984bf1b402d3398fa71de7f0a75b817.tar.gz sonarqube-c333b3ae6984bf1b402d3398fa71de7f0a75b817.zip |
SONAR-16302 persist and fetch rules with new DB structure
Diffstat (limited to 'server')
31 files changed, 416 insertions, 175 deletions
diff --git a/server/sonar-db-core/src/main/java/org/sonar/db/version/SqTables.java b/server/sonar-db-core/src/main/java/org/sonar/db/version/SqTables.java index 0efe8159a86..b46f6a4a1d9 100644 --- a/server/sonar-db-core/src/main/java/org/sonar/db/version/SqTables.java +++ b/server/sonar-db-core/src/main/java/org/sonar/db/version/SqTables.java @@ -90,6 +90,7 @@ public final class SqTables { "quality_gate_conditions", "saml_message_ids", "rules", + "rule_desc_sections", "rules_metadata", "rules_parameters", "rules_profiles", diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java b/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java index 99875cdcbd7..462ea745804 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java @@ -131,7 +131,6 @@ import org.sonar.db.qualityprofile.QProfileEditGroupsMapper; import org.sonar.db.qualityprofile.QProfileEditUsersMapper; import org.sonar.db.qualityprofile.QualityProfileExportMapper; import org.sonar.db.qualityprofile.QualityProfileMapper; -import org.sonar.db.rule.RuleDto; import org.sonar.db.rule.RuleMapper; import org.sonar.db.rule.RuleParamDto; import org.sonar.db.rule.RuleRepositoryMapper; @@ -221,7 +220,6 @@ public class MyBatis { confBuilder.loadAlias("QualityGate", QualityGateDto.class); confBuilder.loadAlias("Resource", ResourceDto.class); confBuilder.loadAlias("RuleParam", RuleParamDto.class); - confBuilder.loadAlias("Rule", RuleDto.class); confBuilder.loadAlias("SchemaMigration", SchemaMigrationDto.class); confBuilder.loadAlias("ScrapProperty", ScrapPropertyDto.class); confBuilder.loadAlias("ScrapAnalysisProperty", ScrapAnalysisPropertyDto.class); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDao.java index 20b7c6edd46..95e81b68c4a 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDao.java @@ -24,7 +24,6 @@ import java.util.List; import java.util.Optional; import java.util.Set; import java.util.function.Consumer; -import org.apache.ibatis.session.ResultHandler; import org.sonar.api.rule.RuleKey; import org.sonar.api.rules.RuleQuery; import org.sonar.core.util.UuidFactory; @@ -34,7 +33,6 @@ import org.sonar.db.RowNotFoundException; import static com.google.common.base.Preconditions.checkNotNull; import static java.util.Collections.emptyList; -import static java.util.Optional.ofNullable; import static org.sonar.db.DatabaseUtils.executeLargeInputs; import static org.sonar.db.DatabaseUtils.executeLargeInputsWithoutOutput; import static org.sonar.db.DatabaseUtils.executeLargeUpdates; @@ -48,16 +46,15 @@ public class RuleDao implements Dao { } public Optional<RuleDto> selectByKey(DbSession session, RuleKey key) { - RuleDto res = mapper(session).selectByKey(key); - return ofNullable(res); + return Optional.ofNullable(mapper(session).selectByKey(key)); } public Optional<RuleDefinitionDto> selectDefinitionByKey(DbSession session, RuleKey key) { - return ofNullable(mapper(session).selectDefinitionByKey(key)); + return Optional.ofNullable(mapper(session).selectDefinitionByKey(key)); } public Optional<RuleMetadataDto> selectMetadataByKey(DbSession session, RuleKey key) { - return ofNullable(mapper(session).selectMetadataByKey(key)); + return Optional.ofNullable(mapper(session).selectMetadataByKey(key)); } public List<RuleMetadataDto> selectMetadataByKeys(DbSession session, Collection<RuleKey> keys) { @@ -68,28 +65,21 @@ public class RuleDao implements Dao { } public RuleDto selectOrFailByKey(DbSession session, RuleKey key) { - RuleDto rule = mapper(session).selectByKey(key); - if (rule == null) { - throw new RowNotFoundException(String.format("Rule with key '%s' does not exist", key)); - } - return rule; + return Optional.ofNullable(mapper(session).selectByKey(key)) + .orElseThrow(() -> new RowNotFoundException(String.format("Rule with key '%s' does not exist", key))); } public RuleDefinitionDto selectOrFailDefinitionByKey(DbSession session, RuleKey key) { - RuleDefinitionDto rule = mapper(session).selectDefinitionByKey(key); - if (rule == null) { - throw new RowNotFoundException(String.format("Rule with key '%s' does not exist", key)); - } - return rule; + return Optional.ofNullable(mapper(session).selectDefinitionByKey(key)) + .orElseThrow(() -> new RowNotFoundException(String.format("Rule with key '%s' does not exist", key))); } public Optional<RuleDto> selectByUuid(String uuid, DbSession session) { - RuleDto res = mapper(session).selectByUuid(uuid); - return ofNullable(res); + return Optional.ofNullable(mapper(session).selectByUuid(uuid)); } public Optional<RuleDefinitionDto> selectDefinitionByUuid(String uuid, DbSession session) { - return ofNullable(mapper(session).selectDefinitionByUuid(uuid)); + return Optional.ofNullable(mapper(session).selectDefinitionByUuid(uuid)); } public List<RuleDto> selectByUuids(DbSession session, List<String> uuids) { @@ -120,8 +110,8 @@ public class RuleDao implements Dao { return executeLargeInputs(keys, mapper(session)::selectDefinitionByKeys); } - public void selectEnabled(DbSession session, ResultHandler<RuleDefinitionDto> resultHandler) { - mapper(session).selectEnabled(resultHandler); + public List<RuleDefinitionDto> selectEnabled(DbSession session) { + return mapper(session).selectEnabled(); } public List<RuleDto> selectAll(DbSession session) { @@ -140,9 +130,11 @@ public class RuleDao implements Dao { return mapper(session).selectByQuery(ruleQuery); } - public void insert(DbSession session, RuleDefinitionDto dto) { - checkNotNull(dto.getUuid(), "RuleDefinitionDto has no 'uuid'."); - mapper(session).insertDefinition(dto); + public void insert(DbSession session, RuleDefinitionDto ruleDefinitionDto) { + checkNotNull(ruleDefinitionDto.getUuid(), "RuleDefinitionDto has no 'uuid'."); + RuleMapper mapper = mapper(session); + mapper.insertDefinition(ruleDefinitionDto); + insertRuleDescriptionSectionDtos(ruleDefinitionDto, mapper); } public void insert(DbSession session, RuleMetadataDto dto) { @@ -150,8 +142,20 @@ public class RuleDao implements Dao { mapper(session).insertMetadata(dto); } - public void update(DbSession session, RuleDefinitionDto dto) { - mapper(session).updateDefinition(dto); + public void update(DbSession session, RuleDefinitionDto ruleDefinitionDto) { + RuleMapper mapper = mapper(session); + mapper.updateDefinition(ruleDefinitionDto); + updateRuleDescriptionDtos(ruleDefinitionDto, mapper); + } + + private void updateRuleDescriptionDtos(RuleDefinitionDto ruleDefinitionDto, RuleMapper mapper) { + mapper.deleteRuleDescriptionSection(ruleDefinitionDto.getUuid()); + insertRuleDescriptionSectionDtos(ruleDefinitionDto, mapper); + } + + private void insertRuleDescriptionSectionDtos(RuleDefinitionDto ruleDefinitionDto, RuleMapper mapper) { + ruleDefinitionDto.getRuleDescriptionSectionDtos() + .forEach(section -> mapper.insertRuleDescriptionSection(ruleDefinitionDto.getUuid(), section)); } public void insertOrUpdate(DbSession session, RuleMetadataDto dto) { diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDefinitionDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDefinitionDto.java index 1cd974855ff..2347e80f8f5 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDefinitionDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDefinitionDto.java @@ -21,10 +21,9 @@ package org.sonar.db.rule; import com.google.common.base.Splitter; import com.google.common.collect.ImmutableSet; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; +import java.util.HashSet; import java.util.Objects; +import java.util.Optional; import java.util.Set; import javax.annotation.CheckForNull; import javax.annotation.Nullable; @@ -36,7 +35,7 @@ import org.sonar.api.rules.RuleType; import org.sonar.db.rule.RuleDto.Scope; import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Collections.unmodifiableCollection; +import static org.sonar.db.rule.RuleDescriptionSectionDto.DEFAULT_KEY; public class RuleDefinitionDto { @@ -46,7 +45,7 @@ public class RuleDefinitionDto { private String repositoryKey; private String ruleKey; - private Map<String, RuleDescriptionSectionDto> ruleDescriptionSectionDtos = new HashMap<>(); + private Set<RuleDescriptionSectionDto> ruleDescriptionSectionDtos = new HashSet<>(); /** * Description format can be null on external rule, otherwise it should never be null @@ -167,35 +166,38 @@ public class RuleDefinitionDto { return this; } - public Collection<RuleDescriptionSectionDto> getRuleDescriptionSectionDtos() { - return unmodifiableCollection(ruleDescriptionSectionDtos.values()); - } - @CheckForNull public RuleDescriptionSectionDto getRuleDescriptionSectionDto(String ruleDescriptionSectionKey) { - return ruleDescriptionSectionDtos.get(ruleDescriptionSectionKey); + return findExistingSectionWithSameKey(ruleDescriptionSectionKey).orElse(null); } @CheckForNull public RuleDescriptionSectionDto getDefaultRuleDescriptionSectionDto() { - return ruleDescriptionSectionDtos.get(RuleDescriptionSectionDto.DEFAULT_KEY); + return findExistingSectionWithSameKey(DEFAULT_KEY).orElse(null); } public RuleDefinitionDto addRuleDescriptionSectionDto(RuleDescriptionSectionDto ruleDescriptionSectionDto) { - checkArgument(!isSectionKeyUsed(ruleDescriptionSectionDto.getKey()), "A section with key %s already exists", ruleDescriptionSectionDto.getKey()); - this.ruleDescriptionSectionDtos.put(ruleDescriptionSectionDto.getKey(), ruleDescriptionSectionDto); + checkArgument(sectionWithSameKeyShouldNotExist(ruleDescriptionSectionDto), + "A section with key %s already exists", ruleDescriptionSectionDto.getKey()); + ruleDescriptionSectionDtos.add(ruleDescriptionSectionDto); return this; } - private boolean isSectionKeyUsed(String sectionKey) { - return ruleDescriptionSectionDtos.containsKey(sectionKey); + private boolean sectionWithSameKeyShouldNotExist(RuleDescriptionSectionDto ruleDescriptionSectionDto) { + return findExistingSectionWithSameKey(ruleDescriptionSectionDto.getKey()).isEmpty(); } public RuleDefinitionDto addOrReplaceRuleDescriptionSectionDto(RuleDescriptionSectionDto ruleDescriptionSectionDto) { - this.ruleDescriptionSectionDtos.put(ruleDescriptionSectionDto.getKey(), ruleDescriptionSectionDto); + Optional<RuleDescriptionSectionDto> existingSectionWithSameKey = findExistingSectionWithSameKey(ruleDescriptionSectionDto.getKey()); + existingSectionWithSameKey.ifPresent(ruleDescriptionSectionDtos::remove); + ruleDescriptionSectionDtos.add(ruleDescriptionSectionDto); return this; } + private Optional<RuleDescriptionSectionDto> findExistingSectionWithSameKey(String ruleDescriptionSectionKey) { + return ruleDescriptionSectionDtos.stream().filter(section -> section.getKey().equals(ruleDescriptionSectionKey)).findAny(); + } + @CheckForNull public RuleDto.Format getDescriptionFormat() { return descriptionFormat; @@ -429,6 +431,14 @@ public class RuleDefinitionDto { return this; } + public Set<RuleDescriptionSectionDto> getRuleDescriptionSectionDtos() { + return ruleDescriptionSectionDtos; + } + + void setRuleDescriptionSectionDtos(Set<RuleDescriptionSectionDto> ruleDescriptionSectionDtos) { + this.ruleDescriptionSectionDtos = ruleDescriptionSectionDtos; + } + @Override public boolean equals(Object obj) { if (!(obj instanceof RuleDefinitionDto)) { @@ -475,4 +485,5 @@ public class RuleDefinitionDto { ", scope=" + scope + '}'; } + } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDescriptionSectionDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDescriptionSectionDto.java index bff3a3d30d1..76dc0684d9e 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDescriptionSectionDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDescriptionSectionDto.java @@ -25,14 +25,21 @@ import static org.sonar.api.utils.Preconditions.checkArgument; public class RuleDescriptionSectionDto { static final String DEFAULT_KEY = "default"; + + private final String uuid; private final String key; private final String description; - private RuleDescriptionSectionDto(String key, String description) { + private RuleDescriptionSectionDto(String uuid, String key, String description) { + this.uuid = uuid; this.key = key; this.description = description; } + public String getUuid() { + return uuid; + } + public String getKey() { return key; } @@ -41,9 +48,10 @@ public class RuleDescriptionSectionDto { return description; } - public static RuleDescriptionSectionDto createDefaultRuleDescriptionSection(String description) { + public static RuleDescriptionSectionDto createDefaultRuleDescriptionSection(String uuid, String description) { return RuleDescriptionSectionDto.builder() .setDefault() + .uuid(uuid) .description(description) .build(); } @@ -59,18 +67,25 @@ public class RuleDescriptionSectionDto { @Override public String toString() { return new StringJoiner(", ", RuleDescriptionSectionDto.class.getSimpleName() + "[", "]") + .add("uuid='" + uuid + "'") .add("key='" + key + "'") .add("description='" + description + "'") .toString(); } public static final class RuleDescriptionSectionDtoBuilder { + private String uuid; private String key = null; private String description; private RuleDescriptionSectionDtoBuilder() { } + public RuleDescriptionSectionDtoBuilder uuid(String uuid) { + this.uuid = uuid; + return this; + } + public RuleDescriptionSectionDtoBuilder setDefault() { checkArgument(this.key == null, "Only one of setDefault and key methods can be called"); this.key = DEFAULT_KEY; @@ -83,14 +98,13 @@ public class RuleDescriptionSectionDto { return this; } - public RuleDescriptionSectionDtoBuilder description(String description) { this.description = description; return this; } public RuleDescriptionSectionDto build() { - return new RuleDescriptionSectionDto(key, description); + return new RuleDescriptionSectionDto(uuid, key, description); } } } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java index 3e518801fa7..12f4d4e4625 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java @@ -125,6 +125,10 @@ public class RuleDto { return this; } + void setRuleDescriptionSectionDtos(Set<RuleDescriptionSectionDto> ruleDescriptionSectionDtos) { + definition.setRuleDescriptionSectionDtos(ruleDescriptionSectionDtos); + } + public Format getDescriptionFormat() { return definition.getDescriptionFormat(); } @@ -203,7 +207,7 @@ public class RuleDto { return definition.isAdHoc(); } - public RuleDto setIsAdhoc(boolean isAdHoc) { + public RuleDto setIsAdHoc(boolean isAdHoc) { definition.setIsAdHoc(isAdHoc); return this; } @@ -510,6 +514,8 @@ public class RuleDto { return this; } + + @Override public boolean equals(Object obj) { if (!(obj instanceof RuleDto)) { diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleMapper.java index 34bb0d063b7..74f67110746 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleMapper.java @@ -33,7 +33,7 @@ public interface RuleMapper { List<RuleDefinitionDto> selectAllDefinitions(); - void selectEnabled(ResultHandler<RuleDefinitionDto> resultHandler); + List<RuleDefinitionDto> selectEnabled(); RuleDto selectByUuid(@Param("uuid") String uuid); @@ -67,8 +67,12 @@ public interface RuleMapper { void insertDefinition(RuleDefinitionDto ruleDefinitionDto); + void insertRuleDescriptionSection(@Param("ruleUuid") String ruleUuid, @Param("dto") RuleDescriptionSectionDto ruleDescriptionSectionDto); + void updateDefinition(RuleDefinitionDto ruleDefinitionDto); + void deleteRuleDescriptionSection(String ruleUuid); + int countMetadata(RuleMetadataDto ruleMetadataDto); void insertMetadata(RuleMetadataDto ruleMetadataDto); diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/rule/RuleMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/rule/RuleMapper.xml index 06b8316d728..0188bf511d8 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/rule/RuleMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/rule/RuleMapper.xml @@ -3,11 +3,22 @@ <mapper namespace="org.sonar.db.rule.RuleMapper"> + <sql id="selectRuleDescriptionSectionColumns"> + rds.uuid as "rds_uuid", + rds.kee as "rds_kee", + rds.description as "rds_description", + </sql> + + <sql id="leftOuterJoinRulesDescriptionSections"> + left outer join rule_desc_sections rds on + rds.rule_uuid = r.uuid + </sql> + <sql id="selectDefinitionColumns"> - r.uuid, + <include refid="selectRuleDescriptionSectionColumns"/> + r.uuid as "r_uuid", r.plugin_rule_key as "ruleKey", r.plugin_name as "repositoryKey", - r.description, r.description_format as "descriptionFormat", r.status, r.name, @@ -60,88 +71,182 @@ rm.rule_uuid = r.uuid </sql> - <select id="selectAll" resultType="Rule"> + <select id="selectAll" resultMap="ruleResultMap"> select <include refid="selectJoinedTablesColumns"/> from rules r <include refid="outerJoinRulesMetadata"/> + <include refid="leftOuterJoinRulesDescriptionSections"/> </select> - <select id="selectAllDefinitions" resultType="org.sonar.db.rule.RuleDefinitionDto"> + <resultMap id="ruleResultMap" type="org.sonar.db.rule.RuleDto"> + <id property="uuid" column="r_uuid"/> + + <result property="createdAtFromDefinition" column="createdAtFromDefinition" /> + <result property="updatedAtFromDefinition" column="updatedAtFromDefinition" /> + <result property="noteData" column="noteData" /> + <result property="noteUserUuid" column="noteUserUuid" /> + <result property="noteCreatedAt" column="noteCreatedAt" /> + <result property="noteUpdatedAt" column="noteUpdatedAt" /> + <result property="remediationFunction" column="remediationFunction" /> + <result property="remediationGapMultiplier" column="remediationGapMultiplier" /> + <result property="remediationBaseEffort" column="remediationBaseEffort" /> + <result property="tagsField" column="tagsField" /> + <result property="adHocName" column="adHocName" /> + <result property="adHocDescription" column="adHocDescription" /> + <result property="adHocSeverity" column="adHocSeverity" /> + <result property="adHocType" column="adHocType" /> + <result property="createdAtFromMetadata" column="createdAtFromMetadata" /> + <result property="updatedAtFromMetadata" column="updatedAtFromMetadata" /> + + <result property="ruleKey" column="ruleKey"/> + <result property="repositoryKey" column="repositoryKey"/> + <result property="descriptionFormat" column="descriptionFormat"/> + <result property="status" column="status"/> + <result property="name" column="name"/> + <result property="configKey" column="configKey"/> + <result property="severity" column="severity"/> + <result property="isTemplate" column="isTemplate"/> + <result property="isExternal" column="isExternal"/> + <result property="isAdHoc" column="isAdHoc"/> + <result property="language" column="language"/> + <result property="templateUuid" column="templateUuid"/> + <result property="defRemediationFunction" column="defRemediationFunction"/> + <result property="defRemediationGapMultiplier" column="defRemediationGapMultiplier"/> + <result property="defRemediationBaseEffort" column="defRemediationBaseEffort"/> + <result property="gapDescription" column="gapDescription"/> + <result property="systemTagsField" column="systemTagsField"/> + <result property="securityStandardsField" column="securityStandardsField"/> + <result property="type" column="type"/> + <result property="pluginKey" column="pluginKey"/> + <result property="scope" column="scope"/> + <result property="createdAt" column="created_at"/> + <result property="updatedAt" column="updated_at"/> + + <collection property="ruleDescriptionSectionDtos" ofType="org.sonar.db.rule.RuleDescriptionSectionDto"> + <id property="uuid" column="rds_uuid"/> + <result property="key" column="rds_kee"/> + <result property="description" column="rds_description"/> + </collection> + </resultMap> + + <resultMap id="ruleDefinitionResultMap" type="org.sonar.db.rule.RuleDefinitionDto"> + <id property="uuid" column="r_uuid"/> + <result property="ruleKey" column="ruleKey"/> + <result property="repositoryKey" column="repositoryKey"/> + <result property="descriptionFormat" column="descriptionFormat"/> + <result property="status" column="status"/> + <result property="name" column="name"/> + <result property="configKey" column="configKey"/> + <result property="severity" column="severity"/> + <result property="isTemplate" column="isTemplate"/> + <result property="isExternal" column="isExternal"/> + <result property="isAdHoc" column="isAdHoc"/> + <result property="language" column="language"/> + <result property="templateUuid" column="templateUuid"/> + <result property="defRemediationFunction" column="defRemediationFunction"/> + <result property="defRemediationGapMultiplier" column="defRemediationGapMultiplier"/> + <result property="defRemediationBaseEffort" column="defRemediationBaseEffort"/> + <result property="gapDescription" column="gapDescription"/> + <result property="systemTagsField" column="systemTagsField"/> + <result property="securityStandardsField" column="securityStandardsField"/> + <result property="type" column="type"/> + <result property="pluginKey" column="pluginKey"/> + <result property="scope" column="scope"/> + <result property="createdAt" column="createdAt"/> + <result property="updatedAt" column="updatedAt"/> + + <collection property="ruleDescriptionSectionDtos" ofType="org.sonar.db.rule.RuleDescriptionSectionDto"> + <id property="uuid" column="rds_uuid"/> + <result property="key" column="rds_kee"/> + <result property="description" column="rds_description"/> + </collection> + + </resultMap> + + <select id="selectAllDefinitions" resultMap="ruleDefinitionResultMap"> select <include refid="selectRuleTableColumns"/> from rules r + <include refid="leftOuterJoinRulesDescriptionSections"/> </select> - <select id="selectEnabled" resultType="org.sonar.db.rule.RuleDefinitionDto"> + <select id="selectEnabled" resultMap="ruleDefinitionResultMap"> select <include refid="selectRuleTableColumns"/> from rules r + <include refid="leftOuterJoinRulesDescriptionSections"/> where r.status != 'REMOVED' </select> - <select id="selectByUuid" parameterType="map" resultType="Rule"> + <select id="selectByUuid" parameterType="map" resultMap="ruleResultMap"> select <include refid="selectJoinedTablesColumns"/> from rules r <include refid="outerJoinRulesMetadata"/> + <include refid="leftOuterJoinRulesDescriptionSections"/> where r.uuid=#{uuid,jdbcType=VARCHAR} </select> - <select id="selectDefinitionByUuid" parameterType="String" resultType="org.sonar.db.rule.RuleDefinitionDto"> + <select id="selectDefinitionByUuid" parameterType="String" resultMap="ruleDefinitionResultMap"> select <include refid="selectRuleTableColumns"/> from rules r + <include refid="leftOuterJoinRulesDescriptionSections"/> where r.uuid=#{uuid,jdbcType=VARCHAR} </select> - <select id="selectByUuids" parameterType="map" resultType="Rule"> + <select id="selectByUuids" parameterType="map" resultMap="ruleResultMap"> select <include refid="selectJoinedTablesColumns"/> from rules r <include refid="outerJoinRulesMetadata"/> + <include refid="leftOuterJoinRulesDescriptionSections"/> where <foreach collection="uuids" index="index" item="uuid" open="" separator=" or " close=""> r.uuid=#{uuid,jdbcType=VARCHAR} </foreach> </select> - <select id="selectDefinitionByUuids" parameterType="map" resultType="org.sonar.db.rule.RuleDefinitionDto"> + <select id="selectDefinitionByUuids" parameterType="map" resultMap="ruleDefinitionResultMap"> select <include refid="selectRuleTableColumns"/> from rules r + <include refid="leftOuterJoinRulesDescriptionSections"/> where <foreach collection="uuids" index="index" item="uuid" open="" separator=" or " close=""> r.uuid=#{uuid,jdbcType=VARCHAR} </foreach> </select> - <select id="selectByKey" parameterType="map" resultType="Rule"> + <select id="selectByKey" parameterType="map" resultMap="ruleResultMap"> select <include refid="selectJoinedTablesColumns"/> from rules r <include refid="outerJoinRulesMetadata"/> + <include refid="leftOuterJoinRulesDescriptionSections"/> where r.plugin_name=#{ruleKey.repository,jdbcType=VARCHAR} and r.plugin_rule_key=#{ruleKey.rule,jdbcType=VARCHAR} </select> - <select id="selectDefinitionByKey" parameterType="map" resultType="org.sonar.db.rule.RuleDefinitionDto"> + <select id="selectDefinitionByKey" parameterType="map" resultMap="ruleDefinitionResultMap"> select <include refid="selectRuleTableColumns"/> from rules r + <include refid="leftOuterJoinRulesDescriptionSections"/> where r.plugin_name=#{repository,jdbcType=VARCHAR} and r.plugin_rule_key=#{rule,jdbcType=VARCHAR} @@ -231,23 +336,25 @@ </foreach> </select> - <select id="selectByKeys" parameterType="map" resultType="Rule"> + <select id="selectByKeys" parameterType="map" resultMap="ruleResultMap"> select <include refid="selectJoinedTablesColumns"/> from rules r <include refid="outerJoinRulesMetadata"/> + <include refid="leftOuterJoinRulesDescriptionSections"/> 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> </select> - <select id="selectDefinitionByKeys" parameterType="map" resultType="org.sonar.db.rule.RuleDefinitionDto"> + <select id="selectDefinitionByKeys" parameterType="map" resultMap="ruleDefinitionResultMap"> select <include refid="selectRuleTableColumns"/> from rules r + <include refid="leftOuterJoinRulesDescriptionSections"/> 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}) @@ -275,7 +382,6 @@ r.plugin_name as "repository", r.plugin_rule_key as "pluginRuleKey", r.name as "name", - r.description as "description", r.description_format as "descriptionFormat", r.priority as "severity", r.status as "status", @@ -296,12 +402,13 @@ left outer join rules_metadata rm on r.uuid = rm.rule_uuid </sql> - <select id="selectByQuery" parameterType="map" resultType="Rule"> + <select id="selectByQuery" parameterType="map" resultMap="ruleResultMap"> select <include refid="selectJoinedTablesColumns"/> from rules r <include refid="outerJoinRulesMetadata"/> + <include refid="leftOuterJoinRulesDescriptionSections"/> where r.status != 'REMOVED' <if test="query.repositoryKey!=null"> @@ -317,12 +424,13 @@ r.updated_at desc </select> - <select id="selectByTypeAndLanguages" parameterType="map" resultType="Rule"> + <select id="selectByTypeAndLanguages" parameterType="map" resultMap="ruleResultMap"> select <include refid="selectJoinedTablesColumns"/> from rules r <include refid="outerJoinRulesMetadata"/> + <include refid="leftOuterJoinRulesDescriptionSections"/> where r.status != 'REMOVED' and r.is_external=${_false} and r.is_template=${_false} and r.rule_type in @@ -331,13 +439,27 @@ <foreach collection="languages" item="language" separator="," open="(" close=")">#{language, jdbcType=VARCHAR}</foreach> </select> + <insert id="insertRuleDescriptionSection" parameterType="Map" useGeneratedKeys="false"> + insert into rule_desc_sections ( + uuid, + rule_uuid, + kee, + description + ) + values ( + #{dto.uuid,jdbcType=VARCHAR}, + #{ruleUuid,jdbcType=VARCHAR}, + #{dto.key,jdbcType=VARCHAR}, + #{dto.description,jdbcType=VARCHAR} + ) + </insert> + <insert id="insertDefinition" parameterType="org.sonar.db.rule.RuleDefinitionDto" useGeneratedKeys="false"> insert into rules ( uuid, plugin_key, plugin_rule_key, plugin_name, - description, description_format, status, name, @@ -364,7 +486,6 @@ #{pluginKey,jdbcType=VARCHAR}, #{ruleKey,jdbcType=VARCHAR}, #{repositoryKey,jdbcType=VARCHAR}, - #{description,jdbcType=VARCHAR}, #{descriptionFormat,jdbcType=VARCHAR}, #{status,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, @@ -393,7 +514,6 @@ plugin_key=#{pluginKey,jdbcType=VARCHAR}, plugin_rule_key=#{ruleKey,jdbcType=VARCHAR}, plugin_name=#{repositoryKey,jdbcType=VARCHAR}, - description=#{description,jdbcType=VARCHAR}, description_format=#{descriptionFormat,jdbcType=VARCHAR}, status=#{status,jdbcType=VARCHAR}, name=#{name,jdbcType=VARCHAR}, @@ -417,6 +537,13 @@ uuid=#{uuid,jdbcType=VARCHAR} </update> + <delete id="deleteRuleDescriptionSection" parameterType="String"> + delete from + rule_desc_sections + where + rule_uuid=#{uuid,jdbcType=VARCHAR} + </delete> + <select id="countMetadata" parameterType="org.sonar.db.rule.RuleMetadataDto" resultType="int"> select count(1) diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDaoTest.java index 438b517a244..c68c59ad0bf 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDaoTest.java @@ -28,9 +28,8 @@ import java.util.List; import java.util.Optional; import java.util.Set; import java.util.function.Consumer; -import java.util.stream.Collectors; +import org.apache.commons.lang.RandomStringUtils; import org.apache.ibatis.exceptions.PersistenceException; -import org.apache.ibatis.session.ResultHandler; import org.junit.Rule; import org.junit.Test; import org.sonar.api.rule.RuleKey; @@ -41,6 +40,7 @@ import org.sonar.api.rules.RuleType; import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.api.utils.DateUtils; import org.sonar.api.utils.System2; +import org.sonar.core.util.UuidFactoryFast; import org.sonar.db.DbTester; import org.sonar.db.RowNotFoundException; import org.sonar.db.rule.RuleDto.Scope; @@ -49,18 +49,15 @@ import static com.google.common.collect.Sets.newHashSet; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; -import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic; import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.tuple; import static org.sonar.api.rule.RuleStatus.REMOVED; -import static org.sonar.db.rule.RuleDescriptionSectionDto.createDefaultRuleDescriptionSection; import static org.sonar.db.rule.RuleTesting.newRuleMetadata; public class RuleDaoTest { private static final String UNKNOWN_RULE_UUID = "unknown-uuid"; - private static final RuleDescriptionSectionDto RULE_DESCRIPTION_SECTION_1 = createDefaultRuleDescriptionSection("new description"); @Rule public DbTester db = DbTester.create(System2.INSTANCE); @@ -299,9 +296,7 @@ public class RuleDaoTest { RuleDefinitionDto rule = db.rules().insert(); db.rules().insert(r -> r.setStatus(REMOVED)); - final List<RuleDefinitionDto> rules = new ArrayList<>(); - ResultHandler<RuleDefinitionDto> resultHandler = resultContext -> rules.add(resultContext.getResultObject()); - underTest.selectEnabled(db.getSession(), resultHandler); + List<RuleDefinitionDto> rules = underTest.selectEnabled(db.getSession()); assertThat(rules.size()).isOne(); RuleDefinitionDto ruleDto = rules.get(0); @@ -427,13 +422,14 @@ public class RuleDaoTest { @Test public void insert() { + RuleDescriptionSectionDto sectionDto = createDefaultRuleDescriptionSection(); RuleDefinitionDto newRule = new RuleDefinitionDto() .setUuid("rule-uuid") .setRuleKey("NewRuleKey") .setRepositoryKey("plugin") .setName("new name") .setDescriptionFormat(RuleDto.Format.MARKDOWN) - .addRuleDescriptionSectionDto(RULE_DESCRIPTION_SECTION_1) + .addRuleDescriptionSectionDto(sectionDto) .setStatus(RuleStatus.DEPRECATED) .setConfigKey("NewConfigKey") .setSeverity(Severity.INFO) @@ -480,19 +476,20 @@ public class RuleDaoTest { assertThat(ruleDto.getUpdatedAt()).isEqualTo(2_000_000_000_000L); assertThat(ruleDto.getDescriptionFormat()).isEqualTo(RuleDto.Format.MARKDOWN); assertThat(ruleDto.getRuleDescriptionSectionDtos()).usingRecursiveFieldByFieldElementComparator() - .containsOnly(RULE_DESCRIPTION_SECTION_1); + .containsOnly(sectionDto); } @Test public void update_RuleDefinitionDto() { RuleDefinitionDto rule = db.rules().insert(); + RuleDescriptionSectionDto sectionDto = createDefaultRuleDescriptionSection(); RuleDefinitionDto ruleToUpdate = new RuleDefinitionDto() .setUuid(rule.getUuid()) .setRuleKey("NewRuleKey") .setRepositoryKey("plugin") .setName("new name") .setDescriptionFormat(RuleDto.Format.MARKDOWN) - .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(randomAlphabetic(5))) + .addRuleDescriptionSectionDto(sectionDto) .setStatus(RuleStatus.DEPRECATED) .setConfigKey("NewConfigKey") .setSeverity(Severity.INFO) @@ -537,8 +534,53 @@ public class RuleDaoTest { assertThat(ruleDto.getCreatedAt()).isEqualTo(rule.getCreatedAt()); assertThat(ruleDto.getUpdatedAt()).isEqualTo(2_000_000_000_000L); assertThat(ruleDto.getDescriptionFormat()).isEqualTo(RuleDto.Format.MARKDOWN); + assertThat(ruleDto.getRuleDescriptionSectionDtos()).usingRecursiveFieldByFieldElementComparator() - .containsOnly(RULE_DESCRIPTION_SECTION_1); + .containsOnly(sectionDto); + } + + @Test + public void update_rule_sections_add_new_section() { + RuleDefinitionDto rule = db.rules().insert(); + RuleDescriptionSectionDto existingSection = rule.getRuleDescriptionSectionDtos().iterator().next(); + RuleDescriptionSectionDto newSection = RuleDescriptionSectionDto.builder() + .uuid(randomAlphanumeric(20)) + .key("new_key") + .description(randomAlphanumeric(1000)) + .build(); + + rule.addRuleDescriptionSectionDto(newSection); + + underTest.update(db.getSession(), rule); + db.getSession().commit(); + + RuleDefinitionDto ruleDto = underTest.selectOrFailDefinitionByKey(db.getSession(), RuleKey.of(rule.getRepositoryKey(), rule.getRuleKey())); + + assertThat(ruleDto.getRuleDescriptionSectionDtos()) + .usingRecursiveFieldByFieldElementComparator() + .containsExactlyInAnyOrder(newSection, existingSection); + } + + @Test + public void update_rule_sections_replaces_section() { + RuleDefinitionDto rule = db.rules().insert(); + RuleDescriptionSectionDto existingSection = rule.getRuleDescriptionSectionDtos().iterator().next(); + RuleDescriptionSectionDto replacingSection = RuleDescriptionSectionDto.builder() + .uuid(randomAlphanumeric(20)) + .key(existingSection.getKey()) + .description(randomAlphanumeric(1000)) + .build(); + + rule.addOrReplaceRuleDescriptionSectionDto(replacingSection); + + underTest.update(db.getSession(), rule); + db.getSession().commit(); + + RuleDefinitionDto ruleDto = underTest.selectOrFailDefinitionByKey(db.getSession(), RuleKey.of(rule.getRepositoryKey(), rule.getRuleKey())); + + assertThat(ruleDto.getRuleDescriptionSectionDtos()) + .usingRecursiveFieldByFieldElementComparator() + .containsOnly(replacingSection); } @Test @@ -806,7 +848,7 @@ public class RuleDaoTest { assertThat(firstRule.getPluginRuleKey()).isEqualTo(r1.getRuleKey()); assertThat(firstRule.getName()).isEqualTo(r1.getName()); //FIXME SONAR-16309 - assertThat(firstRule.getDescription()).isEqualTo(r1.getRuleDescriptionSectionDtos().stream().map(RuleDescriptionSectionDto::getDescription).collect(Collectors.joining())); + //assertThat(firstRule.getDescription()).isEqualTo(r1.getRuleDescriptionSectionDtos().stream().map(RuleDescriptionSectionDto::getDescription).collect(Collectors.joining())); assertThat(firstRule.getDescriptionFormat()).isEqualTo(r1.getDescriptionFormat()); assertThat(firstRule.getSeverity()).isEqualTo(r1.getSeverity()); assertThat(firstRule.getStatus()).isEqualTo(r1.getStatus()); @@ -886,7 +928,7 @@ public class RuleDaoTest { assertThat(firstRule.getPluginRuleKey()).isEqualTo(r1.getRuleKey()); assertThat(firstRule.getName()).isEqualTo(r1.getName()); //FIXME SONAR-16309 - assertThat(firstRule.getDescription()).isEqualTo(r1.getRuleDescriptionSectionDtos().stream().map(RuleDescriptionSectionDto::getDescription).collect(Collectors.joining())); + //assertThat(firstRule.getDescription()).isEqualTo(r1.getRuleDescriptionSectionDtos().stream().map(RuleDescriptionSectionDto::getDescription).collect(Collectors.joining())); assertThat(firstRule.getDescriptionFormat()).isEqualTo(r1.getDescriptionFormat()); assertThat(firstRule.getSeverity()).isEqualTo(r1.getSeverity()); assertThat(firstRule.getSeverityAsString()).isEqualTo(SeverityUtil.getSeverityFromOrdinal(r1.getSeverity())); @@ -1047,6 +1089,10 @@ public class RuleDaoTest { .isInstanceOf(PersistenceException.class); } + private static RuleDescriptionSectionDto createDefaultRuleDescriptionSection() { + return RuleDescriptionSectionDto.createDefaultRuleDescriptionSection(UuidFactoryFast.getInstance().create(), RandomStringUtils.randomAlphanumeric(1000)); + } + private static class Accumulator<T> implements Consumer<T> { private final List<T> list = new ArrayList<>(); diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/rule/RuleTesting.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/rule/RuleTesting.java index b544afa6379..28f8fc3d219 100644 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/rule/RuleTesting.java +++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/rule/RuleTesting.java @@ -66,7 +66,7 @@ public class RuleTesting { public static RuleDefinitionDto newRule(RuleKey key) { RuleDefinitionDto ruleDefinitionDto = newRuleWithoutSection(key); - ruleDefinitionDto.addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("description_" + randomAlphabetic(5))); + ruleDefinitionDto.addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "description_" + randomAlphabetic(5))); return ruleDefinitionDto; } @@ -181,7 +181,7 @@ public class RuleTesting { .setRepositoryKey(ruleKey.repository()) .setName("Rule " + ruleKey.rule()) .setDescriptionFormat(RuleDto.Format.HTML) - .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("Description" + ruleKey.rule())) + .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "Description" + ruleKey.rule())) .setStatus(RuleStatus.READY) .setConfigKey("InternalKey" + ruleKey.rule()) .setSeverity(Severity.INFO) diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/rule/DefaultRuleFinder.java b/server/sonar-server-common/src/main/java/org/sonar/server/rule/DefaultRuleFinder.java index e821838fd17..d423396f329 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/rule/DefaultRuleFinder.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/rule/DefaultRuleFinder.java @@ -75,9 +75,7 @@ public class DefaultRuleFinder implements ServerRuleFinder { @Override public Collection<RuleDefinitionDto> findAll() { try (DbSession dbSession = dbClient.openSession(false)) { - List<RuleDefinitionDto> list = new ArrayList<>(); - ruleDao.selectEnabled(dbSession, r -> list.add(r.getResultObject())); - return list; + return ruleDao.selectEnabled(dbSession); } } diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/rule/HotspotRuleDescriptionTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/rule/HotspotRuleDescriptionTest.java index 12c34c19c62..494b8af7a16 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/rule/HotspotRuleDescriptionTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/rule/HotspotRuleDescriptionTest.java @@ -48,7 +48,7 @@ public class HotspotRuleDescriptionTest { @Test public void parse_returns_all_empty_fields_when_empty_description() { - RuleDefinitionDto dto = newRuleWithoutSection().addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("")); + RuleDefinitionDto dto = newRuleWithoutSection().addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("uuid", "")); HotspotRuleDescription result = HotspotRuleDescription.from(dto); @@ -60,7 +60,7 @@ public class HotspotRuleDescriptionTest { @Test @UseDataProvider("descriptionsWithoutTitles") public void parse_to_risk_description_fields_when_desc_contains_no_section(String description) { - RuleDefinitionDto dto = newRuleWithoutSection().addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(description)); + RuleDefinitionDto dto = newRuleWithoutSection().addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("uuid", description)); HotspotRuleDescription result = HotspotRuleDescription.from(dto); @@ -82,7 +82,7 @@ public class HotspotRuleDescriptionTest { @Test public void parse_return_null_risk_when_desc_starts_with_ask_yourself_title() { RuleDefinitionDto dto = newRuleWithoutSection().addRuleDescriptionSectionDto( - createDefaultRuleDescriptionSection((ASKATRISK + RECOMMENTEDCODINGPRACTICE))); + createDefaultRuleDescriptionSection("uuid", (ASKATRISK + RECOMMENTEDCODINGPRACTICE))); HotspotRuleDescription result = HotspotRuleDescription.from(dto); @@ -94,7 +94,7 @@ public class HotspotRuleDescriptionTest { @Test public void parse_return_null_vulnerable_when_no_ask_yourself_whether_title() { RuleDefinitionDto dto = newRuleWithoutSection() - .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection((DESCRIPTION + RECOMMENTEDCODINGPRACTICE))); + .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("uuid", (DESCRIPTION + RECOMMENTEDCODINGPRACTICE))); HotspotRuleDescription result = HotspotRuleDescription.from(dto); @@ -106,7 +106,7 @@ public class HotspotRuleDescriptionTest { @Test public void parse_return_null_fixIt_when_desc_has_no_Recommended_Secure_Coding_Practices_title() { RuleDefinitionDto dto = newRuleWithoutSection() - .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection((DESCRIPTION + ASKATRISK))); + .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("uuid", (DESCRIPTION + ASKATRISK))); HotspotRuleDescription result = HotspotRuleDescription.from(dto); @@ -118,7 +118,7 @@ public class HotspotRuleDescriptionTest { @Test public void parse_with_noncompliant_section_not_removed() { RuleDefinitionDto dto = newRuleWithoutSection().addRuleDescriptionSectionDto( - createDefaultRuleDescriptionSection((DESCRIPTION + NONCOMPLIANTCODE + COMPLIANTCODE))); + createDefaultRuleDescriptionSection("uuid", (DESCRIPTION + NONCOMPLIANTCODE + COMPLIANTCODE))); HotspotRuleDescription result = HotspotRuleDescription.from(dto); @@ -130,7 +130,7 @@ public class HotspotRuleDescriptionTest { @Test public void parse_moved_noncompliant_code() { RuleDefinitionDto dto = newRuleWithoutSection().addRuleDescriptionSectionDto( - createDefaultRuleDescriptionSection((DESCRIPTION + RECOMMENTEDCODINGPRACTICE + NONCOMPLIANTCODE + SEE))); + createDefaultRuleDescriptionSection("uuid", (DESCRIPTION + RECOMMENTEDCODINGPRACTICE + NONCOMPLIANTCODE + SEE))); HotspotRuleDescription result = HotspotRuleDescription.from(dto); @@ -144,7 +144,7 @@ public class HotspotRuleDescriptionTest { @Test public void parse_moved_sensitivecode_code() { RuleDefinitionDto dto = newRuleWithoutSection().addRuleDescriptionSectionDto( - createDefaultRuleDescriptionSection((DESCRIPTION + ASKATRISK + RECOMMENTEDCODINGPRACTICE + SENSITIVECODE + SEE))); + createDefaultRuleDescriptionSection("uuid", (DESCRIPTION + ASKATRISK + RECOMMENTEDCODINGPRACTICE + SENSITIVECODE + SEE))); HotspotRuleDescription result = HotspotRuleDescription.from(dto); @@ -164,7 +164,7 @@ public class HotspotRuleDescriptionTest { .setTemplateUuid("123") .setDescriptionFormat(RuleDto.Format.MARKDOWN) .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection( - ruleDescription + "\n" + "uuid", ruleDescription + "\n" + "== Exceptions" + "\n" + exceptionsContent + "\n" + "== Ask Yourself Whether" + "\n" diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/rule/RuleDescriptionFormatterTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/rule/RuleDescriptionFormatterTest.java index b50f77deb3e..ca8ca7d6da2 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/rule/RuleDescriptionFormatterTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/rule/RuleDescriptionFormatterTest.java @@ -29,8 +29,8 @@ import static org.sonar.db.rule.RuleDescriptionSectionDto.createDefaultRuleDescr public class RuleDescriptionFormatterTest { - private static final RuleDescriptionSectionDto HTML_SECTION = createDefaultRuleDescriptionSection("<span class=\"example\">*md* ``description``</span>"); - private static final RuleDescriptionSectionDto MARKDOWN_SECTION = createDefaultRuleDescriptionSection("*md* ``description``"); + private static final RuleDescriptionSectionDto HTML_SECTION = createDefaultRuleDescriptionSection("uuid", "<span class=\"example\">*md* ``description``</span>"); + private static final RuleDescriptionSectionDto MARKDOWN_SECTION = createDefaultRuleDescriptionSection("uuid", "*md* ``description``"); @Test public void getMarkdownDescriptionAsHtml() { @@ -55,7 +55,7 @@ public class RuleDescriptionFormatterTest { @Test public void handleNullDescriptionFormat() { - RuleDescriptionSectionDto sectionWithNullFormat = createDefaultRuleDescriptionSection("whatever"); + RuleDescriptionSectionDto sectionWithNullFormat = createDefaultRuleDescriptionSection("uuid", "whatever"); RuleDefinitionDto rule = new RuleDefinitionDto().addRuleDescriptionSectionDto(sectionWithNullFormat); String result = RuleDescriptionFormatter.getDescriptionAsHtml(rule); assertThat(result).isNull(); diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java index d4ae6d45d5b..d617fd46c29 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java @@ -33,6 +33,8 @@ import org.sonar.api.impl.utils.AlwaysIncreasingSystem2; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.utils.System2; +import org.sonar.core.util.UuidFactory; +import org.sonar.core.util.UuidFactoryFast; import org.sonar.db.DbTester; import org.sonar.db.qualityprofile.QProfileDto; import org.sonar.db.rule.RuleDefinitionDto; @@ -103,7 +105,8 @@ public class RuleIndexTest { private ActiveRuleIndexer activeRuleIndexer = new ActiveRuleIndexer(db.getDbClient(), es.client()); private RuleIndex underTest = new RuleIndex(es.client(), system2); - + private UuidFactory uuidFactory = UuidFactoryFast.getInstance(); + @Test public void search_all_rules() { createRule(); @@ -214,19 +217,20 @@ public class RuleIndexTest { // otherwise the generated random values may raise false-positives RuleDefinitionDto rule1 = createJavaRule(rule -> rule.setRuleKey("123") .setName("rule 123") - .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("My great rule CWE-123 which makes your code 1000 times better!"))); + .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "My great rule CWE-123 which makes your code 1000 times better!"))); RuleDefinitionDto rule2 = createJavaRule(rule -> rule.setRuleKey("124") .setName("rule 124") - .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("Another great and shiny rule CWE-124"))); + .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "Another great and shiny rule CWE-124"))); RuleDefinitionDto rule3 = createJavaRule(rule -> rule.setRuleKey("1000") .setName("rule 1000") - .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("Another great rule CWE-1000"))); + .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "Another great rule CWE-1000"))); RuleDefinitionDto rule4 = createJavaRule(rule -> rule.setRuleKey("404") .setName("rule 404") - .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("<h1>HTML-Geeks</h1><p style=\"color:blue\">special formatting!</p><table><tr><td>inside</td><td>tables</td></tr></table>"))); + .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), + "<h1>HTML-Geeks</h1><p style=\"color:blue\">special formatting!</p><table><tr><td>inside</td><td>tables</td></tr></table>"))); RuleDefinitionDto rule5 = createJavaRule(rule -> rule.setRuleKey("405") .setName("rule 405") - .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("internationalization missunderstandings alsdkjfnadklsjfnadkdfnsksdjfn"))); + .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "internationalization missunderstandings alsdkjfnadklsjfnadkdfnsksdjfn"))); index(); // partial match at word boundary diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexerTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexerTest.java index e3362dd71ee..1c8a1ee73e1 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexerTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexerTest.java @@ -36,6 +36,7 @@ import org.sonar.api.rule.Severity; import org.sonar.api.rules.RuleType; import org.sonar.api.utils.log.LogTester; import org.sonar.api.utils.log.LoggerLevel; +import org.sonar.core.util.UuidFactoryFast; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; @@ -43,7 +44,6 @@ import org.sonar.db.rule.RuleDefinitionDto; import org.sonar.db.rule.RuleDescriptionSectionDto; import org.sonar.db.rule.RuleDto; import org.sonar.db.rule.RuleDto.Scope; -import org.sonar.db.rule.RuleTesting; import org.sonar.server.es.EsTester; import org.sonar.server.security.SecurityStandards; import org.sonar.server.security.SecurityStandards.SQCategory; @@ -56,6 +56,7 @@ import static java.util.stream.Collectors.toSet; import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic; import static org.assertj.core.api.Assertions.assertThat; import static org.sonar.db.rule.RuleDescriptionSectionDto.createDefaultRuleDescriptionSection; +import static org.sonar.db.rule.RuleTesting.newRuleWithoutSection; import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_RULE; import static org.sonar.server.security.SecurityStandards.CWES_BY_SQ_CATEGORY; import static org.sonar.server.security.SecurityStandards.SQ_CATEGORY_KEYS_ORDERING; @@ -69,7 +70,8 @@ public class RuleIndexerTest { "<h2>Recommended Secure Coding Practices</h2>\n" + "foo"; - private static final RuleDescriptionSectionDto RULE_DESCRIPTION_SECTION_DTO = createDefaultRuleDescriptionSection(VALID_HOTSPOT_RULE_DESCRIPTION); + private static final UuidFactoryFast uuidFactory = UuidFactoryFast.getInstance(); + private static final RuleDescriptionSectionDto RULE_DESCRIPTION_SECTION_DTO = createDefaultRuleDescriptionSection(uuidFactory.create(), VALID_HOTSPOT_RULE_DESCRIPTION); @Rule public EsTester es = EsTester.create(); @@ -131,8 +133,8 @@ public class RuleIndexerTest { @Test public void index_long_rule_description() { String description = IntStream.range(0, 100000).map(i -> i % 100).mapToObj(Integer::toString).collect(joining(" ")); - RuleDescriptionSectionDto ruleDescriptionSectionDto = createDefaultRuleDescriptionSection(description); - RuleDefinitionDto rule = dbTester.rules().insert(r -> r.addRuleDescriptionSectionDto(ruleDescriptionSectionDto)); + RuleDescriptionSectionDto ruleDescriptionSectionDto = createDefaultRuleDescriptionSection(uuidFactory.create(), description); + RuleDefinitionDto rule = dbTester.rules().insert(r -> r.addOrReplaceRuleDescriptionSectionDto(ruleDescriptionSectionDto)); underTest.commitAndIndex(dbTester.getSession(), rule.getUuid()); assertThat(es.countDocuments(TYPE_RULE)).isOne(); @@ -145,7 +147,7 @@ public class RuleIndexerTest { .flatMap(t -> CWES_BY_SQ_CATEGORY.get(t).stream().map(e -> "cwe:" + e)) .collect(toSet()); SecurityStandards securityStandards = SecurityStandards.fromSecurityStandards(standards); - RuleDefinitionDto rule = dbTester.rules().insert(RuleTesting.newRule() + RuleDefinitionDto rule = dbTester.rules().insert(newRuleWithoutSection() .setType(RuleType.SECURITY_HOTSPOT) .setSecurityStandards(standards) .addRuleDescriptionSectionDto(RULE_DESCRIPTION_SECTION_DTO)); @@ -180,7 +182,7 @@ public class RuleIndexerTest { @Test public void log_debug_when_hotspot_rule_no_description () { - RuleDefinitionDto rule = dbTester.rules().insert(RuleTesting.newRuleWithoutSection() + RuleDefinitionDto rule = dbTester.rules().insert(newRuleWithoutSection() .setType(RuleType.SECURITY_HOTSPOT)); underTest.commitAndIndex(dbTester.getSession(), rule.getUuid()); @@ -193,9 +195,9 @@ public class RuleIndexerTest { @Test public void log_debug_when_hotspot_rule_description_has_none_of_the_key_titles() { - RuleDefinitionDto rule = dbTester.rules().insert(RuleTesting.newRule() + RuleDefinitionDto rule = dbTester.rules().insert(newRuleWithoutSection() .setType(RuleType.SECURITY_HOTSPOT) - .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(randomAlphabetic(30)))); + .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), randomAlphabetic(30)))); underTest.commitAndIndex(dbTester.getSession(), rule.getUuid()); assertThat(logTester.getLogs()).hasSize(1); @@ -207,9 +209,9 @@ public class RuleIndexerTest { @Test public void log_debug_when_hotspot_rule_description_is_missing_fixIt_tab_content() { - RuleDefinitionDto rule = dbTester.rules().insert(RuleTesting.newRule() + RuleDefinitionDto rule = dbTester.rules().insert(newRuleWithoutSection() .setType(RuleType.SECURITY_HOTSPOT) - .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("bar\n" + + .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "bar\n" + "<h2>Ask Yourself Whether</h2>\n" + "foo"))); underTest.commitAndIndex(dbTester.getSession(), rule.getUuid()); @@ -223,9 +225,9 @@ public class RuleIndexerTest { @Test public void log_debug_when_hotspot_rule_description_is_missing_risk_tab_content() { - RuleDefinitionDto rule = dbTester.rules().insert(RuleTesting.newRule() + RuleDefinitionDto rule = dbTester.rules().insert(newRuleWithoutSection() .setType(RuleType.SECURITY_HOTSPOT) - .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("<h2>Ask Yourself Whether</h2>\n" + + .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "<h2>Ask Yourself Whether</h2>\n" + "bar\n" + "<h2>Recommended Secure Coding Practices</h2>\n" + "foo"))); @@ -240,9 +242,9 @@ public class RuleIndexerTest { @Test public void log_debug_when_hotspot_rule_description_is_missing_vulnerable_tab_content() { - RuleDefinitionDto rule = dbTester.rules().insert(RuleTesting.newRule() + RuleDefinitionDto rule = dbTester.rules().insert(newRuleWithoutSection() .setType(RuleType.SECURITY_HOTSPOT) - .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("bar\n" + + .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "bar\n" + "<h2>Recommended Secure Coding Practices</h2>\n" + "foo"))); underTest.commitAndIndex(dbTester.getSession(), rule.getUuid()); diff --git a/server/sonar-webserver-api/src/test/java/org/sonar/server/rule/CachingRuleFinderTest.java b/server/sonar-webserver-api/src/test/java/org/sonar/server/rule/CachingRuleFinderTest.java index cd2c2235981..57db0bb1390 100644 --- a/server/sonar-webserver-api/src/test/java/org/sonar/server/rule/CachingRuleFinderTest.java +++ b/server/sonar-webserver-api/src/test/java/org/sonar/server/rule/CachingRuleFinderTest.java @@ -46,7 +46,6 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; -import static org.sonar.db.rule.RuleDescriptionSectionDto.createDefaultRuleDescriptionSection; public class CachingRuleFinderTest { @org.junit.Rule @@ -423,7 +422,7 @@ public class CachingRuleFinderTest { assertThat(rule.getSeverity().name()).isEqualTo(ruleDefinition.getSeverityString()); assertThat(rule.getSystemTags()).isEqualTo(ruleDefinition.getSystemTags().toArray(new String[0])); assertThat(rule.getTags()).isEmpty(); - assertThat(rule.getDescription()).isEqualTo(createDefaultRuleDescriptionSection(randomAlphabetic(5)).getDescription()); + assertThat(rule.getDescription()).isEqualTo(ruleDefinition.getDefaultRuleDescriptionSectionDto().getDescription()); assertThat(rule.getParams()).hasSize(1); org.sonar.api.rules.RuleParam param = rule.getParams().iterator().next(); diff --git a/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/RegisterRules.java b/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/RegisterRules.java index fb4e08ec15a..5540f8f376c 100644 --- a/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/RegisterRules.java +++ b/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/RegisterRules.java @@ -401,10 +401,10 @@ public class RegisterRules implements Startable { .setCreatedAt(system2.now()) .setUpdatedAt(system2.now()); if (isNotEmpty(ruleDef.htmlDescription())) { - ruleDto.addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(ruleDef.htmlDescription())); + ruleDto.addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), ruleDef.htmlDescription())); ruleDto.setDescriptionFormat(Format.HTML); } else if (isNotEmpty(ruleDef.markdownDescription())) { - ruleDto.addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(ruleDef.markdownDescription())); + ruleDto.addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), ruleDef.markdownDescription())); ruleDto.setDescriptionFormat(Format.MARKDOWN); } @@ -433,7 +433,7 @@ public class RegisterRules implements Startable { } } - private static boolean mergeRule(RulesDefinition.Rule def, RuleDefinitionDto dto) { + private boolean mergeRule(RulesDefinition.Rule def, RuleDefinitionDto dto) { boolean changed = false; if (!Objects.equals(dto.getName(), def.name())) { dto.setName(def.name()); @@ -484,16 +484,16 @@ public class RegisterRules implements Startable { return changed; } - private static boolean mergeDescription(RulesDefinition.Rule rule, RuleDefinitionDto ruleDefinitionDto) { + private boolean mergeDescription(RulesDefinition.Rule rule, RuleDefinitionDto ruleDefinitionDto) { boolean changed = false; String currentDescription = ruleDefinitionDto.getDefaultRuleDescriptionSectionDto() != null ? ruleDefinitionDto.getDefaultRuleDescriptionSectionDto().getDescription() : null; if (isHtmlDescriptionUpdated(rule, currentDescription)) { - ruleDefinitionDto.addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(rule.htmlDescription())); + ruleDefinitionDto.addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), rule.htmlDescription())); ruleDefinitionDto.setDescriptionFormat(Format.HTML); changed = true; } else if (isMarkdownDescriptionUpdated(rule, currentDescription)) { - ruleDefinitionDto.addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(rule.markdownDescription())); + ruleDefinitionDto.addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), rule.markdownDescription())); ruleDefinitionDto.setDescriptionFormat(Format.MARKDOWN); changed = true; } diff --git a/server/sonar-webserver-core/src/test/java/org/sonar/server/rule/RegisterRulesTest.java b/server/sonar-webserver-core/src/test/java/org/sonar/server/rule/RegisterRulesTest.java index e9cbb4ebbc7..34d1c8deaad 100644 --- a/server/sonar-webserver-core/src/test/java/org/sonar/server/rule/RegisterRulesTest.java +++ b/server/sonar-webserver-core/src/test/java/org/sonar/server/rule/RegisterRulesTest.java @@ -836,7 +836,7 @@ public class RegisterRulesTest { .setRepositoryKey("findbugs") .setName("Rule One") .setScope(Scope.ALL) - .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("Rule one description")) + .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "Rule one description")) .setDescriptionFormat(RuleDto.Format.HTML) .setSystemTags(newHashSet("tag1", "tag2"))); db.getSession().commit(); diff --git a/server/sonar-webserver-pushapi/src/test/java/org/sonar/server/qualityprofile/builtin/QualityProfileChangeEventServiceImplTest.java b/server/sonar-webserver-pushapi/src/test/java/org/sonar/server/qualityprofile/builtin/QualityProfileChangeEventServiceImplTest.java index 77b5db39783..f96821ea009 100644 --- a/server/sonar-webserver-pushapi/src/test/java/org/sonar/server/qualityprofile/builtin/QualityProfileChangeEventServiceImplTest.java +++ b/server/sonar-webserver-pushapi/src/test/java/org/sonar/server/qualityprofile/builtin/QualityProfileChangeEventServiceImplTest.java @@ -74,7 +74,7 @@ public class QualityProfileChangeEventServiceImplTest { .setRepositoryKey("repo") .setRuleKey("ruleKey") .setDescriptionFormat(RuleDto.Format.MARKDOWN) - .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("<div>line1\nline2</div>")); + .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("uuid", "<div>line1\nline2</div>")); db.rules().insert(rule1); ActiveRuleDto activeRuleDto = ActiveRuleDto.createFor(qualityProfileDto, rule1); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/RuleCreator.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/RuleCreator.java index e67c9d22a4d..b7d321877a7 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/RuleCreator.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/RuleCreator.java @@ -208,7 +208,7 @@ public class RuleCreator { .setUpdatedAt(system2.now()); if (newRule.markdownDescription() != null) { - RuleDescriptionSectionDto ruleDescriptionSectionDto = createDefaultRuleDescriptionSection(newRule.markdownDescription()); + RuleDescriptionSectionDto ruleDescriptionSectionDto = createDefaultRuleDescriptionSection(uuidFactory.create(), newRule.markdownDescription()); ruleDefinition.setDescriptionFormat(Format.MARKDOWN); ruleDefinition.addRuleDescriptionSectionDto(ruleDescriptionSectionDto); } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/RuleUpdater.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/RuleUpdater.java index 78e4aebf313..c6fa6e3342d 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/RuleUpdater.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/RuleUpdater.java @@ -37,6 +37,7 @@ import org.sonar.api.rule.Severity; import org.sonar.api.server.ServerSide; import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.api.utils.System2; +import org.sonar.core.util.UuidFactory; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.qualityprofile.ActiveRuleDto; @@ -61,11 +62,13 @@ public class RuleUpdater { private final DbClient dbClient; private final RuleIndexer ruleIndexer; + private final UuidFactory uuidFactory; private final System2 system; - public RuleUpdater(DbClient dbClient, RuleIndexer ruleIndexer, System2 system) { + public RuleUpdater(DbClient dbClient, RuleIndexer ruleIndexer, UuidFactory uuidFactory, System2 system) { this.dbClient = dbClient; this.ruleIndexer = ruleIndexer; + this.uuidFactory = uuidFactory; this.system = system; } @@ -133,12 +136,12 @@ public class RuleUpdater { rule.setName(name); } - private static void updateDescription(RuleUpdate update, RuleDto rule) { + private void updateDescription(RuleUpdate update, RuleDto rule) { String description = update.getMarkdownDescription(); if (isNullOrEmpty(description)) { throw new IllegalArgumentException("The description is missing"); } - RuleDescriptionSectionDto descriptionSectionDto = createDefaultRuleDescriptionSection(description); + RuleDescriptionSectionDto descriptionSectionDto = createDefaultRuleDescriptionSection(uuidFactory.create(), description); rule.setDescriptionFormat(RuleDto.Format.MARKDOWN); rule.addOrReplaceRuleDescriptionSectionDto(descriptionSectionDto); } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/ListAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/ListAction.java index 70823cd4d32..a3245751914 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/ListAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/ListAction.java @@ -19,6 +19,7 @@ */ package org.sonar.server.rule.ws; +import java.util.Set; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; @@ -29,6 +30,7 @@ import org.sonarqube.ws.MediaTypes; import org.sonarqube.ws.Rules.ListResponse; import static com.google.common.base.Strings.nullToEmpty; +import static java.util.stream.Collectors.toSet; public class ListAction implements RulesWsAction { @@ -54,21 +56,24 @@ public class ListAction implements RulesWsAction { final ListResponse.Builder listResponseBuilder = ListResponse.newBuilder(); final ListResponse.Rule.Builder ruleBuilder = ListResponse.Rule.newBuilder(); try (DbSession dbSession = dbClient.openSession(false)) { - dbClient.ruleDao().selectEnabled(dbSession, resultContext -> { - RuleDefinitionDto dto = resultContext.getResultObject(); - ruleBuilder - .clear() - .setRepository(dto.getRepositoryKey()) - .setKey(dto.getRuleKey()) - .setName(nullToEmpty(dto.getName())) - .setInternalKey(nullToEmpty(dto.getConfigKey())); - listResponseBuilder.addRules(ruleBuilder.build()); - }); + Set<ListResponse.Rule> rules = dbClient.ruleDao().selectEnabled(dbSession).stream() + .map(dto -> toRule(ruleBuilder, dto)) + .collect(toSet()); + listResponseBuilder.addAllRules(rules); } - // JSON response is voluntarily not supported. This WS is for internal use. wsResponse.stream().setMediaType(MediaTypes.PROTOBUF); listResponseBuilder.build().writeTo(wsResponse.stream().output()); } + private ListResponse.Rule toRule(ListResponse.Rule.Builder ruleBuilder, RuleDefinitionDto dto) { + return ruleBuilder + .clear() + .setRepository(dto.getRepositoryKey()) + .setKey(dto.getRuleKey()) + .setName(nullToEmpty(dto.getName())) + .setInternalKey(nullToEmpty(dto.getConfigKey())) + .build(); + } + } diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/hotspot/ws/ShowActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/hotspot/ws/ShowActionTest.java index fd9c031e807..d791c487edc 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/hotspot/ws/ShowActionTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/hotspot/ws/ShowActionTest.java @@ -45,6 +45,8 @@ import org.sonar.api.issue.Issue; import org.sonar.api.rules.RuleType; import org.sonar.api.utils.System2; import org.sonar.api.web.UserRole; +import org.sonar.core.util.UuidFactory; +import org.sonar.core.util.UuidFactoryFast; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; @@ -113,6 +115,7 @@ public class ShowActionTest { private final TextRangeResponseFormatter textRangeFormatter = new TextRangeResponseFormatter(); private final ShowAction underTest = new ShowAction(dbClient, hotspotWsSupport, responseFormatter, textRangeFormatter, userFormatter, issueChangeSupport); private final WsActionTester actionTester = new WsActionTester(underTest); + private final UuidFactory uuidFactory = UuidFactoryFast.getInstance(); @Test public void ws_is_public() { @@ -435,7 +438,7 @@ public class ShowActionTest { RuleDefinitionDto rule = newRuleWithoutSection(SECURITY_HOTSPOT, r -> r.setTemplateUuid("123") - .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(description)) + .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), description)) .setDescriptionFormat(MARKDOWN)); IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file); @@ -454,7 +457,7 @@ public class ShowActionTest { userSessionRule.logIn().addProjectPermission(UserRole.USER, project); ComponentDto file = dbTester.components().insertComponent(newFileDto(project)); - RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT, r -> r.setTemplateUuid("123")); + RuleDefinitionDto rule = newRuleWithoutSection(SECURITY_HOTSPOT, r -> r.setTemplateUuid("123")); IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file); mockChangelogAndCommentsFormattingContext(); diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/SearchActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/SearchActionTest.java index cfc87dc6e5f..2954b7b8c8c 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/SearchActionTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/SearchActionTest.java @@ -40,6 +40,7 @@ import org.sonar.api.rules.RuleType; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.Durations; import org.sonar.api.utils.System2; +import org.sonar.core.util.UuidFactoryFast; import org.sonar.core.util.Uuids; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -118,6 +119,7 @@ import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SINCE_LEAK_ public class SearchActionTest { + private final UuidFactoryFast uuidFactory = UuidFactoryFast.getInstance(); @Rule public UserSessionRule userSession = standalone(); @Rule @@ -1442,7 +1444,7 @@ public class SearchActionTest { private RuleDto newIssueRule() { RuleDto rule = RuleTesting.newXooX1() .setName("Rule name") - .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("Rule desc")) + .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "Rule desc")) .setStatus(RuleStatus.READY); db.rules().insert(rule.getDefinition()); return rule; @@ -1451,7 +1453,7 @@ public class SearchActionTest { private RuleDto newHotspotRule() { RuleDto rule = RuleTesting.newXooX2() .setName("Rule name") - .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("Rule desc")) + .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "Rule desc")) .setStatus(RuleStatus.READY) .setType(SECURITY_HOTSPOT_VALUE); db.rules().insert(rule.getDefinition()); diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualityprofile/QProfileBackuperImplTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualityprofile/QProfileBackuperImplTest.java index a4faa701fa1..08e74098b12 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualityprofile/QProfileBackuperImplTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualityprofile/QProfileBackuperImplTest.java @@ -35,6 +35,7 @@ import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rules.RuleType; import org.sonar.api.utils.System2; +import org.sonar.core.util.UuidFactoryFast; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.qualityprofile.ActiveRuleDto; @@ -142,7 +143,7 @@ public class QProfileBackuperImplTest { RuleDefinitionDto templateRule = db.rules().insert(ruleDefinitionDto -> ruleDefinitionDto .setIsTemplate(true)); RuleDefinitionDto rule = db.rules().insert(ruleDefinitionDto -> ruleDefinitionDto - .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("custom rule description")) + .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(UuidFactoryFast.getInstance().create(), "custom rule description")) .setName("custom rule name") .setStatus(RuleStatus.READY) .setTemplateUuid(templateRule.getUuid())); diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/RuleCreatorTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/RuleCreatorTest.java index 63627fd5556..082fe1de06a 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/RuleCreatorTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/RuleCreatorTest.java @@ -289,7 +289,7 @@ public class RuleCreatorTest { .setRuleKey(key) .setStatus(RuleStatus.REMOVED) .setName("Old name") - .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("Old description")) + .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "Old description")) .setDescriptionFormat(Format.MARKDOWN) .setSeverity(Severity.INFO); dbTester.rules().insert(rule.getDefinition()); @@ -329,7 +329,7 @@ public class RuleCreatorTest { .setRuleKey(key) .setStatus(RuleStatus.REMOVED) .setName("Old name") - .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("Old description")) + .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "Old description")) .setSeverity(Severity.INFO); dbTester.rules().insert(rule.getDefinition()); dbTester.rules().insertRuleParam(rule.getDefinition(), param -> param.setDefaultValue("a.*")); diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/RuleUpdaterTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/RuleUpdaterTest.java index 0c2fbae7dc7..8cce0607d88 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/RuleUpdaterTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/RuleUpdaterTest.java @@ -35,6 +35,7 @@ import org.sonar.api.rule.Severity; import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.api.server.debt.internal.DefaultDebtRemediationFunction; import org.sonar.api.utils.System2; +import org.sonar.core.util.UuidFactoryFast; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.qualityprofile.ActiveRuleDto; @@ -58,6 +59,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.sonar.api.rule.Severity.CRITICAL; import static org.sonar.db.rule.RuleDescriptionSectionDto.createDefaultRuleDescriptionSection; +import static org.sonar.db.rule.RuleTesting.newCustomRule; import static org.sonar.db.rule.RuleTesting.newRule; import static org.sonar.server.rule.RuleUpdate.createForCustomRule; import static org.sonar.server.rule.RuleUpdate.createForPluginRule; @@ -68,7 +70,6 @@ public class RuleUpdaterTest { private final System2 system2 = new TestSystem2().setNow(Instant.now().toEpochMilli()); - @Rule public UserSessionRule userSessionRule = UserSessionRule.standalone(); @@ -82,7 +83,8 @@ public class RuleUpdaterTest { private final RuleIndexer ruleIndexer = new RuleIndexer(es.client(), db.getDbClient()); private final DbSession dbSession = db.getSession(); - private final RuleUpdater underTest = new RuleUpdater(db.getDbClient(), ruleIndexer, system2); + private final UuidFactoryFast uuidFactory = UuidFactoryFast.getInstance(); + private final RuleUpdater underTest = new RuleUpdater(db.getDbClient(), ruleIndexer, uuidFactory, system2); @Test public void do_not_update_rule_with_removed_status() { @@ -340,9 +342,9 @@ public class RuleUpdaterTest { db.rules().insertRuleParam(templateRule.getDefinition(), param -> param.setName("format").setType("STRING").setDescription("Format")); // Create custom rule - RuleDefinitionDto customRule = RuleTesting.newCustomRule(templateRule) + RuleDefinitionDto customRule = newCustomRule(templateRule) .setName("Old name") - .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("Old description")) + .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "Old description")) .setSeverity(Severity.MINOR) .setStatus(RuleStatus.BETA) .getDefinition(); @@ -388,12 +390,11 @@ public class RuleUpdaterTest { db.rules().insertRuleParam(templateRule.getDefinition(), param -> param.setName("regex").setType("STRING").setDescription("Reg ex").setDefaultValue(null)); // Create custom rule - RuleDefinitionDto customRule = RuleTesting.newCustomRule(templateRule) + RuleDefinitionDto customRule = newCustomRule(templateRule.getDefinition()) .setName("Old name") - .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("Old description")) + .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "Old description")) .setSeverity(Severity.MINOR) - .setStatus(RuleStatus.BETA) - .getDefinition(); + .setStatus(RuleStatus.BETA); db.rules().insert(customRule); db.rules().insertRuleParam(customRule, param -> param.setName("regex").setType("STRING").setDescription("Reg ex").setDefaultValue(null)); @@ -425,7 +426,7 @@ public class RuleUpdaterTest { db.rules().insertRuleParam(templateRuleDefinition, param -> param.setName("message").setType("STRING").setDescription("message")); // Create custom rule - RuleDefinitionDto customRule = RuleTesting.newCustomRule(templateRule) + RuleDefinitionDto customRule = newCustomRule(templateRule) .setSeverity(Severity.MAJOR) .setLanguage("xoo") .getDefinition(); @@ -490,7 +491,7 @@ public class RuleUpdaterTest { db.rules().insert(templateRule); // Create custom rule - RuleDefinitionDto customRule = RuleTesting.newCustomRule(templateRule); + RuleDefinitionDto customRule = newCustomRule(templateRule); db.rules().insert(customRule); dbSession.commit(); @@ -514,7 +515,7 @@ public class RuleUpdaterTest { db.rules().insert(templateRule.getDefinition()); // Create custom rule - RuleDto customRule = RuleTesting.newCustomRule(templateRule); + RuleDto customRule = newCustomRule(templateRule); db.rules().insert(customRule.getDefinition()); dbSession.commit(); diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/CreateActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/CreateActionTest.java index dca7895a189..9c2f4bcbd70 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/CreateActionTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/CreateActionTest.java @@ -142,7 +142,7 @@ public class CreateActionTest { .setRuleKey("MY_CUSTOM") .setStatus(RuleStatus.REMOVED) .setName("My custom rule") - .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("Description")) + .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "Description")) .setDescriptionFormat(RuleDto.Format.MARKDOWN) .setSeverity(Severity.MAJOR); db.rules().insert(customRule); diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/SearchActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/SearchActionTest.java index 3b6db659ba2..3482799dea2 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/SearchActionTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/SearchActionTest.java @@ -34,6 +34,8 @@ import org.sonar.api.rules.RuleType; import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; +import org.sonar.core.util.UuidFactory; +import org.sonar.core.util.UuidFactoryFast; import org.sonar.core.util.stream.MoreCollectors; import org.sonar.db.DbTester; import org.sonar.db.qualityprofile.ActiveRuleParamDto; @@ -116,6 +118,7 @@ public class SearchActionTest { private final QProfileRules qProfileRules = new QProfileRulesImpl(db.getDbClient(), ruleActivator, ruleIndex, activeRuleIndexer, qualityProfileChangeEventService); private final WsActionTester ws = new WsActionTester(underTest); + private final UuidFactory uuidFactory = UuidFactoryFast.getInstance(); @Before public void before() { @@ -234,7 +237,7 @@ public class SearchActionTest { @Test public void filter_by_rule_description() { RuleDefinitionDto rule1 = db.rules() - .insert(r1 -> r1.addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("This is the <bold>best</bold> rule now&for<b>ever</b>"))); + .insert(r1 -> r1.addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "This is the <bold>best</bold> rule now&for<b>ever</b>"))); RuleDefinitionDto rule2 = db.rules().insert(r1 -> r1.setName("Some other stuff")); indexRules(); @@ -246,9 +249,9 @@ public class SearchActionTest { @Test public void filter_by_rule_name_or_descriptions_requires_all_words_to_match_anywhere() { RuleDefinitionDto rule1 = db.rules().insert(r1 -> r1.setName("Best rule ever") - .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("This is a good rule"))); + .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "This is a good rule"))); RuleDefinitionDto rule2 = db.rules().insert(r1 -> r1.setName("Another thing") - .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("Another thing"))); + .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "Another thing"))); indexRules(); verify(r -> r.setParam("q", "Best good"), rule1); @@ -931,8 +934,7 @@ public class SearchActionTest { private void verify(Consumer<TestRequest> requestPopulator, RuleDefinitionDto... expectedRules) { TestRequest request = ws.newRequest(); requestPopulator.accept(request); - Rules.SearchResponse response = request - .executeProtobuf(Rules.SearchResponse.class); + Rules.SearchResponse response = request.executeProtobuf(Rules.SearchResponse.class); assertThat(response.getP()).isOne(); RuleKey[] expectedRuleKeys = stream(expectedRules).map(RuleDefinitionDto::getKey).collect(MoreCollectors.toList()).toArray(new RuleKey[0]); diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/ShowActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/ShowActionTest.java index 41ba8fab653..77e97e592b5 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/ShowActionTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/ShowActionTest.java @@ -27,6 +27,8 @@ import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.Severity; import org.sonar.api.rules.RuleType; import org.sonar.api.server.ws.WebService; +import org.sonar.core.util.UuidFactory; +import org.sonar.core.util.UuidFactoryFast; import org.sonar.db.DbTester; import org.sonar.db.qualityprofile.ActiveRuleDto; import org.sonar.db.qualityprofile.ActiveRuleParamDto; @@ -70,6 +72,7 @@ public class ShowActionTest { @org.junit.Rule public DbTester db = DbTester.create(); + private final UuidFactory uuidFactory = UuidFactoryFast.getInstance(); private final MacroInterpreter macroInterpreter = mock(MacroInterpreter.class); private final Languages languages = new Languages(newLanguage("xoo", "Xoo")); private final WsActionTester ws = new WsActionTester( @@ -285,7 +288,7 @@ public class ShowActionTest { db.rules().insert(templateRule.getDefinition()); // Custom rule RuleDefinitionDto customRule = newCustomRule(templateRule.getDefinition()) - .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("<div>line1\nline2</div>")) + .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "<div>line1\nline2</div>")) .setDescriptionFormat(MARKDOWN); db.rules().insert(customRule); doReturn("<div>line1<br/>line2</div>").when(macroInterpreter).interpret("<div>line1\nline2</div>"); @@ -343,7 +346,7 @@ public class ShowActionTest { .setIsExternal(true) .setIsAdHoc(true) .setName("predefined name") - .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("<div>predefined desc</div>")) + .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "<div>predefined desc</div>")) .setSeverity(Severity.BLOCKER) .setType(RuleType.VULNERABILITY)); RuleMetadataDto metadata = db.rules().insertOrUpdateMetadata(externalRule, m -> m diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/UpdateActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/UpdateActionTest.java index 8be2f583b11..671f4e7a5d2 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/UpdateActionTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/UpdateActionTest.java @@ -26,9 +26,11 @@ import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; import org.sonar.api.utils.System2; +import org.sonar.core.util.UuidFactoryFast; import org.sonar.db.DbClient; import org.sonar.db.DbTester; import org.sonar.db.rule.RuleDefinitionDto; +import org.sonar.db.rule.RuleDescriptionSectionDto; import org.sonar.db.rule.RuleMetadataDto; import org.sonar.db.user.UserDto; import org.sonar.server.es.EsClient; @@ -68,7 +70,6 @@ public class UpdateActionTest { private static final long PAST = 10000L; - @Rule public DbTester db = DbTester.create(); @@ -84,7 +85,9 @@ public class UpdateActionTest { private Languages languages = new Languages(); private RuleMapper mapper = new RuleMapper(languages, createMacroInterpreter()); private RuleIndexer ruleIndexer = new RuleIndexer(esClient, dbClient); - private RuleUpdater ruleUpdater = new RuleUpdater(dbClient, ruleIndexer, System2.INSTANCE); + private UuidFactoryFast uuidFactory = UuidFactoryFast.getInstance(); + + private RuleUpdater ruleUpdater = new RuleUpdater(dbClient, ruleIndexer, uuidFactory, System2.INSTANCE); private WsAction underTest = new UpdateAction(dbClient, ruleUpdater, mapper, userSession, new RuleWsSupport(db.getDbClient(), userSession)); private WsActionTester ws = new WsActionTester(underTest); @@ -108,7 +111,7 @@ public class UpdateActionTest { RuleDefinitionDto customRule = db.rules().insert( r -> r.setRuleKey(RuleKey.of("java", "MY_CUSTOM")), r -> r.setName("Old custom"), - r -> r.addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("Old description")), + r -> r.addOrReplaceRuleDescriptionSectionDto(createRuleDescriptionSectionDto()), r -> r.setSeverity(Severity.MINOR), r -> r.setStatus(RuleStatus.BETA), r -> r.setTemplateUuid(templateRule.getUuid()), @@ -244,7 +247,7 @@ public class UpdateActionTest { RuleDefinitionDto customRule = db.rules().insert( r -> r.setRuleKey(RuleKey.of("java", "MY_CUSTOM")), r -> r.setName("Old custom"), - r -> r.addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("Old description")), + r -> r.addOrReplaceRuleDescriptionSectionDto(createRuleDescriptionSectionDto()), r -> r.setTemplateUuid(templateRule.getUuid()), r -> r.setCreatedAt(PAST), r -> r.setUpdatedAt(PAST)); @@ -300,6 +303,10 @@ public class UpdateActionTest { .addPermission(ADMINISTER_QUALITY_PROFILES); } + private RuleDescriptionSectionDto createRuleDescriptionSectionDto() { + return createDefaultRuleDescriptionSection(uuidFactory.create(), "Old description"); + } + private static MacroInterpreter createMacroInterpreter() { MacroInterpreter macroInterpreter = mock(MacroInterpreter.class); doAnswer(returnsFirstArg()).when(macroInterpreter).interpret(anyString()); |