dto.setProfileUuid(profile.getRulesProfileUuid());
dto.setRuleUuid(ruleDto.getUuid());
dto.setKey(ActiveRuleKey.of(profile, ruleDto.getKey()));
+ dto.setImpacts(ruleDto.getDefaultImpactsMap());
return dto;
}
Map<String, List<ActiveRuleParamDto>> paramsByActiveRuleUuid = dbClient.activeRuleDao().selectParamsByActiveRuleUuids(dbSession, activeRuleUuids)
.stream().collect(Collectors.groupingBy(ActiveRuleParamDto::getActiveRuleUuid));
- Map<String, String> activeRuleUuidByRuleUuid = activeRuleDtos.stream().collect(Collectors.toMap(ActiveRuleDto::getRuleUuid, ActiveRuleDto::getUuid));
+ Map<String, OrgActiveRuleDto> activeRuleByRuleUuid = activeRuleDtos.stream().collect(Collectors.toMap(ActiveRuleDto::getRuleUuid,
+ r -> r));
List<String> ruleUuids = activeRuleDtos.stream().map(ActiveRuleDto::getRuleUuid).toList();
List<RuleDto> ruleDtos = dbClient.ruleDao().selectByUuids(dbSession, ruleUuids);
for (RuleDto ruleDto : ruleDtos) {
- String activeRuleUuid = activeRuleUuidByRuleUuid.get(ruleDto.getUuid());
+ OrgActiveRuleDto activeRule = activeRuleByRuleUuid.get(ruleDto.getUuid());
+ String activeRuleUuid = activeRule.getUuid();
List<ActiveRuleParamDto> params = paramsByActiveRuleUuid.getOrDefault(activeRuleUuid, new ArrayList<>());
- RuleChange ruleChange = toRuleChange(ruleDto, params);
+ RuleChange ruleChange = toRuleChange(ruleDto, activeRule, params);
ruleChanges.add(ruleChange);
}
}
}
@NotNull
- private RuleChange toRuleChange(RuleDto ruleDto, List<ActiveRuleParamDto> activeRuleParamDtos) {
+ private RuleChange toRuleChange(RuleDto ruleDto, OrgActiveRuleDto activeRule, List<ActiveRuleParamDto> activeRuleParamDtos) {
RuleChange ruleChange = new RuleChange();
ruleChange.setKey(ruleDto.getKey().toString());
ruleChange.setLanguage(ruleDto.getLanguage());
- ruleChange.setSeverity(ruleDto.getSeverityString());
+ ruleChange.setSeverity(activeRule.getSeverityString());
+ activeRule.getImpacts().forEach(ruleChange::addImpact);
List<ParamChange> paramChanges = new ArrayList<>();
for (ActiveRuleParamDto activeRuleParam : activeRuleParamDtos) {
ruleChange.setSeverity(arc.getSeverity());
ruleChange.setLanguage(language);
+ arc.getImpactSeverities().forEach(ruleChange::addImpact);
+
Optional<String> templateKey = templateKey(arc);
templateKey.ifPresent(ruleChange::setTemplateKey);
.collect(Collectors.toSet());
}
-
-
-
private static byte[] serializeIssueToPushEvent(RuleSetChangedEvent event) {
return GSON.toJson(event).getBytes(UTF_8);
}
import java.util.Collections;
import java.util.Deque;
import java.util.List;
+import java.util.Map;
+import java.util.Random;
import java.util.Set;
import java.util.function.Consumer;
-import org.junit.Rule;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.sonar.api.issue.impact.Severity;
+import org.sonar.api.issue.impact.SoftwareQuality;
import org.sonar.api.rule.RuleKey;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.rule.RuleDto;
import org.sonar.db.rule.RuleParamDto;
import org.sonar.server.qualityprofile.ActiveRuleChange;
-import org.sonarqube.ws.Common;
import static java.util.List.of;
import static org.apache.commons.lang3.RandomStringUtils.secure;
import static org.sonar.db.rule.RuleTesting.newTemplateRule;
import static org.sonar.server.qualityprofile.ActiveRuleChange.Type.ACTIVATED;
-public class QualityProfileChangeEventServiceImplTest {
+class QualityProfileChangeEventServiceImplTest {
- @Rule
- public DbTester db = DbTester.create();
-
- public final QualityProfileChangeEventServiceImpl underTest = new QualityProfileChangeEventServiceImpl(db.getDbClient());
+ @RegisterExtension
+ private final DbTester db = DbTester.create();
+ private final QualityProfileChangeEventServiceImpl underTest = new QualityProfileChangeEventServiceImpl(db.getDbClient());
@Test
- public void distributeRuleChangeEvent() {
+ void distributeRuleChangeEvent() {
QProfileDto qualityProfileDto = QualityProfileTesting.newQualityProfileDto();
RuleDto templateRule = newTemplateRule(RuleKey.of("xoo", "template-key"));
db.rules().insert(rule1);
ActiveRuleChange activeRuleChange = changeActiveRule(qualityProfileDto, rule1, "paramChangeKey", "paramChangeValue");
+ activeRuleChange.setImpactSeverities(Map.of(SoftwareQuality.MAINTAINABILITY, Severity.LOW));
Collection<QProfileDto> profiles = Collections.singleton(qualityProfileDto);
.contains("\"activatedRules\":[{\"key\":\"repo:ruleKey\"," +
"\"language\":\"xoo\"," +
"\"templateKey\":\"xoo:template-key\"," +
- "\"params\":[{\"key\":\"paramChangeKey\",\"value\":\"paramChangeValue\"}]}]," +
+ "\"params\":[{\"key\":\"paramChangeKey\",\"value\":\"paramChangeValue\"}]," +
+ "\"impacts\":[{\"softwareQuality\":\"MAINTAINABILITY\",\"severity\":\"LOW\"}]}]," +
"\"deactivatedRules\":[]");
}
@Test
- public void distributeRuleChangeEvent_when_project_has_only_default_quality_profiles() {
+ void distributeRuleChangeEvent_when_project_has_only_default_quality_profiles() {
String language = "xoo";
ProjectData projectData = db.components().insertPrivateProject();
ComponentDto mainBranch = projectData.getMainBranchComponent();
RuleDto templateRule = insertTemplateRule();
QProfileDto defaultQualityProfile = insertDefaultQualityProfile(language);
RuleDto rule = insertCustomRule(templateRule, language, "<div>line1\nline2</div>");
- ActiveRuleChange activeRuleChange = changeActiveRule(defaultQualityProfile, rule, "paramChangeKey", "paramChangeValue");
+ ActiveRuleChange activeRuleChange = changeActiveRule(defaultQualityProfile, rule, "paramChangeKey", "paramChangeValue")
+ .setImpactSeverities(Map.of(SoftwareQuality.RELIABILITY, Severity.MEDIUM));
db.measures().insertMeasure(mainBranch, m -> m.addValue(NCLOC_LANGUAGE_DISTRIBUTION_KEY, language + "=100"));
db.getSession().commit();
.contains("\"activatedRules\":[{\"key\":\"repo:ruleKey\"," +
"\"language\":\"xoo\"," +
"\"templateKey\":\"xoo:template-key\"," +
- "\"params\":[{\"key\":\"paramChangeKey\",\"value\":\"paramChangeValue\"}]}]," +
+ "\"params\":[{\"key\":\"paramChangeKey\",\"value\":\"paramChangeValue\"}]," +
+ "\"impacts\":[{\"softwareQuality\":\"RELIABILITY\",\"severity\":\"MEDIUM\"}]}]," +
"\"deactivatedRules\":[]");
}
}
@Test
- public void publishRuleActivationToSonarLintClients() {
+ void publishRuleActivationToSonarLintClients() {
ProjectDto projectDto = new ProjectDto().setUuid("project-uuid");
QProfileDto activatedQualityProfile = QualityProfileTesting.newQualityProfileDto();
activatedQualityProfile.setLanguage("xoo");
RuleDto rule1 = db.rules().insert(r -> r.setLanguage("xoo").setRepositoryKey("repo").setRuleKey("ruleKey"));
RuleParamDto rule1Param = db.rules().insertRuleParam(rule1);
- ActiveRuleDto activeRule1 = db.qualityProfiles().activateRule(activatedQualityProfile, rule1);
+ ActiveRuleDto activeRule1 = db.qualityProfiles().activateRule(activatedQualityProfile, rule1, ar -> ar.setImpacts(Map.of(SoftwareQuality.SECURITY, Severity.BLOCKER)));
ActiveRuleParamDto activeRuleParam1 = ActiveRuleParamDto.createFor(rule1Param).setValue(secure().nextAlphanumeric(20));
db.getDbClient().activeRuleDao().insertParam(db.getSession(), activeRule1, activeRuleParam1);
db.getSession().commit();
assertThat(ruleSetChangedEvent)
.contains("\"activatedRules\":[{\"key\":\"repo:ruleKey\"," +
- "\"language\":\"xoo\",\"severity\":\"" + Common.Severity.forNumber(rule1.getSeverity()).name() + "\"," +
- "\"params\":[{\"key\":\"" + activeRuleParam1.getKey() + "\",\"value\":\"" + activeRuleParam1.getValue() + "\"}]}]," +
+ "\"language\":\"xoo\",\"severity\":\"" + activeRule1.getSeverityString() + "\"," +
+ "\"params\":[{\"key\":\"" + activeRuleParam1.getKey() + "\",\"value\":\"" + activeRuleParam1.getValue() + "\"}]," +
+ "\"impacts\":[{\"softwareQuality\":\"SECURITY\",\"severity\":\"BLOCKER\"}]}]," +
"\"deactivatedRules\":[\"repo2:ruleKey2\"]");
}
}
package org.sonar.core.util.rule;
import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
+import org.sonar.api.issue.impact.Severity;
+import org.sonar.api.issue.impact.SoftwareQuality;
import org.sonar.core.util.ParamChange;
public class RuleChange implements Serializable {
private String templateKey;
private String severity;
private ParamChange[] params = new ParamChange[0];
+ private final List<Impact> impacts = new ArrayList<>();
public String getKey() {
return key;
this.params = params;
return this;
}
+
+ public List<Impact> getImpacts() {
+ return impacts;
+ }
+
+ public void addImpact(SoftwareQuality softwareQuality, Severity severity) {
+ impacts.add(new Impact(softwareQuality, severity));
+ }
+
+ static class Impact implements Serializable {
+ private final SoftwareQuality softwareQuality;
+ private final Severity severity;
+
+ Impact(SoftwareQuality softwareQuality, Severity severity) {
+ this.softwareQuality = softwareQuality;
+ this.severity = severity;
+ }
+
+ public SoftwareQuality getSoftwareQuality() {
+ return softwareQuality;
+ }
+
+ public Severity getSeverity() {
+ return severity;
+ }
+ }
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2024 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.core.util.rule;
+
+import org.junit.jupiter.api.Test;
+import org.sonar.api.issue.impact.Severity;
+import org.sonar.api.issue.impact.SoftwareQuality;
+import org.sonar.core.util.ParamChange;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class RuleChangeTest {
+
+ @Test
+ void valuesAreStoredAndReturnedCorrectly() {
+ RuleChange ruleChange = new RuleChange();
+
+ ruleChange.setKey("key");
+ ruleChange.setTemplateKey("templateKey");
+ ruleChange.setLanguage("language");
+ ruleChange.setSeverity("severity");
+ ruleChange.setParams(new ParamChange[]{new ParamChange("paramKey", "paramValue")});
+ ruleChange.addImpact(SoftwareQuality.MAINTAINABILITY, Severity.HIGH);
+
+ assertThat(ruleChange).extracting(
+ RuleChange::getKey,
+ RuleChange::getTemplateKey,
+ RuleChange::getLanguage,
+ RuleChange::getSeverity)
+ .containsExactly(
+ "key",
+ "templateKey",
+ "language",
+ "severity");
+
+ assertThat(ruleChange.getParams()).hasSize(1);
+ assertThat(ruleChange.getParams()[0])
+ .extracting(ParamChange::getKey, ParamChange::getValue)
+ .containsExactly("paramKey", "paramValue");
+
+ assertThat(ruleChange.getImpacts()).hasSize(1);
+ assertThat(ruleChange.getImpacts().get(0))
+ .extracting(RuleChange.Impact::getSoftwareQuality, RuleChange.Impact::getSeverity)
+ .containsExactly(SoftwareQuality.MAINTAINABILITY, Severity.HIGH);
+ }
+}