Browse Source

SONAR-20260 clean code fields are not populated for security hotspot

tags/10.2.0.77647
Léo Geoffroy 9 months ago
parent
commit
eb9a74051d
17 changed files with 123 additions and 50 deletions
  1. 4
    2
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/AdHocRuleCreator.java
  2. 22
    19
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/NewAdHocRule.java
  3. 1
    0
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/Rule.java
  4. 4
    2
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/pushevent/PushEventFactory.java
  5. 22
    0
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/NewAdHocRuleTest.java
  6. 1
    0
      server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueDto.java
  7. 2
    1
      server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java
  8. 1
    0
      server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleForIndexingDto.java
  9. 0
    2
      server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DbVersion102.java
  10. 4
    2
      server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/PopulateCleanCodeAttributeColumnInRules.java
  11. 25
    1
      server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v102/PopulateCleanCodeAttributeColumnInRulesTest.java
  12. 9
    8
      server/sonar-webserver-core/src/main/java/org/sonar/server/rule/registration/NewRuleCreator.java
  13. 3
    0
      server/sonar-webserver-core/src/main/java/org/sonar/server/rule/registration/StartupRuleUpdater.java
  14. 13
    4
      server/sonar-webserver-core/src/test/java/org/sonar/server/rule/registration/NewRuleCreatorTest.java
  15. 2
    0
      server/sonar-webserver-core/src/test/java/org/sonar/server/rule/registration/RulesRegistrantIT.java
  16. 3
    5
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchResponseFormat.java
  17. 7
    4
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/RuleMapper.java

+ 4
- 2
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/AdHocRuleCreator.java View File

@@ -26,6 +26,7 @@ import java.util.Optional;
import java.util.stream.Collectors;
import org.sonar.api.issue.impact.Severity;
import org.sonar.api.issue.impact.SoftwareQuality;
import org.sonar.api.rules.CleanCodeAttribute;
import org.sonar.api.rules.RuleType;
import org.sonar.api.utils.System2;
import org.sonar.core.util.UuidFactory;
@@ -89,8 +90,9 @@ public class AdHocRuleCreator {
}
}

if (!Objects.equals(ruleDtoToUpdate.getCleanCodeAttribute(), adHoc.getCleanCodeAttribute())) {
ruleDtoToUpdate.setCleanCodeAttribute(adHoc.getCleanCodeAttribute());
CleanCodeAttribute cleanCodeAttribute = adHoc.getCleanCodeAttribute();
if (!Objects.equals(ruleDtoToUpdate.getCleanCodeAttribute(), cleanCodeAttribute)) {
ruleDtoToUpdate.setCleanCodeAttribute(cleanCodeAttribute);
changed = true;
}


+ 22
- 19
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/NewAdHocRule.java View File

@@ -51,8 +51,7 @@ public class NewAdHocRule {
private final String severity;
private final RuleType ruleType;
private final boolean hasDetails;

private final CleanCodeAttribute cleanCodeAttribute;
private CleanCodeAttribute cleanCodeAttribute = null;

private final Map<SoftwareQuality, Severity> defaultImpacts = new EnumMap<>(SoftwareQuality.class);

@@ -70,11 +69,29 @@ public class NewAdHocRule {
this.name = ruleFromScannerReport.getName();
this.description = trimToNull(ruleFromScannerReport.getDescription());
this.hasDetails = true;
this.cleanCodeAttribute = mapCleanCodeAttribute(trimToNull(ruleFromScannerReport.getCleanCodeAttribute()));
this.ruleType = determineType(ruleFromScannerReport);
this.severity = determineSeverity(ruleFromScannerReport);
this.defaultImpacts.putAll(determineImpacts(ruleFromScannerReport));
if (!ScannerReport.IssueType.SECURITY_HOTSPOT.equals(ruleFromScannerReport.getType())) {
this.cleanCodeAttribute = mapCleanCodeAttribute(trimToNull(ruleFromScannerReport.getCleanCodeAttribute()));
this.defaultImpacts.putAll(determineImpacts(ruleFromScannerReport));
}
}

public NewAdHocRule(ScannerReport.ExternalIssue fromIssue) {
Preconditions.checkArgument(isNotBlank(fromIssue.getEngineId()), "'engine id' not expected to be null for an ad hoc rule");
Preconditions.checkArgument(isNotBlank(fromIssue.getRuleId()), "'rule id' not expected to be null for an ad hoc rule");
this.key = RuleKey.of(RuleKey.EXTERNAL_RULE_REPO_PREFIX + fromIssue.getEngineId(), fromIssue.getRuleId());
this.engineId = fromIssue.getEngineId();
this.ruleId = fromIssue.getRuleId();
this.name = null;
this.description = null;
this.severity = null;
this.ruleType = null;
this.hasDetails = false;
if (!ScannerReport.IssueType.SECURITY_HOTSPOT.equals(fromIssue.getType())) {
this.cleanCodeAttribute = CleanCodeAttribute.defaultCleanCodeAttribute();
this.defaultImpacts.put(SoftwareQuality.MAINTAINABILITY, Severity.MEDIUM);
}
}

private Map<SoftwareQuality, Severity> determineImpacts(ScannerReport.AdHocRule ruleFromScannerReport) {
@@ -131,21 +148,6 @@ public class NewAdHocRule {
return SoftwareQuality.valueOf(softwareQuality);
}

public NewAdHocRule(ScannerReport.ExternalIssue fromIssue) {
Preconditions.checkArgument(isNotBlank(fromIssue.getEngineId()), "'engine id' not expected to be null for an ad hoc rule");
Preconditions.checkArgument(isNotBlank(fromIssue.getRuleId()), "'rule id' not expected to be null for an ad hoc rule");
this.key = RuleKey.of(RuleKey.EXTERNAL_RULE_REPO_PREFIX + fromIssue.getEngineId(), fromIssue.getRuleId());
this.engineId = fromIssue.getEngineId();
this.ruleId = fromIssue.getRuleId();
this.name = null;
this.description = null;
this.severity = null;
this.ruleType = null;
this.hasDetails = false;
this.cleanCodeAttribute = CleanCodeAttribute.defaultCleanCodeAttribute();
this.defaultImpacts.put(SoftwareQuality.MAINTAINABILITY, Severity.MEDIUM);
}

public RuleKey getKey() {
return key;
}
@@ -182,6 +184,7 @@ public class NewAdHocRule {
return hasDetails;
}

@CheckForNull
public CleanCodeAttribute getCleanCodeAttribute() {
return cleanCodeAttribute;
}

+ 1
- 0
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/Rule.java View File

@@ -71,5 +71,6 @@ public interface Rule {

Map<SoftwareQuality, Severity> getDefaultImpacts();

@CheckForNull
CleanCodeAttribute cleanCodeAttribute();
}

+ 4
- 2
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/pushevent/PushEventFactory.java View File

@@ -30,6 +30,7 @@ import org.jetbrains.annotations.NotNull;
import org.sonar.api.ce.ComputeEngineSide;
import org.sonar.api.issue.impact.Severity;
import org.sonar.api.issue.impact.SoftwareQuality;
import org.sonar.api.rules.CleanCodeAttribute;
import org.sonar.api.rules.RuleType;
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder;
import org.sonar.ce.task.projectanalysis.component.Component;
@@ -146,8 +147,9 @@ public class PushEventFactory {
issue.getRuleDescriptionContextKey().ifPresent(event::setRuleDescriptionContextKey);

Rule rule = ruleRepository.getByKey(issue.getRuleKey());
event.setCleanCodeAttribute(rule.cleanCodeAttribute().name());
event.setCleanCodeAttributeCategory(rule.cleanCodeAttribute().getAttributeCategory().name());
CleanCodeAttribute cleanCodeAttribute = requireNonNull(rule.cleanCodeAttribute());
event.setCleanCodeAttribute(cleanCodeAttribute.name());
event.setCleanCodeAttributeCategory(cleanCodeAttribute.getAttributeCategory().name());
event.setImpacts(computeEffectiveImpacts(rule.getDefaultImpacts(), issue.impacts()));
return event;
}

+ 22
- 0
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/NewAdHocRuleTest.java View File

@@ -119,4 +119,26 @@ public class NewAdHocRuleTest {
.hasMessage("'issue type' not expected to be null for an ad hoc rule, or impacts should be provided instead");
}

@Test
public void constructor_whenRuleHotspot_shouldNotPopulateImpactsNorAttribute() {
NewAdHocRule adHocRule1 = new NewAdHocRule(ScannerReport.ExternalIssue.newBuilder()
.setEngineId("eslint")
.setType(ScannerReport.IssueType.SECURITY_HOTSPOT)
.setSeverity(Constants.Severity.BLOCKER)
.setRuleId("no-cond-assign").build());
assertThat(adHocRule1.getDefaultImpacts()).isEmpty();
assertThat(adHocRule1.getCleanCodeAttribute()).isNull();
}

@Test
public void constructor_whenIssueHotspot_shouldNotPopulateImpactsNorAttribute() {
NewAdHocRule adHocRule1 = new NewAdHocRule(ScannerReport.ExternalIssue.newBuilder()
.setType(ScannerReport.IssueType.SECURITY_HOTSPOT)
.setSeverity(Constants.Severity.BLOCKER)
.setEngineId("eslint")
.setRuleId("no-cond-assign").build());
assertThat(adHocRule1.getDefaultImpacts()).isEmpty();
assertThat(adHocRule1.getCleanCodeAttribute()).isNull();
}

}

+ 1
- 0
server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueDto.java View File

@@ -771,6 +771,7 @@ public final class IssueDto implements Serializable {
return this;
}

@CheckForNull
public CleanCodeAttribute getCleanCodeAttribute() {
return cleanCodeAttribute;
}

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

@@ -431,11 +431,12 @@ public class RuleDto {
return this;
}

@CheckForNull
public CleanCodeAttribute getCleanCodeAttribute() {
return cleanCodeAttribute;
}

public RuleDto setCleanCodeAttribute(CleanCodeAttribute cleanCodeAttribute) {
public RuleDto setCleanCodeAttribute(@Nullable CleanCodeAttribute cleanCodeAttribute) {
this.cleanCodeAttribute = cleanCodeAttribute;
return this;
}

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

@@ -216,6 +216,7 @@ public class RuleForIndexingDto {
this.type = type;
}

@CheckForNull
public String getCleanCodeAttributeCategory() {
return cleanCodeAttributeCategory;
}

+ 0
- 2
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DbVersion102.java View File

@@ -86,8 +86,6 @@ public class DbVersion102 implements DbVersion {
.add(10_2_032, "Increase size of 'ce_queue.main_is_last_key' from 55 to 80 characters", IncreaseMainIsLastKeyInCeActivity.class)
.add(10_2_033, "Add column 'clean_code_attribute' in 'rules' table", AddCleanCodeAttributeInRules.class)
.add(10_2_034, "Populate 'clean_code_attribute' column in 'rules' table", PopulateCleanCodeAttributeColumnInRules.class)
//TODO SONAR-20073
//.add(10_2_035, "Make 'clean_code_attribute' column not nullable in 'rules' table", MakeCleanCodeAttributeColumnNotNullableInRules.class);

.add(10_2_036, "Create 'rules_default_impacts' table", CreateRulesDefaultImpactsTable.class)
.add(10_2_037, "Create unique constraint index on 'rules_default_impacts' table", CreateUniqueConstraintOnRulesDefaultImpacts.class)

+ 4
- 2
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/PopulateCleanCodeAttributeColumnInRules.java View File

@@ -25,13 +25,15 @@ import org.sonar.db.Database;
import org.sonar.server.platform.db.migration.step.DataChange;
import org.sonar.server.platform.db.migration.step.MassUpdate;

import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT;

public class PopulateCleanCodeAttributeColumnInRules extends DataChange {

private static final String SELECT_QUERY = """
SELECT uuid, clean_code_attribute
FROM rules
WHERE clean_code_attribute is null
""";
WHERE clean_code_attribute is null and (rule_type <> %1$s or ad_hoc_type <> %1$s)
""".formatted(SECURITY_HOTSPOT.getDbConstant());

private static final String UPDATE_QUERY = """
UPDATE rules

+ 25
- 1
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v102/PopulateCleanCodeAttributeColumnInRulesTest.java View File

@@ -24,6 +24,7 @@ import javax.annotation.Nullable;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.rules.CleanCodeAttribute;
import org.sonar.api.rules.RuleType;
import org.sonar.db.CoreDbTester;

import static org.assertj.core.api.Assertions.assertThat;
@@ -68,7 +69,24 @@ public class PopulateCleanCodeAttributeColumnInRulesTest {
.extracting(stringObjectMap -> stringObjectMap.get("CLEAN_CODE_ATTRIBUTE")).containsExactly(CleanCodeAttribute.FOCUSED.name());
}

private void insertRule(String uuid, @Nullable CleanCodeAttribute cleanCodeAttribute) {
@Test
public void execute_whenRuleIsHotspot_shouldNotUpdate() throws SQLException {
insertRule("1", RuleType.SECURITY_HOTSPOT, null, null);
underTest.execute();
assertThat(db.select("select UUID, CLEAN_CODE_ATTRIBUTE from rules"))
.extracting(stringObjectMap -> stringObjectMap.get("CLEAN_CODE_ATTRIBUTE")).containsOnlyNulls();
}

@Test
public void execute_whenAdhocRuleIsHotspot_shouldNotUpdate() throws SQLException {
insertRule("1", null, RuleType.SECURITY_HOTSPOT, null);
underTest.execute();
assertThat(db.select("select UUID, CLEAN_CODE_ATTRIBUTE from rules"))
.extracting(stringObjectMap -> stringObjectMap.get("CLEAN_CODE_ATTRIBUTE")).containsOnlyNulls();
}


private void insertRule(String uuid, @Nullable RuleType ruleType, @Nullable RuleType adhocRuleType, @Nullable CleanCodeAttribute cleanCodeAttribute) {
db.executeInsert(TABLE_NAME,
"UUID", uuid,
"PLUGIN_RULE_KEY", "key",
@@ -76,7 +94,13 @@ public class PopulateCleanCodeAttributeColumnInRulesTest {
"SCOPE", "1",
"CLEAN_CODE_ATTRIBUTE", cleanCodeAttribute != null ? cleanCodeAttribute.name() : null,
"IS_TEMPLATE", false,
"RULE_TYPE", ruleType != null ? ruleType.getDbConstant() : null,
"AD_HOC_TYPE", adhocRuleType != null ? adhocRuleType.getDbConstant() : null,
"IS_AD_HOC", false,
"IS_EXTERNAL", false);
}

private void insertRule(String uuid, @Nullable CleanCodeAttribute cleanCodeAttribute) {
insertRule(uuid, RuleType.CODE_SMELL, null, cleanCodeAttribute);
}
}

+ 9
- 8
server/sonar-webserver-core/src/main/java/org/sonar/server/rule/registration/NewRuleCreator.java View File

@@ -51,12 +51,6 @@ public class NewRuleCreator {

RuleDto createNewRule(RulesRegistrationContext context, RulesDefinition.Rule ruleDef, DbSession session) {
RuleDto newRule = createRuleWithSimpleFields(ruleDef, uuidFactory.create(), system2.now());

newRule.replaceAllDefaultImpacts(ruleDef.defaultImpacts().entrySet()
.stream()
.map(e -> new ImpactDto().setUuid(uuidFactory.create()).setSoftwareQuality(e.getKey()).setSeverity(e.getValue()))
.collect(Collectors.toSet()));

ruleDescriptionSectionsGeneratorResolver.generateFor(ruleDef).forEach(newRule::addRuleDescriptionSectionDto);

dbClient.ruleDao().insert(session, newRule);
@@ -65,7 +59,6 @@ public class NewRuleCreator {
}

RuleDto createRuleWithSimpleFields(RulesDefinition.Rule ruleDef, String uuid, long now) {
CleanCodeAttribute cleanCodeAttribute = ruleDef.cleanCodeAttribute();
RuleDto ruleDto = new RuleDto()
.setUuid(uuid)
.setRuleKey(RuleKey.of(ruleDef.repository().key(), ruleDef.key()))
@@ -85,9 +78,17 @@ public class NewRuleCreator {
.setIsAdHoc(false)
.setCreatedAt(now)
.setUpdatedAt(now)
.setCleanCodeAttribute(cleanCodeAttribute != null ? cleanCodeAttribute : CleanCodeAttribute.defaultCleanCodeAttribute())
.setEducationPrinciples(ruleDef.educationPrincipleKeys());

if (!RuleType.SECURITY_HOTSPOT.equals(ruleDef.type())) {
CleanCodeAttribute cleanCodeAttribute = ruleDef.cleanCodeAttribute();
ruleDto.setCleanCodeAttribute(cleanCodeAttribute != null ? cleanCodeAttribute : CleanCodeAttribute.defaultCleanCodeAttribute());
ruleDto.replaceAllDefaultImpacts(ruleDef.defaultImpacts().entrySet()
.stream()
.map(e -> new ImpactDto().setUuid(uuidFactory.create()).setSoftwareQuality(e.getKey()).setSeverity(e.getValue()))
.collect(Collectors.toSet()));
}

if (isNotEmpty(ruleDef.htmlDescription())) {
ruleDto.setDescriptionFormat(RuleDto.Format.HTML);
} else if (isNotEmpty(ruleDef.markdownDescription())) {

+ 3
- 0
server/sonar-webserver-core/src/main/java/org/sonar/server/rule/registration/StartupRuleUpdater.java View File

@@ -166,6 +166,9 @@ public class StartupRuleUpdater {
}

private static boolean mergeCleanCodeAttribute(RulesDefinition.Rule def, RuleDto dto) {
if (dto.getEnumType() == RuleType.SECURITY_HOTSPOT) {
return false;
}
boolean changed = false;
CleanCodeAttribute defCleanCodeAttribute = def.cleanCodeAttribute();
if (!Objects.equals(dto.getCleanCodeAttribute(), defCleanCodeAttribute) && (defCleanCodeAttribute != null)) {

+ 13
- 4
server/sonar-webserver-core/src/test/java/org/sonar/server/rule/registration/NewRuleCreatorTest.java View File

@@ -69,13 +69,22 @@ public class NewRuleCreatorTest {

@Test
public void from_whenRuleDefinitionDoesHaveCleanCodeAttribute_shouldReturnThisAttribute() {
RulesDefinition.Rule ruleDef = getDefaultRule(CleanCodeAttribute.TESTED);
RulesDefinition.Rule ruleDef = getDefaultRule(CleanCodeAttribute.TESTED, RuleType.CODE_SMELL);

RuleDto newRuleDto = underTest.createNewRule(context, ruleDef, mock());

assertThat(newRuleDto.getCleanCodeAttribute()).isEqualTo(CleanCodeAttribute.TESTED);
}

@Test
public void createNewRule_whenRuleDefinitionDoesHaveCleanCodeAttributeAndIsSecurityHotspot_shouldReturnNull() {
RulesDefinition.Rule ruleDef = getDefaultRule(CleanCodeAttribute.TESTED, RuleType.SECURITY_HOTSPOT);

RuleDto newRuleDto = underTest.createNewRule(context, ruleDef, mock());
assertThat(newRuleDto.getCleanCodeAttribute()).isNull();
assertThat(newRuleDto.getDefaultImpacts()).isEmpty();
}

@Test
public void createNewRule_whenImpactDefined_shouldReturnThisImpact() {
RulesDefinition.Rule ruleDef = getDefaultRule();
@@ -89,14 +98,14 @@ public class NewRuleCreatorTest {
.containsOnly(tuple(SoftwareQuality.RELIABILITY, Severity.LOW));
}

private static RulesDefinition.Rule getDefaultRule(@Nullable CleanCodeAttribute attribute) {
private static RulesDefinition.Rule getDefaultRule(@Nullable CleanCodeAttribute attribute, RuleType ruleType) {
RulesDefinition.Rule ruleDef = mock(RulesDefinition.Rule.class);
RulesDefinition.Repository repository = mock(RulesDefinition.Repository.class);
when(ruleDef.repository()).thenReturn(repository);

when(ruleDef.key()).thenReturn("key");
when(repository.key()).thenReturn("repoKey");
when(ruleDef.type()).thenReturn(RuleType.CODE_SMELL);
when(ruleDef.type()).thenReturn(ruleType);
when(ruleDef.scope()).thenReturn(RuleScope.TEST);
when(ruleDef.cleanCodeAttribute()).thenReturn(attribute);
when(ruleDef.severity()).thenReturn(MAJOR);
@@ -105,6 +114,6 @@ public class NewRuleCreatorTest {
}

private static RulesDefinition.Rule getDefaultRule() {
return getDefaultRule(null);
return getDefaultRule(null, RuleType.CODE_SMELL);
}
}

+ 2
- 0
server/sonar-webserver-core/src/test/java/org/sonar/server/rule/registration/RulesRegistrantIT.java View File

@@ -227,6 +227,8 @@ public class RulesRegistrantIT {
assertThat(hotspotRule.getUpdatedAt()).isEqualTo(RulesRegistrantIT.DATE1.getTime());
assertThat(hotspotRule.getType()).isEqualTo(RuleType.SECURITY_HOTSPOT.getDbConstant());
assertThat(hotspotRule.getSecurityStandards()).containsExactly("cwe:1", "cwe:123", "cwe:863", "owaspTop10-2021:a1", "owaspTop10-2021:a3");
assertThat(hotspotRule.getDefaultImpacts()).isEmpty();
assertThat(hotspotRule.getCleanCodeAttribute()).isNull();
}

@Test

+ 3
- 5
server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchResponseFormat.java View File

@@ -175,11 +175,9 @@ public class SearchResponseFormat {
issueBuilder.setType(Common.RuleType.forNumber(dto.getType()));

CleanCodeAttribute cleanCodeAttribute = dto.getCleanCodeAttribute();
String cleanCodeAttributeString = cleanCodeAttribute != null ? cleanCodeAttribute.name() : null;
String cleanCodeAttributeCategoryString = cleanCodeAttribute != null ? cleanCodeAttribute.getAttributeCategory().name() : null;
if (cleanCodeAttributeString != null) {
issueBuilder.setCleanCodeAttribute(Common.CleanCodeAttribute.valueOf(cleanCodeAttributeString));
issueBuilder.setCleanCodeAttributeCategory(Common.CleanCodeAttributeCategory.valueOf(cleanCodeAttributeCategoryString));
if (cleanCodeAttribute != null) {
issueBuilder.setCleanCodeAttribute(Common.CleanCodeAttribute.valueOf(cleanCodeAttribute.name()));
issueBuilder.setCleanCodeAttributeCategory(Common.CleanCodeAttributeCategory.valueOf(cleanCodeAttribute.getAttributeCategory().name()));
}
issueBuilder.addAllImpacts(dto.getEffectiveImpacts().entrySet()
.stream()

+ 7
- 4
server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/RuleMapper.java View File

@@ -32,6 +32,7 @@ import javax.annotation.Nullable;
import org.sonar.api.resources.Language;
import org.sonar.api.resources.Languages;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rules.CleanCodeAttribute;
import org.sonar.api.rules.RuleType;
import org.sonar.api.server.debt.DebtRemediationFunction;
import org.sonar.api.server.debt.internal.DefaultDebtRemediationFunction;
@@ -223,9 +224,10 @@ public class RuleMapper {
}

private static void setCleanCodeAttributes(Rules.Rule.Builder ruleResponse, RuleDto ruleDto, Set<String> fieldsToReturn) {
if (shouldReturnField(fieldsToReturn, FIELD_CLEAN_CODE_ATTRIBUTE) && ruleDto.getType() != RuleType.SECURITY_HOTSPOT.getDbConstant()) {
ruleResponse.setCleanCodeAttribute(Common.CleanCodeAttribute.valueOf(ruleDto.getCleanCodeAttribute().name()));
ruleResponse.setCleanCodeAttributeCategory(Common.CleanCodeAttributeCategory.valueOf(ruleDto.getCleanCodeAttribute().getAttributeCategory().name()));
CleanCodeAttribute cleanCodeAttribute = ruleDto.getCleanCodeAttribute();
if (shouldReturnField(fieldsToReturn, FIELD_CLEAN_CODE_ATTRIBUTE) && cleanCodeAttribute != null) {
ruleResponse.setCleanCodeAttribute(Common.CleanCodeAttribute.valueOf(cleanCodeAttribute.name()));
ruleResponse.setCleanCodeAttributeCategory(Common.CleanCodeAttributeCategory.valueOf(cleanCodeAttribute.getAttributeCategory().name()));
}
}

@@ -262,7 +264,7 @@ public class RuleMapper {
private static void setGapDescription(Rules.Rule.Builder ruleResponse, RuleDto ruleDto, Set<String> fieldsToReturn) {
String gapDescription = ruleDto.getGapDescription();
if (shouldReturnField(fieldsToReturn, FIELD_GAP_DESCRIPTION)
&& gapDescription != null) {
&& gapDescription != null) {
ruleResponse.setGapDescription(gapDescription);
}
}
@@ -389,6 +391,7 @@ public class RuleMapper {

/**
* This was done to preserve backward compatibility with SonarLint until they stop using htmlDesc field in api/rules/[show|search] endpoints, see SONAR-16635
*
* @deprecated the method should be removed once SonarLint supports rules.descriptionSections fields, I.E in 10.x and DB is cleaned up of non-necessary default sections.
*/
@Deprecated(since = "9.6", forRemoval = true)

Loading…
Cancel
Save