From 7eb70cfcb08299efa259f8261347ce99a3753c08 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Lievremont Date: Tue, 9 Dec 2014 14:35:39 +0100 Subject: [PATCH] SONAR-5899 Use tags in issues queries --- .../org/sonar/server/issue/IssueQuery.java | 12 ++++++++++ .../sonar/server/issue/IssueQueryService.java | 2 ++ .../issue/filter/IssueFilterParameters.java | 3 ++- .../sonar/server/issue/index/IssueIndex.java | 3 +++ .../server/issue/index/IssueNormalizer.java | 1 + .../sonar/server/issue/ws/SearchAction.java | 24 +++++++++++++++++-- .../server/issue/IssueQueryServiceTest.java | 2 ++ .../sonar/server/issue/IssueQueryTest.java | 5 ++++ .../issue/ws/SearchActionMediumTest.java | 2 +- 9 files changed, 50 insertions(+), 4 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQuery.java b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQuery.java index 16ec9fa6539..4d831e6f9df 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQuery.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQuery.java @@ -65,6 +65,7 @@ public class IssueQuery { private final Collection reporters; private final Collection assignees; private final Collection languages; + private final Collection tags; private final Boolean assigned; private final Boolean planned; private final Boolean resolved; @@ -89,6 +90,7 @@ public class IssueQuery { this.reporters = defaultCollection(builder.reporters); this.assignees = defaultCollection(builder.assignees); this.languages = defaultCollection(builder.languages); + this.tags = defaultCollection(builder.tags); this.assigned = builder.assigned; this.planned = builder.planned; this.resolved = builder.resolved; @@ -149,6 +151,10 @@ public class IssueQuery { return languages; } + public Collection tags() { + return tags; + } + @CheckForNull public Boolean assigned() { return assigned; @@ -224,6 +230,7 @@ public class IssueQuery { private Collection reporters; private Collection assignees; private Collection languages; + private Collection tags; private Boolean assigned = null; private Boolean planned = null; private Boolean resolved = null; @@ -298,6 +305,11 @@ public class IssueQuery { return this; } + public Builder tags(@Nullable Collection t) { + this.tags = t; + return this; + } + /** * If true, it will return all issues assigned to someone * If false, it will return all issues not assigned to someone diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQueryService.java b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQueryService.java index 88161e6ebc9..f49a2798f3f 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQueryService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQueryService.java @@ -69,6 +69,7 @@ public class IssueQueryService implements ServerComponent { .reporters(RubyUtils.toStrings(params.get(IssueFilterParameters.REPORTERS))) .assignees(RubyUtils.toStrings(params.get(IssueFilterParameters.ASSIGNEES))) .languages(RubyUtils.toStrings(params.get(IssueFilterParameters.LANGUAGES))) + .tags(RubyUtils.toStrings(params.get(IssueFilterParameters.TAGS))) .assigned(RubyUtils.toBoolean(params.get(IssueFilterParameters.ASSIGNED))) .planned(RubyUtils.toBoolean(params.get(IssueFilterParameters.PLANNED))) .hideRules(RubyUtils.toBoolean(params.get(IssueFilterParameters.HIDE_RULES))) @@ -111,6 +112,7 @@ public class IssueQueryService implements ServerComponent { .reporters(request.paramAsStrings(IssueFilterParameters.REPORTERS)) .assignees(request.paramAsStrings(IssueFilterParameters.ASSIGNEES)) .languages(request.paramAsStrings(IssueFilterParameters.LANGUAGES)) + .tags(request.paramAsStrings(IssueFilterParameters.TAGS)) .assigned(request.paramAsBoolean(IssueFilterParameters.ASSIGNED)) .planned(request.paramAsBoolean(IssueFilterParameters.PLANNED)) .createdAt(request.paramAsDateTime(IssueFilterParameters.CREATED_AT)) diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/filter/IssueFilterParameters.java b/server/sonar-server/src/main/java/org/sonar/server/issue/filter/IssueFilterParameters.java index 4180c4fe537..8dbe5d1776c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/filter/IssueFilterParameters.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/filter/IssueFilterParameters.java @@ -49,6 +49,7 @@ public class IssueFilterParameters { public static final String REPORTERS = "reporters"; public static final String ASSIGNEES = "assignees"; public static final String LANGUAGES = "languages"; + public static final String TAGS = "tags"; public static final String ASSIGNED = "assigned"; public static final String PLANNED = "planned"; public static final String HIDE_RULES = "hideRules"; @@ -61,7 +62,7 @@ public class IssueFilterParameters { public static final String ASC = "asc"; public static final String IGNORE_PAGING = "ignorePaging"; - public static final List ALL = ImmutableList.of(ISSUES, SEVERITIES, STATUSES, RESOLUTIONS, RESOLVED, COMPONENTS, COMPONENT_ROOTS, RULES, ACTION_PLANS, REPORTERS, + public static final List ALL = ImmutableList.of(ISSUES, SEVERITIES, STATUSES, RESOLUTIONS, RESOLVED, COMPONENTS, COMPONENT_ROOTS, RULES, ACTION_PLANS, REPORTERS, TAGS, ASSIGNEES, LANGUAGES, ASSIGNED, PLANNED, HIDE_RULES, CREATED_AT, CREATED_AFTER, CREATED_BEFORE, PAGE_SIZE, PAGE_INDEX, SORT, ASC, COMPONENT_UUIDS, COMPONENT_ROOT_UUIDS, PROJECTS, PROJECT_UUIDS, IGNORE_PAGING); diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java index f7e1c1c1900..f951a4ee67c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java @@ -252,6 +252,7 @@ public class IssueIndex extends BaseIndex { filters.put(IssueIndexDefinition.FIELD_ISSUE_COMPONENT_UUID, matchFilter(IssueIndexDefinition.FIELD_ISSUE_COMPONENT_UUID, query.componentUuids())); filters.put(IssueIndexDefinition.FIELD_ISSUE_PROJECT_UUID, matchFilter(IssueIndexDefinition.FIELD_ISSUE_PROJECT_UUID, query.projectUuids())); filters.put(IssueIndexDefinition.FIELD_ISSUE_LANGUAGE, matchFilter(IssueIndexDefinition.FIELD_ISSUE_LANGUAGE, query.languages())); + filters.put(IssueIndexDefinition.FIELD_ISSUE_TAGS, matchFilter(IssueIndexDefinition.FIELD_ISSUE_TAGS, query.tags())); filters.put(IssueIndexDefinition.FIELD_ISSUE_RESOLUTION, matchFilter(IssueIndexDefinition.FIELD_ISSUE_RESOLUTION, query.resolutions())); filters.put(IssueIndexDefinition.FIELD_ISSUE_REPORTER, matchFilter(IssueIndexDefinition.FIELD_ISSUE_REPORTER, query.reporters())); filters.put(IssueIndexDefinition.FIELD_ISSUE_RULE_KEY, matchFilter(IssueIndexDefinition.FIELD_ISSUE_RULE_KEY, query.rules())); @@ -315,6 +316,8 @@ public class IssueIndex extends BaseIndex { IssueFilterParameters.PROJECT_UUIDS, IssueNormalizer.IssueField.PROJECT.field(), query.projectUuids().toArray()); addSimpleStickyFacetIfNeeded(options, stickyFacetBuilder, esSearch, IssueFilterParameters.LANGUAGES, IssueNormalizer.IssueField.LANGUAGE.field(), query.languages().toArray()); + addSimpleStickyFacetIfNeeded(options, stickyFacetBuilder, esSearch, + IssueFilterParameters.TAGS, IssueNormalizer.IssueField.TAGS.field(), query.tags().toArray()); addSimpleStickyFacetIfNeeded(options, stickyFacetBuilder, esSearch, IssueFilterParameters.RULES, IssueNormalizer.IssueField.RULE_KEY.field(), query.rules().toArray()); addSimpleStickyFacetIfNeeded(options, stickyFacetBuilder, esSearch, diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueNormalizer.java b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueNormalizer.java index 1a7e3dd6d0a..e0d8e6d2ffd 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueNormalizer.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueNormalizer.java @@ -66,6 +66,7 @@ public class IssueNormalizer extends BaseNormalizer { public static final IndexField SEVERITY = add(IndexField.Type.STRING, "severity"); public static final IndexField SEVERITY_VALUE = addSortable(IndexField.Type.INTEGER, "severityValue"); public static final IndexField LANGUAGE = add(IndexField.Type.STRING, "language"); + public static final IndexField TAGS = add(IndexField.Type.STRING, "tags"); public static final IndexField RULE_KEY = add(IndexField.Type.STRING, "ruleKey"); public static final IndexField FILE_PATH = addSortable(IndexField.Type.STRING, "filePath"); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java index a637aadd4b6..5be67c9b8d8 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java @@ -64,7 +64,13 @@ import org.sonar.server.user.UserSession; import javax.annotation.CheckForNull; import javax.annotation.Nullable; -import java.util.*; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Set; import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Maps.newHashMap; @@ -167,6 +173,9 @@ public class SearchAction extends SearchRequestHandler { action.createParam(IssueFilterParameters.RULES) .setDescription("Comma-separated list of coding rule keys. Format is :") .setExampleValue("squid:AvoidCycles"); + action.createParam(IssueFilterParameters.TAGS) + .setDescription("Comma-separated list of tags.") + .setExampleValue("security,convention"); action.createParam(IssueFilterParameters.HIDE_RULES) .setDescription("To not return rules") .setDefaultValue(false) @@ -250,7 +259,8 @@ public class SearchAction extends SearchRequestHandler { IssueFilterParameters.ASSIGNEES, IssueFilterParameters.REPORTERS, IssueFilterParameters.COMPONENT_UUIDS, - IssueFilterParameters.LANGUAGES + IssueFilterParameters.LANGUAGES, + IssueFilterParameters.TAGS, }); } @@ -373,6 +383,7 @@ public class SearchAction extends SearchRequestHandler { addMandatoryFacetValues(results, IssueFilterParameters.REPORTERS, request.paramAsStrings(IssueFilterParameters.REPORTERS)); addMandatoryFacetValues(results, IssueFilterParameters.RULES, request.paramAsStrings(IssueFilterParameters.RULES)); addMandatoryFacetValues(results, IssueFilterParameters.LANGUAGES, request.paramAsStrings(IssueFilterParameters.LANGUAGES)); + addMandatoryFacetValues(results, IssueFilterParameters.TAGS, request.paramAsStrings(IssueFilterParameters.TAGS)); List actionPlans = Lists.newArrayList(""); List actionPlansFromRequest = request.paramAsStrings(IssueFilterParameters.ACTION_PLANS); if (actionPlansFromRequest != null) { @@ -512,6 +523,15 @@ public class SearchAction extends SearchRequestHandler { .prop("fUpdateAge", formatAgeDate(updateDate)) .prop("closeDate", isoDate(issue.closeDate())); + Collection tags = ((IssueDoc) issue).tags(); + if (tags != null && !tags.isEmpty()) { + json.name("tags").beginArray(); + for (String tag: tags) { + json.value(tag); + } + json.endArray(); + } + writeIssueComments(commentsByIssues.get(issue.key()), usersByLogin, json); writeIssueAttributes(issue, json); writeIssueExtraFields(issue, project != null ? project.getKey() : null, usersByLogin, actionPlanByKeys, extraFields, json); diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryServiceTest.java index 2a472eef843..5f13bb3ea6e 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryServiceTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryServiceTest.java @@ -75,6 +75,7 @@ public class IssueQueryServiceTest { map.put("reporters", newArrayList("marilyn")); map.put("assignees", newArrayList("joanna")); map.put("languages", newArrayList("xoo")); + map.put("tags", newArrayList("tag1", "tag2")); map.put("assigned", true); map.put("planned", true); map.put("hideRules", true); @@ -98,6 +99,7 @@ public class IssueQueryServiceTest { assertThat(query.reporters()).containsOnly("marilyn"); assertThat(query.assignees()).containsOnly("joanna"); assertThat(query.languages()).containsOnly("xoo"); + assertThat(query.tags()).containsOnly("tag1", "tag2"); assertThat(query.assigned()).isTrue(); assertThat(query.planned()).isTrue(); assertThat(query.hideRules()).isTrue(); diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryTest.java index e06c6d3d4b7..ff23362a5f7 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryTest.java @@ -46,6 +46,7 @@ public class IssueQueryTest { .reporters(newArrayList("crunky")) .assignees(newArrayList("gargantua")) .languages(newArrayList("xoo")) + .tags(newArrayList("tag1", "tag2")) .assigned(true) .hideRules(true) .createdAfter(new Date()) @@ -65,6 +66,7 @@ public class IssueQueryTest { assertThat(query.reporters()).containsOnly("crunky"); assertThat(query.assignees()).containsOnly("gargantua"); assertThat(query.languages()).containsOnly("xoo"); + assertThat(query.tags()).containsOnly("tag1", "tag2"); assertThat(query.assigned()).isTrue(); assertThat(query.hideRules()).isTrue(); assertThat(query.rules()).containsOnly(RuleKey.of("squid", "AvoidCycle")); @@ -118,6 +120,7 @@ public class IssueQueryTest { .rules(null) .severities(null) .languages(null) + .tags(null) .build(); assertThat(query.issueKeys()).isEmpty(); assertThat(query.componentUuids()).isEmpty(); @@ -130,6 +133,7 @@ public class IssueQueryTest { assertThat(query.rules()).isEmpty(); assertThat(query.severities()).isEmpty(); assertThat(query.languages()).isEmpty(); + assertThat(query.tags()).isEmpty(); } @Test @@ -146,6 +150,7 @@ public class IssueQueryTest { assertThat(query.rules()).isEmpty(); assertThat(query.severities()).isEmpty(); assertThat(query.languages()).isEmpty(); + assertThat(query.tags()).isEmpty(); assertThat(query.assigned()).isNull(); assertThat(query.createdAfter()).isNull(); assertThat(query.createdBefore()).isNull(); diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java index 5ea03bc325f..67efbf1325e 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java @@ -132,7 +132,7 @@ public class SearchActionMediumTest { assertThat(show.isPost()).isFalse(); assertThat(show.isInternal()).isFalse(); assertThat(show.responseExampleAsString()).isNotEmpty(); - assertThat(show.params()).hasSize(31); + assertThat(show.params()).hasSize(32); } @Test -- 2.39.5