]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-16598 Add new generic concepts to rules/show and rules/search endpoints
authorPierre <pierre.guillot@sonarsource.com>
Tue, 5 Jul 2022 15:53:50 +0000 (17:53 +0200)
committersonartech <sonartech@sonarsource.com>
Tue, 12 Jul 2022 14:30:04 +0000 (14:30 +0000)
(cherry picked from commit 31375405689110a07958f2c3be3f3b6d2a824e2b)

server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java
server/sonar-db-dao/src/main/resources/org/sonar/db/rule/RuleMapper.xml
server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDaoTest.java
server/sonar-db-dao/src/testFixtures/java/org/sonar/db/rule/RuleTesting.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/RuleMapper.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
server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/ShowAction.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/SearchActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/ShowActionTest.java
sonar-ws/src/main/protobuf/ws-rules.proto

index 2655b8e8f31c8b4aec054fecb8530f2a09891818..c3809c2ded6bbaa3cb1bdcf5cedf21dc5e1ea6d7 100644 (file)
@@ -21,7 +21,6 @@ package org.sonar.db.rule;
 
 import com.google.common.base.Splitter;
 import com.google.common.collect.ImmutableSet;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Objects;
@@ -37,6 +36,7 @@ import org.sonar.api.rule.RuleStatus;
 import org.sonar.api.rules.RuleType;
 
 import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.Arrays.asList;
 import static java.util.Collections.emptySet;
 import static java.util.Optional.ofNullable;
 import static org.sonar.db.rule.RuleDescriptionSectionDto.DEFAULT_KEY;
@@ -60,6 +60,7 @@ public class RuleDto {
   private String ruleKey = null;
 
   private final Set<RuleDescriptionSectionDto> ruleDescriptionSectionDtos = new HashSet<>();
+  private String genericConceptsField = null;
 
   /**
    * Description format can be null on external rule, otherwise it should never be null
@@ -236,6 +237,15 @@ public class RuleDto {
     return Objects.equals(contextKey, otherContextKey);
   }
 
+  public Set<String> getGenericConcepts() {
+    return deserializeStringSet(genericConceptsField);
+  }
+
+  public RuleDto setGenericConcepts(Set<String> genericConcepts){
+    this.genericConceptsField = serializeStringSet(genericConcepts);
+    return this;
+  }
+
   @CheckForNull
   public Format getDescriptionFormat() {
     return descriptionFormat;
@@ -531,7 +541,7 @@ public class RuleDto {
   }
 
   public Set<String> getTags() {
-    return tags == null ? new HashSet<>() : new TreeSet<>(Arrays.asList(StringUtils.split(tags, ',')));
+    return tags == null ? new HashSet<>() : new TreeSet<>(asList(StringUtils.split(tags, ',')));
   }
 
   String getTagsAsString() {
index 643343da0bd6c35c9ac5f9836f57150a9e5cfc6f..4ccbfe936519d4afbd43d716837229ea8d02e1fb 100644 (file)
@@ -38,7 +38,8 @@
     r.ad_hoc_name as "adHocName",
     r.ad_hoc_description as "adHocDescription",
     r.ad_hoc_severity as "adHocSeverity",
-    r.ad_hoc_type as "adHocType"
+    r.ad_hoc_type as "adHocType",
+    r.generic_concepts as "genericConceptsField"
   </sql>
 
   <sql id="leftOuterJoinRulesDescriptionSections">
       ad_hoc_description,
       ad_hoc_severity,
       ad_hoc_type,
+      generic_concepts,
       created_at,
       updated_at
     )
       #{adHocDescription,jdbcType=CLOB},
       #{adHocSeverity,jdbcType=VARCHAR},
       #{adHocType,jdbcType=TINYINT},
+      #{genericConceptsField,jdbcType=VARCHAR},
       #{createdAt,jdbcType=BIGINT},
       #{updatedAt,jdbcType=BIGINT}
     )
       ad_hoc_description=#{adHocDescription,jdbcType=CLOB},
       ad_hoc_severity=#{adHocSeverity,jdbcType=VARCHAR},
       ad_hoc_type=#{adHocType,jdbcType=TINYINT},
+      generic_concepts=#{genericConceptsField,jdbcType=VARCHAR},
       updated_at=#{updatedAt,jdbcType=BIGINT}
     where
       uuid=#{uuid,jdbcType=VARCHAR}
index 0405c7eaa551c01bd95cb77029ae0f287d5294df..c26aea06e5708065bb39a2b8fbab7f084e9d2d19 100644 (file)
@@ -237,6 +237,7 @@ public class RuleDaoTest {
     assertThat(actual.getAdHocType()).isEqualTo(expected.getAdHocType());
     assertThat(actual.getRuleDescriptionSectionDtos()).usingRecursiveFieldByFieldElementComparator()
       .containsExactlyInAnyOrderElementsOf(expected.getRuleDescriptionSectionDtos());
+    assertThat(actual.getGenericConcepts()).isEqualTo(expected.getGenericConcepts());
   }
 
   @Test
index c2a064c6a43016e1b2ecf97b19e7e761477dd4c9..87e7ed0dde571b933947fde0946ded984eb623e4 100644 (file)
@@ -118,7 +118,8 @@ public class RuleTesting {
       .setAdHocType(RuleType.values()[nextInt(RuleType.values().length - 1)])
       .setCreatedAt(currentTimeMillis)
       .setUpdatedAt(currentTimeMillis + 5)
-      .setScope(Scope.MAIN);
+      .setScope(Scope.MAIN)
+      .setGenericConcepts(Set.of(randomAlphanumeric(5), randomAlphanumeric(5)));
   }
 
   public static RuleParamDto newRuleParam(RuleDto rule) {
index 196cf330a26fb0a5e44d23b7c26786df42e05a8f..856833ccf5243439a8e07e81200bb43fc26c9006 100644 (file)
@@ -61,6 +61,7 @@ import static org.sonar.server.rule.ws.RulesWsParameters.FIELD_DEPRECATED_KEYS;
 import static org.sonar.server.rule.ws.RulesWsParameters.FIELD_DESCRIPTION_SECTIONS;
 import static org.sonar.server.rule.ws.RulesWsParameters.FIELD_EFFORT_TO_FIX_DESCRIPTION;
 import static org.sonar.server.rule.ws.RulesWsParameters.FIELD_GAP_DESCRIPTION;
+import static org.sonar.server.rule.ws.RulesWsParameters.FIELD_GENERIC_CONCEPTS;
 import static org.sonar.server.rule.ws.RulesWsParameters.FIELD_HTML_DESCRIPTION;
 import static org.sonar.server.rule.ws.RulesWsParameters.FIELD_INTERNAL_KEY;
 import static org.sonar.server.rule.ws.RulesWsParameters.FIELD_IS_EXTERNAL;
@@ -147,6 +148,7 @@ public class RuleMapper {
       setAdHocSeverity(ruleResponse, ruleDto, fieldsToReturn);
       setAdHocType(ruleResponse, ruleDto);
     }
+    setGenericConcepts(ruleResponse, ruleDto, fieldsToReturn);
     return ruleResponse;
   }
 
@@ -197,6 +199,12 @@ public class RuleMapper {
     }
   }
 
+  private static void setGenericConcepts(Rules.Rule.Builder ruleResponse, RuleDto ruleDto, Set<String> fieldsToReturn) {
+    if (shouldReturnField(fieldsToReturn, FIELD_GENERIC_CONCEPTS)) {
+      ruleResponse.getGenericConceptsBuilder().addAllGenericConcepts((ruleDto.getGenericConcepts()));
+    }
+  }
+
   private static void setDeprecatedKeys(Rules.Rule.Builder ruleResponse, RuleDto ruleDto, Set<String> fieldsToReturn,
     Map<String, List<DeprecatedRuleKeyDto>> deprecatedRuleKeysByRuleUuid) {
     if (shouldReturnField(fieldsToReturn, FIELD_DEPRECATED_KEYS)) {
index 15260041edfd6bcfd630fc923c1a6aea95920cd9..4f4af555c87752bc8c3ef348740e9ff1ffda2524 100644 (file)
@@ -62,6 +62,7 @@ public class RulesWsParameters {
   public static final String FIELD_MARKDOWN_DESCRIPTION = "mdDesc";
 
   public static final String FIELD_DESCRIPTION_SECTIONS = "descriptionSections";
+  public static final String FIELD_GENERIC_CONCEPTS = "genericConcepts";
   public static final String FIELD_NOTE_LOGIN = "noteLogin";
   public static final String FIELD_MARKDOWN_NOTE = "mdNote";
   public static final String FIELD_HTML_NOTE = "htmlNote";
@@ -109,7 +110,7 @@ public class RulesWsParameters {
     FIELD_MARKDOWN_DESCRIPTION, FIELD_DESCRIPTION_SECTIONS, FIELD_NOTE_LOGIN, FIELD_MARKDOWN_NOTE, FIELD_HTML_NOTE,
     FIELD_DEFAULT_DEBT_REM_FUNCTION, FIELD_EFFORT_TO_FIX_DESCRIPTION, FIELD_DEBT_OVERLOADED, FIELD_DEBT_REM_FUNCTION,
     FIELD_DEFAULT_REM_FUNCTION, FIELD_GAP_DESCRIPTION, FIELD_REM_FUNCTION_OVERLOADED, FIELD_REM_FUNCTION,
-    FIELD_PARAMS, FIELD_ACTIVES, FIELD_SCOPE, FIELD_DEPRECATED_KEYS);
+    FIELD_PARAMS, FIELD_ACTIVES, FIELD_SCOPE, FIELD_DEPRECATED_KEYS, FIELD_GENERIC_CONCEPTS);
 
   private RulesWsParameters() {
     // prevent instantiation
index 1db0a7cada20b53a259119314ab311f0f7e5d374..31db2ae17a7ad2ff416a587733deae9e730a2133 100644 (file)
@@ -151,7 +151,8 @@ public class SearchAction implements RulesWsAction {
         new Change("9.5", "The field 'htmlDesc' has been deprecated use 'descriptionSections' instead"),
         new Change("9.5", "The field 'descriptionSections' has been added to the payload"),
         new Change("9.5", "The field 'descriptionSections' has been added to the 'f' parameter"),
-        new Change("9.6", "'descriptionSections' can optionally embed a context field")
+        new Change("9.6", "'descriptionSections' can optionally embed a context field"),
+        new Change("9.6", "The field 'genericConcepts' has been added to the 'f' parameter")
       );
 
     action.createParam(FACETS)
index ec32f637346ada1fb5929720a6f8392fbc2eb01b..1e5afdb58f91b3c5040f597218968190506ff41a 100644 (file)
@@ -79,7 +79,8 @@ public class ShowAction implements RulesWsAction {
         new Change("9.5", "The field 'htmlDesc' has been deprecated use 'descriptionSections' instead"),
         new Change("9.5", "The field 'descriptionSections' has been added to the payload"),
         new Change("9.5", "The field 'descriptionSections' has been added to the 'f' parameter"),
-        new Change("9.6", "'descriptionSections' can optionally embed a context field")
+        new Change("9.6", "'descriptionSections' can optionally embed a context field"),
+        new Change("9.6", "'genericConcepts' has been added")
       );
 
     action
index a4b683a504005bf59ee402b86579a80c778f3535..bdc2bf3c09ac81400308cb454ef83cb8a0246bfb 100644 (file)
@@ -309,7 +309,7 @@ public class SearchActionTest {
     indexRules();
 
     Rules.SearchResponse response = ws.newRequest()
-      .setParam(WebService.Param.FIELDS, "createdAt,langName")
+      .setParam(WebService.Param.FIELDS, "createdAt,langName,genericConcepts")
       .executeProtobuf(Rules.SearchResponse.class);
     Rules.Rule result = response.getRules(0);
 
@@ -320,6 +320,7 @@ public class SearchActionTest {
     // selected fields
     assertThat(result.getCreatedAt()).isNotEmpty();
     assertThat(result.getLangName()).isNotEmpty();
+    assertThat(result.getGenericConcepts().getGenericConceptsList()).containsExactlyElementsOf(rule.getGenericConcepts());
 
     // not returned fields
     assertThat(result.hasEffortToFixDescription()).isFalse();
index 54b5775528a458961cd8c96eaa60e8879657fdb3..8e6590dee747f59826c0638a753138a83aa59793 100644 (file)
@@ -130,6 +130,7 @@ public class ShowActionTest {
     assertThat(resultRule.getParams().getParamsList())
       .extracting(Rule.Param::getKey, Rule.Param::getHtmlDesc, Rule.Param::getDefaultValue)
       .containsExactlyInAnyOrder(tuple(ruleParam.getName(), ruleParam.getDescription(), ruleParam.getDefaultValue()));
+    assertThat(resultRule.getGenericConcepts().getGenericConceptsList()).containsExactlyElementsOf(rule.getGenericConcepts());
   }
 
   @Test
index e1772529d3c8fc575416214ae3cf6e67f2d46ad3..ec2ee2506247a9faf6d886839c9c6fc8e842ae5e 100644 (file)
@@ -123,6 +123,7 @@ message Rule {
   optional bool isExternal = 47;
   optional DeprecatedKeys deprecatedKeys = 48;
   optional DescriptionSections descriptionSections = 49;
+  optional GenericConcepts genericConcepts = 50;
 
   message DescriptionSections {
     repeated DescriptionSection descriptionSections = 1;
@@ -163,6 +164,10 @@ message Tags {
   repeated string tags = 1;
 }
 
+message GenericConcepts {
+  repeated string genericConcepts = 1;
+}
+
 message Actives {
   map<string, ActiveList> actives = 1;
 }