]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-22224 Add prioritizedRule to rules/search api
authorDDMili <130993898+dejan-milisavljevic-sonarsource@users.noreply.github.com>
Fri, 31 May 2024 14:19:26 +0000 (16:19 +0200)
committersonartech <sonartech@sonarsource.com>
Mon, 3 Jun 2024 20:02:59 +0000 (20:02 +0000)
server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/IndexedActiveRuleDto.java
server/sonar-server-common/src/main/java/org/sonar/server/qualityprofile/index/ActiveRuleDoc.java
server/sonar-server-common/src/main/java/org/sonar/server/qualityprofile/index/ActiveRuleIndexer.java
server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndex.java
server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndexDefinition.java
server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleQuery.java
server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/SearchActionIT.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/RuleQueryFactory.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/RuleWsSupport.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/RulesWsParameters.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/SearchAction.java

index 49a1f0e374e431780e378c08fa4a56b26789f1a3..585cc332186dd2d788cd1ba3768ffbd1477a8581 100644 (file)
@@ -29,6 +29,7 @@ public class IndexedActiveRuleDto {
   private String repository;
   private String key;
   private String ruleProfileUuid;
+  private Boolean prioritizedRule;
 
   public IndexedActiveRuleDto() {
     // nothing to do here
@@ -62,4 +63,8 @@ public class IndexedActiveRuleDto {
   public String getRuleProfileUuid() {
     return ruleProfileUuid;
   }
+
+  public Boolean getPrioritizedRule() {
+    return prioritizedRule;
+  }
 }
index eedbf89adc653ef2e5e00979fc8810c16c725aae..f602bb21a5e1bf30cfc857eddd92b39921ed1a02 100644 (file)
@@ -21,6 +21,8 @@ package org.sonar.server.qualityprofile.index;
 
 import com.google.common.collect.Maps;
 import java.util.Map;
+import java.util.Optional;
+import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 import org.sonar.server.es.BaseDoc;
 import org.sonar.server.qualityprofile.ActiveRuleInheritance;
@@ -30,6 +32,7 @@ import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_
 import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_PROFILE_UUID;
 import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_SEVERITY;
 import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_UUID;
+import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_PRIORITIZED_RULE;
 import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_UUID;
 import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_ACTIVE_RULE;
 
@@ -87,6 +90,12 @@ public class ActiveRuleDoc extends BaseDoc {
     return this;
   }
 
+  ActiveRuleDoc setPrioritizedRule(@Nullable Boolean b) {
+    Boolean notNull = Optional.ofNullable(b).orElse(Boolean.FALSE);
+    setField(FIELD_PRIORITIZED_RULE, notNull);
+    return this;
+  }
+
   ActiveRuleInheritance getInheritance() {
     String inheritance = getNullableField(FIELD_ACTIVE_RULE_INHERITANCE);
     if (inheritance == null || inheritance.isEmpty() ||
index 7b91c40c1528d1005de5396067ed06c9b4c0f74f..d21651b379e4b85c7b934de444ceeb30a37a7269 100644 (file)
@@ -225,7 +225,8 @@ public class ActiveRuleIndexer implements ResilientIndexer {
     ActiveRuleDoc doc = new ActiveRuleDoc(dto.getUuid())
       .setRuleUuid(dto.getRuleUuid())
       .setRuleProfileUuid(dto.getRuleProfileUuid())
-      .setSeverity(SeverityUtil.getSeverityFromOrdinal(dto.getSeverity()));
+      .setSeverity(SeverityUtil.getSeverityFromOrdinal(dto.getSeverity()))
+      .setPrioritizedRule(dto.getPrioritizedRule());
     // all the fields must be present, even if value is null
     String inheritance = dto.getInheritance();
     doc.setInheritance(inheritance == null ? ActiveRuleInheritance.NONE.name() : inheritance);
index 4416dc50cd9d26e28018609fea0cdbc697cab52d..c3b6f438e97ab1edd21008e0e61bd39173378336 100644 (file)
@@ -96,6 +96,7 @@ import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_IMPA
 import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_INHERITANCE;
 import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_PROFILE_UUID;
 import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_SEVERITY;
+import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_PRIORITIZED_RULE;
 import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_CLEAN_CODE_ATTRIBUTE_CATEGORY;
 import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_CREATED_AT;
 import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_CWE;
@@ -443,6 +444,7 @@ public class RuleIndex {
     addTermFilter(activeRuleFilter, FIELD_ACTIVE_RULE_PROFILE_UUID, profile.getRulesProfileUuid());
     addTermFilter(activeRuleFilter, FIELD_ACTIVE_RULE_INHERITANCE, query.getInheritance());
     addTermFilter(activeRuleFilter, FIELD_ACTIVE_RULE_SEVERITY, query.getActiveSeverities());
+    addTermFilter(activeRuleFilter, FIELD_PRIORITIZED_RULE, query.getPrioritizedRule());
 
     // ChildQuery
     QueryBuilder childQuery;
@@ -473,6 +475,13 @@ public class RuleIndex {
     return filter;
   }
 
+  private static BoolQueryBuilder addTermFilter(BoolQueryBuilder filter, String field, @Nullable Boolean value) {
+    if (value != null) {
+      filter.must(QueryBuilders.termQuery(field, value));
+    }
+    return filter;
+  }
+
   private static Map<String, AggregationBuilder> getFacets(RuleQuery query, SearchOptions options, QueryBuilder queryBuilder,
     Map<String, QueryBuilder> filters) {
     Map<String, AggregationBuilder> aggregations = new HashMap<>();
index 6a27bb34c320f5327a0349242334123068bcd022..6da248e2eaca8086947cbe3dfe99104327d49b75 100644 (file)
@@ -86,6 +86,7 @@ public class RuleIndexDefinition implements IndexDefinition {
   public static final String SUB_FIELD_SEVERITY = "severity";
   public static final String FIELD_RULE_IMPACT_SOFTWARE_QUALITY = FIELD_RULE_IMPACTS + "." + SUB_FIELD_SOFTWARE_QUALITY;
   public static final String FIELD_RULE_IMPACT_SEVERITY = FIELD_RULE_IMPACTS + "." + SUB_FIELD_SEVERITY;
+  public static final String FIELD_PRIORITIZED_RULE = "activeRule_prioritizedRule";
 
   private final Configuration config;
   private final boolean enableSource;
@@ -166,6 +167,7 @@ public class RuleIndexDefinition implements IndexDefinition {
       .keywordFieldBuilder(FIELD_ACTIVE_RULE_UUID).disableNorms().build()
       .keywordFieldBuilder(FIELD_ACTIVE_RULE_PROFILE_UUID).disableNorms().build()
       .keywordFieldBuilder(FIELD_ACTIVE_RULE_INHERITANCE).disableNorms().build()
-      .keywordFieldBuilder(FIELD_ACTIVE_RULE_SEVERITY).disableNorms().build();
+      .keywordFieldBuilder(FIELD_ACTIVE_RULE_SEVERITY).disableNorms().build()
+      .createBooleanField(FIELD_PRIORITIZED_RULE);
   }
 }
index b3f4abb0aa4b5def83a81e9043333ffb535f97f6..7c46f846f6bd9814819e987cfc4006071ace3b23 100644 (file)
@@ -61,6 +61,7 @@ public class RuleQuery {
   private Collection<String> impactSeverities;
   private Collection<String> impactSoftwareQualities;
   private Collection<String> cleanCodeAttributesCategories;
+  private Boolean prioritizedRule;
 
 
   @CheckForNull
@@ -369,4 +370,13 @@ public class RuleQuery {
     return this;
   }
 
+  @Nullable
+  public Boolean getPrioritizedRule() {
+    return prioritizedRule;
+  }
+
+  public RuleQuery setPrioritizedRule(@Nullable Boolean prioritizedRule) {
+    this.prioritizedRule = prioritizedRule;
+    return this;
+  }
 }
index cfd07ec45505b3ab19ecc940d97ad3b81d041a9a..cb8219e5d2e748f650889058cf710820a9fbf48a 100644 (file)
@@ -157,7 +157,7 @@ public class SearchActionIT {
     assertThat(def.since()).isEqualTo("4.4");
     assertThat(def.isInternal()).isFalse();
     assertThat(def.responseExampleAsString()).isNotEmpty();
-    assertThat(def.params()).hasSize(31);
+    assertThat(def.params()).hasSize(32);
 
     WebService.Param compareToProfile = def.param("compareToProfile");
     assertThat(compareToProfile.since()).isEqualTo("6.5");
index b29745af4900ee5c99a3342506b8d76720e00ea8..d6469fcb287ffd9316e8bc1f72273af3d1b2dae0 100644 (file)
@@ -47,6 +47,7 @@ import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_IS_TEMPLATE;
 import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_LANGUAGES;
 import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_OWASP_TOP_10;
 import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_OWASP_TOP_10_2021;
+import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_PRIORITIZED_RULE;
 import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_QPROFILE;
 import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_REPOSITORIES;
 import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_RULE_KEY;
@@ -73,6 +74,7 @@ public class RuleQueryFactory {
   public RuleQuery createRuleSearchQuery(DbSession dbSession, Request request) {
     RuleQuery query = createRuleQuery(dbSession, request);
     query.setIncludeExternal(request.mandatoryParamAsBoolean(PARAM_INCLUDE_EXTERNAL));
+    query.setPrioritizedRule(request.paramAsBoolean(PARAM_PRIORITIZED_RULE));
     return query;
   }
 
index e70999c5cdd2ae56a124c41c3fb8f167576aea9b..6667116ef4eb2de58561ff1f9d6b6765128be7b7 100644 (file)
@@ -43,6 +43,7 @@ import org.sonar.server.security.SecurityStandards;
 import org.sonar.server.security.SecurityStandards.SQCategory;
 import org.sonar.server.user.UserSession;
 
+import static java.lang.String.format;
 import static org.sonar.api.server.ws.WebService.Param.ASCENDING;
 import static org.sonar.api.server.ws.WebService.Param.SORT;
 import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY;
@@ -63,6 +64,7 @@ import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_IS_TEMPLATE;
 import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_LANGUAGES;
 import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_OWASP_TOP_10;
 import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_OWASP_TOP_10_2021;
+import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_PRIORITIZED_RULE;
 import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_QPROFILE;
 import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_REPOSITORIES;
 import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_RULE_KEY;
@@ -263,4 +265,12 @@ public class RuleWsSupport {
       .setSince("7.2");
   }
 
+  static void definePrioritizedRuleParam(WebService.NewAction action) {
+    action
+      .createParam(PARAM_PRIORITIZED_RULE)
+      .setDescription(format("Filter on prioritized rules. Ignored if the parameter '%s' is not set.", PARAM_QPROFILE))
+      .setBooleanPossibleValues()
+      .setSince("10.6");
+  }
+
 }
index e09071764fb90a55c2268310286dec12cd08b7a5..afef0698918b20ebc8f85298176de2ed32164936 100644 (file)
@@ -51,6 +51,7 @@ public class RulesWsParameters {
   public static final String PARAM_IMPACT_SOFTWARE_QUALITIES = "impactSoftwareQualities";
   public static final String PARAM_IMPACT_SEVERITIES = "impactSeverities";
   public static final String PARAM_CLEAN_CODE_ATTRIBUTE_CATEGORIES = "cleanCodeAttributeCategories";
+  public static final String PARAM_PRIORITIZED_RULE = "prioritizedRule";
 
   public static final String FIELD_REPO = "repo";
   public static final String FIELD_NAME = "name";
index 7b150eeb9d5f8c354be98947c58613c1b1da3329..174bafec6d6f0b98075d81fbac4fd2694151264f 100644 (file)
@@ -33,6 +33,7 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 import java.util.stream.Collectors;
+import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 import org.sonar.api.issue.impact.SoftwareQuality;
 import org.sonar.api.rule.Severity;
@@ -89,6 +90,7 @@ import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_IMPACT_SOFTWARE_Q
 import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_LANGUAGES;
 import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_OWASP_TOP_10;
 import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_OWASP_TOP_10_2021;
+import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_PRIORITIZED_RULE;
 import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_REPOSITORIES;
 import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_SANS_TOP_25;
 import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_SEVERITIES;
@@ -139,6 +141,7 @@ public class SearchAction implements RulesWsAction {
       .addPagingParams(100, MAX_PAGE_SIZE)
       .setHandler(this)
       .setChangelog(
+        new Change("10.6", format("Parameter '%s has been added", PARAM_PRIORITIZED_RULE)),
         new Change("5.5", "The field 'effortToFixDescription' has been deprecated, use 'gapDescription' instead"),
         new Change("5.5", "The field 'debtRemFnCoeff' has been deprecated, use 'remFnGapMultiplier' instead"),
         new Change("5.5", "The field 'defaultDebtRemFnCoeff' has been deprecated, use 'defaultRemFnGapMultiplier' instead"),
@@ -201,6 +204,7 @@ public class SearchAction implements RulesWsAction {
     // Rule-specific search parameters
     RuleWsSupport.defineGenericRuleSearchParameters(action);
     RuleWsSupport.defineIsExternalParam(action);
+    RuleWsSupport.definePrioritizedRuleParam(action);
   }
 
   @Override
@@ -423,7 +427,8 @@ public class SearchAction implements RulesWsAction {
       .setOwaspTop10(request.paramAsStrings(PARAM_OWASP_TOP_10))
       .setOwaspTop10For2021(request.paramAsStrings(PARAM_OWASP_TOP_10_2021))
       .setSansTop25(request.paramAsStrings(PARAM_SANS_TOP_25))
-      .setSonarsourceSecurity(request.paramAsStrings(PARAM_SONARSOURCE_SECURITY));
+      .setSonarsourceSecurity(request.paramAsStrings(PARAM_SONARSOURCE_SECURITY))
+      .setPrioritizedRule(request.paramAsBoolean(PARAM_PRIORITIZED_RULE));
   }
 
   private static class SearchRequest {
@@ -447,6 +452,7 @@ public class SearchAction implements RulesWsAction {
     private List<String> impactSeverities;
     private List<String> impactSoftwareQualities;
     private List<String> cleanCodeAttributesCategories;
+    private Boolean prioritizedRule;
 
     private SearchRequest setActiveSeverities(List<String> activeSeverities) {
       this.activeSeverities = activeSeverities;
@@ -623,5 +629,15 @@ public class SearchAction implements RulesWsAction {
       this.cleanCodeAttributesCategories = cleanCodeAttributesCategories;
       return this;
     }
+
+    @CheckForNull
+    public Boolean getPrioritizedRule() {
+      return prioritizedRule;
+    }
+
+    public SearchRequest setPrioritizedRule(@Nullable Boolean prioritizedRule) {
+      this.prioritizedRule = prioritizedRule;
+      return this;
+    }
   }
 }