diff options
author | Léo Geoffroy <leo.geoffroy@sonarsource.com> | 2024-11-13 09:09:59 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2024-11-13 20:05:48 +0000 |
commit | 6fc76e284875910d4682ee09323917c604da833f (patch) | |
tree | 0ead594ba5858a6a315319b9a815a6d62b54f9f7 /sonar-scanner-engine/src/main | |
parent | c056a2d19f6211db7a153d5056db51b2452f738c (diff) | |
download | sonarqube-6fc76e284875910d4682ee09323917c604da833f.tar.gz sonarqube-6fc76e284875910d4682ee09323917c604da833f.zip |
SONAR-23270 Handle type and severity in new generic import format
Diffstat (limited to 'sonar-scanner-engine/src/main')
3 files changed, 44 insertions, 23 deletions
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/externalissue/ExternalIssueImporter.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/externalissue/ExternalIssueImporter.java index b8dba3ffdb8..831c6b4b64f 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/externalissue/ExternalIssueImporter.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/externalissue/ExternalIssueImporter.java @@ -39,12 +39,12 @@ import org.sonar.api.batch.sensor.rule.NewAdHocRule; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rules.CleanCodeAttribute; import org.sonar.api.rules.RuleType; -import org.sonar.api.server.rule.internal.ImpactMapper; import org.sonar.scanner.externalissue.ExternalIssueReport.Issue; import org.sonar.scanner.externalissue.ExternalIssueReport.Location; import org.sonar.scanner.externalissue.ExternalIssueReport.Rule; import static java.lang.String.format; +import static java.util.Optional.ofNullable; public class ExternalIssueImporter { private static final Logger LOG = LoggerFactory.getLogger(ExternalIssueImporter.class); @@ -102,25 +102,19 @@ public class ExternalIssueImporter { adHocRule.name(rule.name); adHocRule.description(rule.description); adHocRule.engineId(rule.engineId); - adHocRule.cleanCodeAttribute(CleanCodeAttribute.valueOf(rule.cleanCodeAttribute)); - adHocRule.severity(backmapSeverityFromImpact(rule)); - adHocRule.type(backmapTypeFromImpact(rule)); - for (ExternalIssueReport.Impact impact : rule.impacts) { - adHocRule.addDefaultImpact(SoftwareQuality.valueOf(impact.softwareQuality), - org.sonar.api.issue.impact.Severity.valueOf(impact.severity)); + ofNullable(rule.cleanCodeAttribute).ifPresent(cca -> adHocRule.cleanCodeAttribute(CleanCodeAttribute.valueOf(cca))); + ofNullable(rule.severity).ifPresent(s -> adHocRule.severity(Severity.valueOf(s))); + ofNullable(rule.type).ifPresent(t -> adHocRule.type(RuleType.valueOf(t))); + + if (rule.impacts != null) { + for (ExternalIssueReport.Impact impact : rule.impacts) { + adHocRule.addDefaultImpact(SoftwareQuality.valueOf(impact.softwareQuality), + org.sonar.api.issue.impact.Severity.valueOf(impact.severity)); + } } return adHocRule; } - private static RuleType backmapTypeFromImpact(Rule rule) { - return ImpactMapper.convertToRuleType(SoftwareQuality.valueOf(rule.impacts[0].softwareQuality)); - } - - private static Severity backmapSeverityFromImpact(Rule rule) { - org.sonar.api.issue.impact.Severity impactSeverity = org.sonar.api.issue.impact.Severity.valueOf(rule.impacts[0].severity); - return Severity.valueOf(ImpactMapper.convertToDeprecatedSeverity(impactSeverity)); - } - private boolean populateCommonValues(Issue issue, NewExternalIssue externalIssue) { if (issue.effortMinutes != null) { externalIssue.remediationEffortMinutes(Long.valueOf(issue.effortMinutes)); @@ -159,9 +153,10 @@ public class ExternalIssueImporter { private boolean importIssue(Issue issue, ExternalIssueReport.Rule rule) { NewExternalIssue externalIssue = context.newExternalIssue() .engineId(rule.engineId) - .ruleId(rule.id) - .severity(backmapSeverityFromImpact(rule)) - .type(backmapTypeFromImpact(rule)); + .ruleId(rule.id); + + ofNullable(rule.severity).ifPresent(s -> externalIssue.severity(Severity.valueOf(s))); + ofNullable(rule.type).ifPresent(t -> externalIssue.type(RuleType.valueOf(t))); return populateCommonValues(issue, externalIssue); } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/externalissue/ExternalIssueReport.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/externalissue/ExternalIssueReport.java index bc5bbbe79c7..e7195009602 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/externalissue/ExternalIssueReport.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/externalissue/ExternalIssueReport.java @@ -47,6 +47,8 @@ public class ExternalIssueReport { String name; @Nullable String description; + String type; + String severity; String cleanCodeAttribute; Impact[] impacts; } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/externalissue/ExternalIssueReportValidator.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/externalissue/ExternalIssueReportValidator.java index fc854c79dc1..386224ff5d7 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/externalissue/ExternalIssueReportValidator.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/externalissue/ExternalIssueReportValidator.java @@ -25,6 +25,7 @@ import java.util.Set; import javax.annotation.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.sonar.api.rules.RuleType; import org.sonar.api.scanner.ScannerSide; import org.sonar.core.documentation.DocumentationLinkGenerator; @@ -53,7 +54,7 @@ public class ExternalIssueReportValidator { public void validate(ExternalIssueReport report, Path reportPath) { if (report.rules != null && report.issues != null) { Set<String> ruleIds = validateRules(report.rules, reportPath); - validateIssuesCctFormat(report.issues, ruleIds, reportPath); + validateIssuesNewFormat(report.issues, ruleIds, reportPath); } else if (report.rules == null && report.issues != null) { String documentationLink = documentationLinkGenerator.getDocumentationLink(DOCUMENTATION_SUFFIX); LOGGER.warn("External issues were imported with a deprecated format which will be removed soon. " + @@ -64,7 +65,7 @@ public class ExternalIssueReportValidator { } } - private static void validateIssuesCctFormat(ExternalIssueReport.Issue[] issues, Set<String> ruleIds, Path reportPath) { + private static void validateIssuesNewFormat(ExternalIssueReport.Issue[] issues, Set<String> ruleIds, Path reportPath) { for (ExternalIssueReport.Issue issue : issues) { mandatoryField(issue.ruleId, ISSUE_RULE_ID, reportPath); checkRuleExistsInReport(ruleIds, issue, reportPath); @@ -90,8 +91,19 @@ public class ExternalIssueReportValidator { mandatoryField(rule.id, "id", reportPath); mandatoryField(rule.name, "name", reportPath); mandatoryField(rule.engineId, "engineId", reportPath); - mandatoryField(rule.cleanCodeAttribute, "cleanCodeAttribute", reportPath); - checkImpactsArray(rule.impacts, reportPath); + validateTypeOrImpacts(reportPath, rule); + + if (rule.impacts != null) { + checkImpactsArray(rule.impacts, reportPath); + validateImpactsOnSecurityHostpots(rule.impacts, rule.type, reportPath); + } + if (rule.type != null) { + mandatoryField(rule.severity, SEVERITY, reportPath); + } + + if (rule.severity != null) { + mandatoryField(rule.type, TYPE, reportPath); + } if (!ruleIds.add(rule.id)) { throw new IllegalStateException(String.format("Failed to parse report '%s': found duplicate rule ID '%s'.", reportPath, rule.id)); @@ -101,6 +113,18 @@ public class ExternalIssueReportValidator { return ruleIds; } + private static void validateImpactsOnSecurityHostpots(ExternalIssueReport.Impact[] impacts, String type, Path reportPath) { + if (impacts.length > 0 && RuleType.SECURITY_HOTSPOT.name().equals(type)) { + throw new IllegalStateException(String.format("Failed to parse report '%s': impacts should not be provided for rule type 'SECURITY_HOTSPOT'.", reportPath)); + } + } + + private static void validateTypeOrImpacts(Path reportPath, ExternalIssueReport.Rule rule) { + if (rule.type == null && rule.impacts == null) { + throw new IllegalStateException(String.format("Failed to parse report '%s': either type, impacts or both should be provided.", reportPath)); + } + } + private static void checkNoField(@Nullable Object value, String fieldName, Path reportPath) { if (value != null) { throw new IllegalStateException(String.format("Deprecated '%s' field found in the following report: '%s'.", fieldName, reportPath)); |