]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-10313 Use issue ID for ES ISSUES.ISSUE
authorEric Hartmann <hartmann.eric@gmail.com>
Fri, 26 Jan 2018 09:22:50 +0000 (10:22 +0100)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Thu, 8 Feb 2018 12:41:00 +0000 (13:41 +0100)
Previously RuleKey was used, in order to allow renaming of the key
we must store the ID of the rule.

18 files changed:
server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDao.java
server/sonar-server/src/main/java/org/sonar/server/issue/IssueQuery.java
server/sonar-server/src/main/java/org/sonar/server/issue/IssueQueryFactory.java
server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueDoc.java
server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java
server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java
server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java
server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java
server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchResponseLoader.java
server/sonar-server/src/test/java/org/sonar/server/issue/IssueDocTesting.java
server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryFactoryTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexDebtTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIteratorFactoryTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionComponentsTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionTest.java
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/result_for_rule_search.json [new file with mode: 0644]

index bd02532869b57600aecf7732a679d0d21df5d072..7989e98e3b848848ced49fd890d50eb35702bb28 100644 (file)
@@ -87,7 +87,7 @@ public class RuleDao implements Dao {
       executeLargeInputs(ids, chunk -> mapper(session).selectByIds(organizationUuid, chunk)));
   }
 
-  public List<RuleDefinitionDto> selectDefinitionByIds(DbSession session, List<Integer> ids) {
+  public List<RuleDefinitionDto> selectDefinitionByIds(DbSession session, Collection<Integer> ids) {
     return executeLargeInputs(ids, mapper(session)::selectDefinitionByIds);
   }
 
index b8379edacd3fe2faea7c8385097f1fee19378f36..fd3508f252d17e7957a54eeee87521d6e0755091 100644 (file)
@@ -28,7 +28,6 @@ import java.util.Set;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 import org.apache.commons.lang.builder.ReflectionToStringBuilder;
-import org.sonar.api.rule.RuleKey;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static org.sonar.server.es.SearchOptions.MAX_LIMIT;
@@ -64,7 +63,7 @@ public class IssueQuery {
   private final Collection<String> directories;
   private final Collection<String> files;
   private final Collection<String> views;
-  private final Collection<RuleKey> rules;
+  private final Collection<Integer> rules;
   private final Collection<String> assignees;
   private final Collection<String> authors;
   private final Collection<String> languages;
@@ -163,7 +162,7 @@ public class IssueQuery {
     return views;
   }
 
-  public Collection<RuleKey> rules() {
+  public Collection<Integer> rules() {
     return rules;
   }
 
@@ -274,7 +273,7 @@ public class IssueQuery {
     private Collection<String> directories;
     private Collection<String> files;
     private Collection<String> views;
-    private Collection<RuleKey> rules;
+    private Collection<Integer> rules;
     private Collection<String> assignees;
     private Collection<String> authors;
     private Collection<String> languages;
@@ -354,7 +353,7 @@ public class IssueQuery {
       return this;
     }
 
-    public Builder rules(@Nullable Collection<RuleKey> rules) {
+    public Builder rules(@Nullable Collection<Integer> rules) {
       this.rules = rules;
       return this;
     }
index 8af0aff307a7324aed40d79bbc190ba1f80d6817..5eea597845c376562315343ad767ef1779136631 100644 (file)
  */
 package org.sonar.server.issue;
 
-import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Joiner;
-import com.google.common.base.Splitter;
 import com.google.common.base.Strings;
-import com.google.common.collect.Collections2;
 import com.google.common.collect.Lists;
 import java.time.Clock;
 import java.time.OffsetDateTime;
@@ -47,16 +44,18 @@ import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.server.ServerSide;
 import org.sonar.api.web.UserRole;
+import org.sonar.core.util.stream.MoreCollectors;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.component.SnapshotDto;
 import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.rule.RuleDefinitionDto;
 import org.sonar.server.issue.IssueQuery.PeriodStart;
 import org.sonar.server.user.UserSession;
 
 import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.collect.Lists.newArrayList;
+import static com.google.common.collect.Collections2.transform;
 import static java.lang.String.format;
 import static java.util.Collections.singleton;
 import static java.util.Collections.singletonList;
@@ -107,7 +106,7 @@ public class IssueQueryFactory {
         .statuses(request.getStatuses())
         .resolutions(request.getResolutions())
         .resolved(request.getResolved())
-        .rules(stringsToRules(request.getRules()))
+        .rules(ruleKeysToRuleId(dbSession, request.getRules()))
         .assignees(buildAssignees(request.getAssignees()))
         .languages(request.getLanguages())
         .tags(request.getTags())
@@ -364,24 +363,13 @@ public class IssueQueryFactory {
     return componentDtos;
   }
 
-  @VisibleForTesting
-  static Collection<RuleKey> toRules(@Nullable Object o) {
-    Collection<RuleKey> result = null;
-    if (o != null) {
-      if (o instanceof List) {
-        // assume that it contains only strings
-        result = stringsToRules((List<String>) o);
-      } else if (o instanceof String) {
-        result = stringsToRules(newArrayList(Splitter.on(',').omitEmptyStrings().split((String) o)));
-      }
-    }
-    return result;
-  }
-
   @CheckForNull
-  private static Collection<RuleKey> stringsToRules(@Nullable Collection<String> rules) {
+  private Collection<Integer> ruleKeysToRuleId(DbSession dbSession, @Nullable Collection<String> rules) {
     if (rules != null) {
-      return Collections2.transform(rules, RuleKey::parse);
+      return dbClient.ruleDao().selectDefinitionByKeys(dbSession, transform(rules, RuleKey::parse))
+        .stream()
+        .map(RuleDefinitionDto::getId)
+        .collect(MoreCollectors.toList());
     }
     return null;
   }
index 4d617040d6d9b879c86600a4f3345d0a9fda1e0e..69f45aff4345d09a4fc69fa0519c584df6a4433a 100644 (file)
@@ -25,7 +25,6 @@ import java.util.Date;
 import java.util.Map;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
-import org.sonar.api.rule.RuleKey;
 import org.sonar.api.rule.Severity;
 import org.sonar.api.rules.RuleType;
 import org.sonar.api.utils.Duration;
@@ -85,8 +84,8 @@ public class IssueDoc extends BaseDoc {
     return getField(IssueIndexDefinition.FIELD_ISSUE_IS_MAIN_BRANCH);
   }
 
-  public RuleKey ruleKey() {
-    return RuleKey.parse(getField(IssueIndexDefinition.FIELD_ISSUE_RULE_KEY));
+  public Integer ruleId() {
+    return getField(IssueIndexDefinition.FIELD_ISSUE_RULE_ID);
   }
 
   public String language() {
@@ -195,8 +194,8 @@ public class IssueDoc extends BaseDoc {
     return this;
   }
 
-  public IssueDoc setRuleKey(@Nullable String s) {
-    setField(IssueIndexDefinition.FIELD_ISSUE_RULE_KEY, s);
+  public IssueDoc setRuleId(Integer s) {
+    setField(IssueIndexDefinition.FIELD_ISSUE_RULE_ID, s);
     return this;
   }
 
index 2b23343f6ddc71d771463ec7c825182fb6e0fe6b..eba5e6f4c3383ccdacb6634439999f7813e03404 100644 (file)
@@ -409,8 +409,7 @@ public class IssueIndex {
     filters.put(IssueIndexDefinition.FIELD_ISSUE_TYPE, createTermsFilter(IssueIndexDefinition.FIELD_ISSUE_TYPE, query.types()));
     filters.put(IssueIndexDefinition.FIELD_ISSUE_RESOLUTION, createTermsFilter(IssueIndexDefinition.FIELD_ISSUE_RESOLUTION, query.resolutions()));
     filters.put(IssueIndexDefinition.FIELD_ISSUE_AUTHOR_LOGIN, createTermsFilter(IssueIndexDefinition.FIELD_ISSUE_AUTHOR_LOGIN, query.authors()));
-    filters.put(IssueIndexDefinition.FIELD_ISSUE_RULE_KEY, createTermsFilter(IssueIndexDefinition.FIELD_ISSUE_RULE_KEY,
-      query.rules().stream().map(String::valueOf).collect(MoreCollectors.toList(query.rules().size()))));
+    filters.put(IssueIndexDefinition.FIELD_ISSUE_RULE_ID, createTermsFilter(IssueIndexDefinition.FIELD_ISSUE_RULE_ID, query.rules()));
     filters.put(IssueIndexDefinition.FIELD_ISSUE_SEVERITY, createTermsFilter(IssueIndexDefinition.FIELD_ISSUE_SEVERITY, query.severities()));
     filters.put(IssueIndexDefinition.FIELD_ISSUE_STATUS, createTermsFilter(IssueIndexDefinition.FIELD_ISSUE_STATUS, query.statuses()));
     filters.put(IssueIndexDefinition.FIELD_ISSUE_ORGANIZATION_UUID, createTermFilter(IssueIndexDefinition.FIELD_ISSUE_ORGANIZATION_UUID, query.organizationUuid()));
@@ -484,7 +483,7 @@ public class IssueIndex {
       addSimpleStickyFacetIfNeeded(options, stickyFacetBuilder, esSearch,
         PARAM_LANGUAGES, IssueIndexDefinition.FIELD_ISSUE_LANGUAGE, query.languages().toArray());
       addSimpleStickyFacetIfNeeded(options, stickyFacetBuilder, esSearch,
-        PARAM_RULES, IssueIndexDefinition.FIELD_ISSUE_RULE_KEY, query.rules().toArray());
+        PARAM_RULES, IssueIndexDefinition.FIELD_ISSUE_RULE_ID, query.rules().toArray());
 
       addSimpleStickyFacetIfNeeded(options, stickyFacetBuilder, esSearch,
         PARAM_AUTHORS, IssueIndexDefinition.FIELD_ISSUE_AUTHOR_LOGIN, query.authors().toArray());
index 6a59e2f27514c7b9b0ff7c5a22bdaf0713281165..3521b7056720549748358d38a178d4c67964ec22 100644 (file)
@@ -86,7 +86,7 @@ public class IssueIndexDefinition implements IndexDefinition {
 
   public static final String FIELD_ISSUE_DIRECTORY_PATH = "dirPath";
   public static final String FIELD_ISSUE_RESOLUTION = "resolution";
-  public static final String FIELD_ISSUE_RULE_KEY = "ruleKey";
+  public static final String FIELD_ISSUE_RULE_ID = "ruleId";
   public static final String FIELD_ISSUE_SEVERITY = "severity";
   public static final String FIELD_ISSUE_SEVERITY_VALUE = "severityValue";
   public static final String FIELD_ISSUE_STATUS = "status";
@@ -146,7 +146,7 @@ public class IssueIndexDefinition implements IndexDefinition {
     type.createBooleanField(FIELD_ISSUE_IS_MAIN_BRANCH);
     type.keywordFieldBuilder(FIELD_ISSUE_DIRECTORY_PATH).disableNorms().build();
     type.keywordFieldBuilder(FIELD_ISSUE_RESOLUTION).disableNorms().build();
-    type.keywordFieldBuilder(FIELD_ISSUE_RULE_KEY).disableNorms().build();
+    type.keywordFieldBuilder(FIELD_ISSUE_RULE_ID).disableNorms().build();
     type.keywordFieldBuilder(FIELD_ISSUE_SEVERITY).disableNorms().build();
     type.createByteField(FIELD_ISSUE_SEVERITY_VALUE);
     type.keywordFieldBuilder(FIELD_ISSUE_STATUS).disableNorms().addSubFields(SORTABLE_ANALYZER).build();
index e9c5df9e18ddf223237b49d64c12652785c8e274..ee1ec7950a9e3b94d407df05d2cd18473f01ebdc 100644 (file)
@@ -34,7 +34,6 @@ import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 import org.apache.commons.lang.StringUtils;
 import org.sonar.api.resources.Scopes;
-import org.sonar.api.rule.RuleKey;
 import org.sonar.api.rules.RuleType;
 import org.sonar.db.DatabaseUtils;
 import org.sonar.db.DbClient;
@@ -66,8 +65,7 @@ class IssueIteratorForSingleChunk implements IssueIterator {
 
     // column 11
     "i.issue_update_date",
-    "r.plugin_name",
-    "r.plugin_rule_key",
+    "r.id",
     "r.language",
     "c.uuid",
     "c.module_uuid_path",
@@ -200,21 +198,20 @@ class IssueIteratorForSingleChunk implements IssueIterator {
       doc.setFuncCloseDate(longToDate(getLong(rs, 9)));
       doc.setFuncCreationDate(longToDate(getLong(rs, 10)));
       doc.setFuncUpdateDate(longToDate(getLong(rs, 11)));
-      String ruleRepo = rs.getString(12);
-      String ruleKey = rs.getString(13);
-      doc.setRuleKey(RuleKey.of(ruleRepo, ruleKey).toString());
-      doc.setLanguage(rs.getString(14));
-      doc.setComponentUuid(rs.getString(15));
-      String moduleUuidPath = rs.getString(16);
+      Integer ruleId = rs.getInt(12);
+      doc.setRuleId(ruleId);
+      doc.setLanguage(rs.getString(13));
+      doc.setComponentUuid(rs.getString(14));
+      String moduleUuidPath = rs.getString(15);
       doc.setModuleUuid(extractModule(moduleUuidPath));
       doc.setModuleUuidPath(moduleUuidPath);
-      String scope = rs.getString(18);
-      String filePath = extractFilePath(rs.getString(17), scope);
+      String scope = rs.getString(17);
+      String filePath = extractFilePath(rs.getString(16), scope);
       doc.setFilePath(filePath);
       doc.setDirectoryPath(extractDirPath(doc.filePath(), scope));
-      doc.setOrganizationUuid(rs.getString(19));
-      String branchUuid = rs.getString(20);
-      String mainBranchProjectUuid = DatabaseUtils.getString(rs, 21);
+      doc.setOrganizationUuid(rs.getString(18));
+      String branchUuid = rs.getString(19);
+      String mainBranchProjectUuid = DatabaseUtils.getString(rs, 20);
       doc.setBranchUuid(branchUuid);
       if (mainBranchProjectUuid == null) {
         doc.setProjectUuid(branchUuid);
@@ -223,9 +220,9 @@ class IssueIteratorForSingleChunk implements IssueIterator {
         doc.setProjectUuid(mainBranchProjectUuid);
         doc.setIsMainBranch(false);
       }
-      String tags = rs.getString(22);
+      String tags = rs.getString(21);
       doc.setTags(ImmutableList.copyOf(IssueIteratorForSingleChunk.TAGS_SPLITTER.split(tags == null ? "" : tags)));
-      doc.setType(RuleType.valueOf(rs.getInt(23)));
+      doc.setType(RuleType.valueOf(rs.getInt(22)));
       return doc;
     }
 
index 7b74faaf2d40c6cb34cc0f6257e9694418f4246c..a0a9b33a0abb7ed2c8992476e4d1589c117b8f66 100644 (file)
@@ -29,6 +29,7 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
 import javax.annotation.Nullable;
 import org.elasticsearch.action.search.SearchResponse;
 import org.elasticsearch.search.SearchHit;
@@ -43,15 +44,20 @@ import org.sonar.api.server.ws.WebService;
 import org.sonar.api.server.ws.WebService.Param;
 import org.sonar.api.utils.Paging;
 import org.sonar.api.utils.System2;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
 import org.sonar.core.util.stream.MoreCollectors;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.rule.RuleDefinitionDto;
 import org.sonar.server.es.Facets;
 import org.sonar.server.es.SearchOptions;
 import org.sonar.server.issue.IssueQuery;
 import org.sonar.server.issue.IssueQueryFactory;
+import org.sonar.server.issue.SearchRequest;
 import org.sonar.server.issue.index.IssueIndex;
 import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.Issues.SearchWsResponse;
-import org.sonar.server.issue.SearchRequest;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.collect.Iterables.concat;
@@ -112,6 +118,7 @@ public class SearchAction implements IssuesWsAction {
   private static final Set<String> IGNORED_FACETS = newHashSet(PARAM_PLANNED, DEPRECATED_PARAM_ACTION_PLANS, PARAM_REPORTERS);
   private static final Set<String> FACETS_REQUIRING_PROJECT_OR_ORGANIZATION = newHashSet(PARAM_FILE_UUIDS, PARAM_DIRECTORIES, PARAM_MODULE_UUIDS);
   private static final Joiner COMA_JOINER = Joiner.on(",");
+  private static final Logger LOGGER = Loggers.get(SearchAction.class);
 
   private final UserSession userSession;
   private final IssueIndex issueIndex;
@@ -119,15 +126,18 @@ public class SearchAction implements IssuesWsAction {
   private final SearchResponseLoader searchResponseLoader;
   private final SearchResponseFormat searchResponseFormat;
   private final System2 system2;
+  private final DbClient dbClient;
 
   public SearchAction(UserSession userSession, IssueIndex issueIndex, IssueQueryFactory issueQueryFactory,
-    SearchResponseLoader searchResponseLoader, SearchResponseFormat searchResponseFormat, System2 system2) {
+    SearchResponseLoader searchResponseLoader, SearchResponseFormat searchResponseFormat, System2 system2,
+    DbClient dbClient) {
     this.userSession = userSession;
     this.issueIndex = issueIndex;
     this.issueQueryFactory = issueQueryFactory;
     this.searchResponseLoader = searchResponseLoader;
     this.searchResponseFormat = searchResponseFormat;
     this.system2 = system2;
+    this.dbClient = dbClient;
   }
 
   @Override
@@ -359,6 +369,7 @@ public class SearchAction implements IssuesWsAction {
     // Must be done after loading of data as the "hidden" facet "debt"
     // can be used to get total debt.
     facets = reorderFacets(facets, options.getFacets());
+    replaceRuleIdsByRuleKeys(facets);
 
     // FIXME allow long in Paging
     Paging paging = forPageIndex(options.getPage()).withPageSize(options.getLimit()).andTotal((int) result.getHits().getTotalHits());
@@ -366,6 +377,35 @@ public class SearchAction implements IssuesWsAction {
     return searchResponseFormat.formatSearch(additionalFields, data, paging, facets);
   }
 
+  private void replaceRuleIdsByRuleKeys(@Nullable Facets facets) {
+    if (facets == null || facets.get(PARAM_RULES) == null) {
+      return;
+    }
+    // The facet for PARAM_RULES contains the id of the rule as the key
+    // We need to update the key to be a RuleKey
+    LinkedHashMap<String, Long> rulesFacet = facets.get(PARAM_RULES);
+
+    try (DbSession dbSession = dbClient.openSession(false)) {
+      Map<Integer, RuleKey> idToRuleKey = dbClient.ruleDao()
+        .selectDefinitionByIds(dbSession, Collections2.transform(rulesFacet.keySet(), Integer::parseInt))
+        .stream()
+        .collect(Collectors.toMap(RuleDefinitionDto::getId, RuleDefinitionDto::getKey));
+
+      LinkedHashMap<String, Long> newRulesFacet = new LinkedHashMap<>();
+      rulesFacet.forEach((k, v) -> {
+        RuleKey ruleKey = idToRuleKey.get(Integer.parseInt(k));
+        if (ruleKey != null) {
+          newRulesFacet.put(ruleKey.toString(), v);
+        } else {
+          // RuleKey not found ES/DB incorrect?
+          LOGGER.error("Rule with id {} is not available in database", k);
+        }
+      });
+      rulesFacet.clear();
+      rulesFacet.putAll(newRulesFacet);
+    }
+  }
+
   private static SearchOptions createSearchOptionsFromRequest(SearchRequest request) {
     SearchOptions options = new SearchOptions();
     options.setPage(request.getPage(), request.getPageSize());
@@ -448,7 +488,7 @@ public class SearchAction implements IssuesWsAction {
   private static void collectFacets(SearchResponseLoader.Collector collector, Facets facets) {
     Set<String> facetRules = facets.getBucketKeys(PARAM_RULES);
     if (facetRules != null) {
-      collector.addAll(SearchAdditionalField.RULES, Collections2.transform(facetRules, RuleKey::parse));
+      collector.addAll(SearchAdditionalField.RULES, facetRules);
     }
     collector.addProjectUuids(facets.getBucketKeys(PARAM_PROJECT_UUIDS));
     collector.addComponentUuids(facets.getBucketKeys(PARAM_COMPONENT_UUIDS));
index 440e2a00beb9ddde75b571c4b1372f1fa4b53eda..7647b198edb2d80c3c691b1493776a24d776f007 100644 (file)
@@ -222,7 +222,7 @@ public class SearchResponseLoader {
 
   private void loadRules(Collector collector, DbSession dbSession, SearchResponseData result) {
     if (collector.contains(RULES)) {
-      result.setRules(dbClient.ruleDao().selectDefinitionByKeys(dbSession, collector.getList(RULES)));
+      result.setRules(dbClient.ruleDao().selectDefinitionByIds(dbSession, collector.getList(RULES)));
     }
   }
 
@@ -311,7 +311,7 @@ public class SearchResponseLoader {
       for (IssueDto issue : issues) {
         componentUuids.add(issue.getComponentUuid());
         projectUuids.add(issue.getProjectUuid());
-        add(RULES, issue.getRuleKey());
+        add(RULES, issue.getRuleId());
         add(USERS, issue.getAssignee());
         collectComponentsFromIssueLocations(issue);
       }
index 2af1ac4b4d6e3c3fc00b31210e337a8c95960eb1..a7a02a3b744c0325b3e1c66b58b3bdcd7048c02f 100644 (file)
@@ -21,13 +21,11 @@ package org.sonar.server.issue;
 
 import com.google.common.collect.Maps;
 import java.util.Date;
-import org.apache.commons.lang.math.RandomUtils;
 import org.sonar.api.resources.Scopes;
 import org.sonar.api.rule.Severity;
 import org.sonar.api.rules.RuleType;
 import org.sonar.core.util.Uuids;
 import org.sonar.db.component.ComponentDto;
-import org.sonar.db.rule.RuleTesting;
 import org.sonar.server.issue.index.IssueDoc;
 
 import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
@@ -58,7 +56,7 @@ public class IssueDocTesting {
   public static IssueDoc newDoc() {
     IssueDoc doc = new IssueDoc(Maps.newHashMap());
     doc.setKey(Uuids.createFast());
-    doc.setRuleKey(RuleTesting.XOO_X1.toString());
+    doc.setRuleId(nextInt(1000));
     doc.setType(RuleType.CODE_SMELL);
     doc.setAssignee("assignee_" + randomAlphabetic(5));
     doc.setAuthorLogin("author_" + randomAlphabetic(5));
@@ -73,7 +71,7 @@ public class IssueDocTesting {
     doc.setStatus(STATUS_OPEN);
     doc.setResolution(null);
     doc.setSeverity(Severity.ALL.get(nextInt(Severity.ALL.size())));
-    doc.setEffort((long) RandomUtils.nextInt(10));
+    doc.setEffort((long) nextInt(10));
     doc.setFuncCreationDate(new Date(System.currentTimeMillis() - 2_000));
     doc.setFuncUpdateDate(new Date(System.currentTimeMillis() - 1_000));
     doc.setFuncCloseDate(null);
index 04e8edffc6100b035798b309f3cc2638f314d7e1..a7886ab7fd9c15abf1060b95f9c1725ed78a509a 100644 (file)
@@ -34,6 +34,8 @@ import org.sonar.db.DbTester;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.component.SnapshotDto;
 import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.rule.RuleDbTester;
+import org.sonar.db.rule.RuleDefinitionDto;
 import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.tester.UserSessionRule;
 
@@ -50,6 +52,7 @@ import static org.sonar.db.component.ComponentTesting.newFileDto;
 import static org.sonar.db.component.ComponentTesting.newModuleDto;
 import static org.sonar.db.component.ComponentTesting.newProjectCopy;
 import static org.sonar.db.component.ComponentTesting.newSubView;
+import static org.sonar.db.rule.RuleTesting.newRule;
 
 public class IssueQueryFactoryTest {
 
@@ -60,6 +63,8 @@ public class IssueQueryFactoryTest {
   @Rule
   public DbTester db = DbTester.create();
 
+  private RuleDbTester ruleDbTester = new RuleDbTester(db);
+
   private Clock clock = mock(Clock.class);
   private IssueQueryFactory underTest = new IssueQueryFactory(db.getDbClient(), clock, userSession);
 
@@ -70,6 +75,9 @@ public class IssueQueryFactoryTest {
     ComponentDto module = db.components().insertComponent(newModuleDto(project));
     ComponentDto file = db.components().insertComponent(newFileDto(project));
 
+    RuleDefinitionDto rule1 = ruleDbTester.insert();
+    RuleDefinitionDto rule2 = ruleDbTester.insert();
+    newRule(RuleKey.of("findbugs", "NullReference"));
     SearchRequest request = new SearchRequest()
       .setIssues(asList("anIssueKey"))
       .setSeverities(asList("MAJOR", "MINOR"))
@@ -87,7 +95,7 @@ public class IssueQueryFactoryTest {
       .setAssigned(true)
       .setCreatedAfter("2013-04-16T09:08:24+0200")
       .setCreatedBefore("2013-04-17T09:08:24+0200")
-      .setRules(asList("squid:AvoidCycle", "findbugs:NullReference"))
+      .setRules(asList(rule1.getKey().toString(), rule2.getKey().toString()))
       .setSort("CREATION_DATE")
       .setAsc(true);
 
@@ -198,15 +206,6 @@ public class IssueQueryFactoryTest {
     assertThat(query.branchUuid()).isNull();
   }
 
-  @Test
-  public void parse_list_of_rules() {
-    assertThat(IssueQueryFactory.toRules(null)).isNull();
-    assertThat(IssueQueryFactory.toRules("")).isEmpty();
-    assertThat(IssueQueryFactory.toRules("squid:AvoidCycle")).containsOnly(RuleKey.of("squid", "AvoidCycle"));
-    assertThat(IssueQueryFactory.toRules("squid:AvoidCycle,findbugs:NullRef")).containsOnly(RuleKey.of("squid", "AvoidCycle"), RuleKey.of("findbugs", "NullRef"));
-    assertThat(IssueQueryFactory.toRules(asList("squid:AvoidCycle", "findbugs:NullRef"))).containsOnly(RuleKey.of("squid", "AvoidCycle"), RuleKey.of("findbugs", "NullRef"));
-  }
-
   @Test
   public void fail_if_components_and_components_uuid_params_are_set_at_the_same_time() {
     SearchRequest request = new SearchRequest()
index ab5d9d6f0c918a1ac6f4017c4a3daf007fa1e0d9..8c89d26a8a96576643737f376944df88687d9235 100644 (file)
@@ -24,11 +24,11 @@ import com.google.common.collect.Lists;
 import java.util.Date;
 import org.junit.Test;
 import org.sonar.api.issue.Issue;
-import org.sonar.api.rule.RuleKey;
 import org.sonar.api.rule.Severity;
 import org.sonar.server.issue.IssueQuery.PeriodStart;
 
 import static com.google.common.collect.Lists.newArrayList;
+import static org.apache.commons.lang.math.RandomUtils.nextInt;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.entry;
 
@@ -36,6 +36,7 @@ public class IssueQueryTest {
 
   @Test
   public void build_query() {
+    int ruleId = nextInt(1000);
     PeriodStart filterDate = new IssueQuery.PeriodStart(new Date(10_000_000_000L),false);
     IssueQuery query = IssueQuery.builder()
       .issueKeys(newArrayList("ABCDE"))
@@ -45,7 +46,7 @@ public class IssueQueryTest {
       .projectUuids(newArrayList("PROJECT"))
       .componentUuids(newArrayList("org/struts/Action.java"))
       .moduleUuids(newArrayList("org.struts:core"))
-      .rules(newArrayList(RuleKey.of("squid", "AvoidCycle")))
+      .rules(newArrayList(ruleId))
       .assignees(newArrayList("gargantua"))
       .languages(newArrayList("xoo"))
       .tags(newArrayList("tag1", "tag2"))
@@ -76,7 +77,7 @@ public class IssueQueryTest {
     assertThat(query.branchUuid()).isEqualTo("my_branch");
     assertThat(query.createdAfterByProjectUuids()).containsOnly(entry("PROJECT", filterDate));
     assertThat(query.assigned()).isTrue();
-    assertThat(query.rules()).containsOnly(RuleKey.of("squid", "AvoidCycle"));
+    assertThat(query.rules()).containsOnly(ruleId);
     assertThat(query.createdAfter()).isNotNull();
     assertThat(query.createdBefore()).isNotNull();
     assertThat(query.createdAt()).isNotNull();
index c0e189394687f3cedef2f13efd282d0e58d2dd27..d518666c8236bd6caf1b19cdb4fa9ee30e69ea6b 100644 (file)
@@ -183,7 +183,7 @@ public class IssueIndexDebtTest {
     ComponentDto file = ComponentTesting.newFileDto(project, null);
     RuleKey ruleKey = RuleKey.of("repo", "X1");
 
-    indexIssues(IssueDocTesting.newDoc("I1", file).setRuleKey(ruleKey.toString()).setLanguage("xoo").setEffort(10L));
+    indexIssues(IssueDocTesting.newDoc("I1", file).setLanguage("xoo").setEffort(10L));
 
     Facets facets = search("languages");
     assertThat(facets.getNames()).containsOnly("languages", FACET_MODE_EFFORT);
index 3f4f70dc8a3b542c39aa4617e085b6e0e52fac49..70767cbf4054ab23b273d9eb939e013f672148d3 100644 (file)
@@ -39,13 +39,11 @@ import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.config.internal.MapSettings;
 import org.sonar.api.issue.Issue;
-import org.sonar.api.rule.RuleKey;
 import org.sonar.api.rule.Severity;
 import org.sonar.api.utils.System2;
 import org.sonar.api.utils.internal.TestSystem2;
 import org.sonar.db.DbTester;
 import org.sonar.db.component.ComponentDto;
-import org.sonar.db.component.ComponentTesting;
 import org.sonar.db.organization.OrganizationDto;
 import org.sonar.db.rule.RuleDefinitionDto;
 import org.sonar.db.user.GroupDto;
@@ -82,6 +80,7 @@ import static org.sonar.db.component.ComponentTesting.newFileDto;
 import static org.sonar.db.component.ComponentTesting.newModuleDto;
 import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
 import static org.sonar.db.organization.OrganizationTesting.newOrganizationDto;
+import static org.sonar.db.rule.RuleTesting.newRule;
 import static org.sonar.db.user.GroupTesting.newGroupDto;
 import static org.sonar.db.user.UserTesting.newUserDto;
 import static org.sonar.server.issue.IssueDocTesting.newDoc;
@@ -111,20 +110,20 @@ public class IssueIndexTest {
 
   @Test
   public void filter_by_keys() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
 
     indexIssues(
       newDoc("I1", newFileDto(project, null)),
       newDoc("I2", newFileDto(project, null)));
 
     assertThatSearchReturnsOnly(IssueQuery.builder().issueKeys(asList("I1", "I2")), "I1", "I2");
-    assertThatSearchReturnsOnly(IssueQuery.builder().issueKeys(asList("I1")), "I1");
+    assertThatSearchReturnsOnly(IssueQuery.builder().issueKeys(singletonList("I1")), "I1");
     assertThatSearchReturnsEmpty(IssueQuery.builder().issueKeys(asList("I3", "I4")));
   }
 
   @Test
   public void filter_by_projects() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto module = newModuleDto(project);
     ComponentDto subModule = newModuleDto(module);
 
@@ -136,8 +135,8 @@ public class IssueIndexTest {
       newDoc("I5", subModule),
       newDoc("I6", newFileDto(subModule, null)));
 
-    assertThatSearchReturnsOnly(IssueQuery.builder().projectUuids(asList(project.uuid())), "I1", "I2", "I3", "I4", "I5", "I6");
-    assertThatSearchReturnsEmpty(IssueQuery.builder().projectUuids(asList("unknown")));
+    assertThatSearchReturnsOnly(IssueQuery.builder().projectUuids(singletonList(project.uuid())), "I1", "I2", "I3", "I4", "I5", "I6");
+    assertThatSearchReturnsEmpty(IssueQuery.builder().projectUuids(singletonList("unknown")));
   }
 
   @Test
@@ -156,7 +155,7 @@ public class IssueIndexTest {
 
   @Test
   public void filter_by_modules() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto module = newModuleDto(project);
     ComponentDto subModule = newModuleDto(module);
     ComponentDto file = newFileDto(subModule, null);
@@ -166,16 +165,16 @@ public class IssueIndexTest {
       newDoc("I5", subModule),
       newDoc("I2", file));
 
-    assertThatSearchReturnsEmpty(IssueQuery.builder().projectUuids(asList(project.uuid())).moduleUuids(asList(file.uuid())));
-    assertThatSearchReturnsOnly(IssueQuery.builder().projectUuids(asList(project.uuid())).moduleUuids(asList(module.uuid())), "I3");
-    assertThatSearchReturnsOnly(IssueQuery.builder().projectUuids(asList(project.uuid())).moduleUuids(asList(subModule.uuid())), "I2", "I5");
-    assertThatSearchReturnsEmpty(IssueQuery.builder().projectUuids(asList(project.uuid())).moduleUuids(asList(project.uuid())));
-    assertThatSearchReturnsEmpty(IssueQuery.builder().projectUuids(asList(project.uuid())).moduleUuids(asList("unknown")));
+    assertThatSearchReturnsEmpty(IssueQuery.builder().projectUuids(singletonList(project.uuid())).moduleUuids(singletonList(file.uuid())));
+    assertThatSearchReturnsOnly(IssueQuery.builder().projectUuids(singletonList(project.uuid())).moduleUuids(singletonList(module.uuid())), "I3");
+    assertThatSearchReturnsOnly(IssueQuery.builder().projectUuids(singletonList(project.uuid())).moduleUuids(singletonList(subModule.uuid())), "I2", "I5");
+    assertThatSearchReturnsEmpty(IssueQuery.builder().projectUuids(singletonList(project.uuid())).moduleUuids(singletonList(project.uuid())));
+    assertThatSearchReturnsEmpty(IssueQuery.builder().projectUuids(singletonList(project.uuid())).moduleUuids(singletonList("unknown")));
   }
 
   @Test
   public void filter_by_components_on_contextualized_search() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto module = newModuleDto(project);
     ComponentDto subModule = newModuleDto(module);
     ComponentDto file1 = newFileDto(project, null);
@@ -193,12 +192,12 @@ public class IssueIndexTest {
       newDoc("I6", file3));
 
     assertThatSearchReturnsOnly(IssueQuery.builder().fileUuids(asList(file1.uuid(), file2.uuid(), file3.uuid())), "I2", "I4", "I6");
-    assertThatSearchReturnsOnly(IssueQuery.builder().fileUuids(asList(file1.uuid())), "I2");
-    assertThatSearchReturnsOnly(IssueQuery.builder().moduleRootUuids(asList(subModule.uuid())), "I5", "I6");
-    assertThatSearchReturnsOnly(IssueQuery.builder().moduleRootUuids(asList(module.uuid())), "I3", "I4", "I5", "I6");
-    assertThatSearchReturnsOnly(IssueQuery.builder().projectUuids(asList(project.uuid())), "I1", "I2", "I3", "I4", "I5", "I6");
-    assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(asList(view)), "I1", "I2", "I3", "I4", "I5", "I6");
-    assertThatSearchReturnsEmpty(IssueQuery.builder().projectUuids(asList("unknown")));
+    assertThatSearchReturnsOnly(IssueQuery.builder().fileUuids(singletonList(file1.uuid())), "I2");
+    assertThatSearchReturnsOnly(IssueQuery.builder().moduleRootUuids(singletonList(subModule.uuid())), "I5", "I6");
+    assertThatSearchReturnsOnly(IssueQuery.builder().moduleRootUuids(singletonList(module.uuid())), "I3", "I4", "I5", "I6");
+    assertThatSearchReturnsOnly(IssueQuery.builder().projectUuids(singletonList(project.uuid())), "I1", "I2", "I3", "I4", "I5", "I6");
+    assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(singletonList(view)), "I1", "I2", "I3", "I4", "I5", "I6");
+    assertThatSearchReturnsEmpty(IssueQuery.builder().projectUuids(singletonList("unknown")));
   }
 
   @Test
@@ -220,12 +219,12 @@ public class IssueIndexTest {
       newDoc("I5", subModule),
       newDoc("I6", file3));
 
-    assertThatSearchReturnsEmpty(IssueQuery.builder().projectUuids(asList("unknown")));
-    assertThatSearchReturnsOnly(IssueQuery.builder().projectUuids(asList(project.uuid())), "I1", "I2", "I3", "I4", "I5", "I6");
-    assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(asList(view)), "I1", "I2", "I3", "I4", "I5", "I6");
-    assertThatSearchReturnsOnly(IssueQuery.builder().moduleUuids(asList(module.uuid())), "I3", "I4");
-    assertThatSearchReturnsOnly(IssueQuery.builder().moduleUuids(asList(subModule.uuid())), "I5", "I6");
-    assertThatSearchReturnsOnly(IssueQuery.builder().fileUuids(asList(file1.uuid())), "I2");
+    assertThatSearchReturnsEmpty(IssueQuery.builder().projectUuids(singletonList("unknown")));
+    assertThatSearchReturnsOnly(IssueQuery.builder().projectUuids(singletonList(project.uuid())), "I1", "I2", "I3", "I4", "I5", "I6");
+    assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(singletonList(view)), "I1", "I2", "I3", "I4", "I5", "I6");
+    assertThatSearchReturnsOnly(IssueQuery.builder().moduleUuids(singletonList(module.uuid())), "I3", "I4");
+    assertThatSearchReturnsOnly(IssueQuery.builder().moduleUuids(singletonList(subModule.uuid())), "I5", "I6");
+    assertThatSearchReturnsOnly(IssueQuery.builder().fileUuids(singletonList(file1.uuid())), "I2");
     assertThatSearchReturnsOnly(IssueQuery.builder().fileUuids(asList(file1.uuid(), file2.uuid(), file3.uuid())), "I2", "I4", "I6");
   }
 
@@ -248,7 +247,7 @@ public class IssueIndexTest {
 
   @Test
   public void filter_by_directories() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file1 = newFileDto(project, null).setPath("src/main/xoo/F1.xoo");
     ComponentDto file2 = newFileDto(project, null).setPath("F2.xoo");
 
@@ -256,14 +255,14 @@ public class IssueIndexTest {
       newDoc("I1", file1).setDirectoryPath("/src/main/xoo"),
       newDoc("I2", file2).setDirectoryPath("/"));
 
-    assertThatSearchReturnsOnly(IssueQuery.builder().directories(asList("/src/main/xoo")), "I1");
-    assertThatSearchReturnsOnly(IssueQuery.builder().directories(asList("/")), "I2");
-    assertThatSearchReturnsEmpty(IssueQuery.builder().directories(asList("unknown")));
+    assertThatSearchReturnsOnly(IssueQuery.builder().directories(singletonList("/src/main/xoo")), "I1");
+    assertThatSearchReturnsOnly(IssueQuery.builder().directories(singletonList("/")), "I2");
+    assertThatSearchReturnsEmpty(IssueQuery.builder().directories(singletonList("unknown")));
   }
 
   @Test
   public void facets_on_directories() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file1 = newFileDto(project, null).setPath("src/main/xoo/F1.xoo");
     ComponentDto file2 = newFileDto(project, null).setPath("F2.xoo");
 
@@ -277,9 +276,9 @@ public class IssueIndexTest {
   @Test
   public void filter_by_views() {
     OrganizationDto organizationDto = newOrganizationDto();
-    ComponentDto project1 = ComponentTesting.newPrivateProjectDto(organizationDto);
+    ComponentDto project1 = newPrivateProjectDto(organizationDto);
     ComponentDto file1 = newFileDto(project1, null);
-    ComponentDto project2 = ComponentTesting.newPrivateProjectDto(organizationDto);
+    ComponentDto project2 = newPrivateProjectDto(organizationDto);
     indexIssues(
       // Project1 has 2 issues (one on a file and one on the project itself)
       newDoc("I1", project1),
@@ -295,16 +294,16 @@ public class IssueIndexTest {
     String view2 = "CDEF";
     indexView(view2, asList(project2.uuid()));
 
-    assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(asList(view1)), "I1", "I2");
-    assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(asList(view2)), "I3");
+    assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(singletonList(view1)), "I1", "I2");
+    assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(singletonList(view2)), "I3");
     assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(asList(view1, view2)), "I1", "I2", "I3");
-    assertThatSearchReturnsEmpty(IssueQuery.builder().viewUuids(asList("unknown")));
+    assertThatSearchReturnsEmpty(IssueQuery.builder().viewUuids(singletonList("unknown")));
   }
 
   @Test
   public void filter_by_views_not_having_projects() {
     OrganizationDto organizationDto = newOrganizationDto();
-    ComponentDto project1 = ComponentTesting.newPrivateProjectDto(organizationDto);
+    ComponentDto project1 = newPrivateProjectDto(organizationDto);
     ComponentDto file1 = newFileDto(project1, null);
     indexIssues(newDoc("I2", file1));
     String view1 = "ABCD";
@@ -424,7 +423,7 @@ public class IssueIndexTest {
 
   @Test
   public void filter_by_severities() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
 
     indexIssues(
@@ -432,13 +431,13 @@ public class IssueIndexTest {
       newDoc("I2", file).setSeverity(Severity.MAJOR));
 
     assertThatSearchReturnsOnly(IssueQuery.builder().severities(asList(Severity.INFO, Severity.MAJOR)), "I1", "I2");
-    assertThatSearchReturnsOnly(IssueQuery.builder().severities(asList(Severity.INFO)), "I1");
-    assertThatSearchReturnsEmpty(IssueQuery.builder().severities(asList(Severity.BLOCKER)));
+    assertThatSearchReturnsOnly(IssueQuery.builder().severities(singletonList(Severity.INFO)), "I1");
+    assertThatSearchReturnsEmpty(IssueQuery.builder().severities(singletonList(Severity.BLOCKER)));
   }
 
   @Test
   public void facets_on_severities() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
 
     indexIssues(
@@ -451,7 +450,7 @@ public class IssueIndexTest {
 
   @Test
   public void filter_by_statuses() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
 
     indexIssues(
@@ -459,13 +458,13 @@ public class IssueIndexTest {
       newDoc("I2", file).setStatus(Issue.STATUS_OPEN));
 
     assertThatSearchReturnsOnly(IssueQuery.builder().statuses(asList(Issue.STATUS_CLOSED, Issue.STATUS_OPEN)), "I1", "I2");
-    assertThatSearchReturnsOnly(IssueQuery.builder().statuses(asList(Issue.STATUS_CLOSED)), "I1");
-    assertThatSearchReturnsEmpty(IssueQuery.builder().statuses(asList(Issue.STATUS_CONFIRMED)));
+    assertThatSearchReturnsOnly(IssueQuery.builder().statuses(singletonList(Issue.STATUS_CLOSED)), "I1");
+    assertThatSearchReturnsEmpty(IssueQuery.builder().statuses(singletonList(Issue.STATUS_CONFIRMED)));
   }
 
   @Test
   public void facets_on_statuses() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
 
     indexIssues(
@@ -478,7 +477,7 @@ public class IssueIndexTest {
 
   @Test
   public void filter_by_resolutions() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
 
     indexIssues(
@@ -486,13 +485,13 @@ public class IssueIndexTest {
       newDoc("I2", file).setResolution(Issue.RESOLUTION_FIXED));
 
     assertThatSearchReturnsOnly(IssueQuery.builder().resolutions(asList(Issue.RESOLUTION_FALSE_POSITIVE, Issue.RESOLUTION_FIXED)), "I1", "I2");
-    assertThatSearchReturnsOnly(IssueQuery.builder().resolutions(asList(Issue.RESOLUTION_FALSE_POSITIVE)), "I1");
-    assertThatSearchReturnsEmpty(IssueQuery.builder().resolutions(asList(Issue.RESOLUTION_REMOVED)));
+    assertThatSearchReturnsOnly(IssueQuery.builder().resolutions(singletonList(Issue.RESOLUTION_FALSE_POSITIVE)), "I1");
+    assertThatSearchReturnsEmpty(IssueQuery.builder().resolutions(singletonList(Issue.RESOLUTION_REMOVED)));
   }
 
   @Test
   public void facets_on_resolutions() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
 
     indexIssues(
@@ -505,7 +504,7 @@ public class IssueIndexTest {
 
   @Test
   public void filter_by_resolved() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
 
     indexIssues(
@@ -520,42 +519,45 @@ public class IssueIndexTest {
 
   @Test
   public void filter_by_rules() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
-    RuleKey ruleKey = RuleKey.of("repo", "X1");
+    RuleDefinitionDto ruleDefinitionDto = newRule();
+    db.rules().insert(ruleDefinitionDto);
 
-    indexIssues(newDoc("I1", file).setRuleKey(ruleKey.toString()));
+    indexIssues(newDoc("I1", file).setRuleId(ruleDefinitionDto.getId()));
 
-    assertThatSearchReturnsOnly(IssueQuery.builder().rules(asList(ruleKey)), "I1");
-    assertThatSearchReturnsEmpty(IssueQuery.builder().rules(asList(RuleKey.of("rule", "without issue"))));
+    assertThatSearchReturnsOnly(IssueQuery.builder().rules(singletonList(ruleDefinitionDto.getId())), "I1");
+    assertThatSearchReturnsEmpty(IssueQuery.builder().rules(singletonList(-1)));
   }
 
   @Test
   public void filter_by_languages() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
-    RuleKey ruleKey = RuleKey.of("repo", "X1");
+    RuleDefinitionDto ruleDefinitionDto = newRule();
+    db.rules().insert(ruleDefinitionDto);
 
-    indexIssues(newDoc("I1", file).setRuleKey(ruleKey.toString()).setLanguage("xoo"));
+    indexIssues(newDoc("I1", file).setRuleId(ruleDefinitionDto.getId()).setLanguage("xoo"));
 
-    assertThatSearchReturnsOnly(IssueQuery.builder().languages(asList("xoo")), "I1");
-    assertThatSearchReturnsEmpty(IssueQuery.builder().languages(asList("unknown")));
+    assertThatSearchReturnsOnly(IssueQuery.builder().languages(singletonList("xoo")), "I1");
+    assertThatSearchReturnsEmpty(IssueQuery.builder().languages(singletonList("unknown")));
   }
 
   @Test
   public void facets_on_languages() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
-    RuleKey ruleKey = RuleKey.of("repo", "X1");
+    RuleDefinitionDto ruleDefinitionDto = newRule();
+    db.rules().insert(ruleDefinitionDto);
 
-    indexIssues(newDoc("I1", file).setRuleKey(ruleKey.toString()).setLanguage("xoo"));
+    indexIssues(newDoc("I1", file).setRuleId(ruleDefinitionDto.getId()).setLanguage("xoo"));
 
     assertThatFacetHasOnly(IssueQuery.builder(), "languages", entry("xoo", 1L));
   }
 
   @Test
   public void filter_by_assignees() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
 
     indexIssues(
@@ -563,14 +565,14 @@ public class IssueIndexTest {
       newDoc("I2", file).setAssignee("marcel"),
       newDoc("I3", file).setAssignee(null));
 
-    assertThatSearchReturnsOnly(IssueQuery.builder().assignees(asList("steph")), "I1");
+    assertThatSearchReturnsOnly(IssueQuery.builder().assignees(singletonList("steph")), "I1");
     assertThatSearchReturnsOnly(IssueQuery.builder().assignees(asList("steph", "marcel")), "I1", "I2");
-    assertThatSearchReturnsEmpty(IssueQuery.builder().assignees(asList("unknown")));
+    assertThatSearchReturnsEmpty(IssueQuery.builder().assignees(singletonList("unknown")));
   }
 
   @Test
   public void facets_on_assignees() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
 
     indexIssues(
@@ -584,7 +586,7 @@ public class IssueIndexTest {
 
   @Test
   public void facets_on_assignees_supports_dashes() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
 
     indexIssues(
@@ -593,12 +595,12 @@ public class IssueIndexTest {
       newDoc("I3", file).setAssignee("marcel"),
       newDoc("I4", file).setAssignee(null));
 
-    assertThatFacetHasOnly(IssueQuery.builder().assignees(asList("j-b")), "assignees", entry("j-b", 1L), entry("marcel", 2L), entry("", 1L));
+    assertThatFacetHasOnly(IssueQuery.builder().assignees(singletonList("j-b")), "assignees", entry("j-b", 1L), entry("marcel", 2L), entry("", 1L));
   }
 
   @Test
   public void filter_by_assigned() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
 
     indexIssues(
@@ -613,7 +615,7 @@ public class IssueIndexTest {
 
   @Test
   public void filter_by_authors() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
 
     indexIssues(
@@ -621,14 +623,14 @@ public class IssueIndexTest {
       newDoc("I2", file).setAuthorLogin("marcel"),
       newDoc("I3", file).setAssignee(null));
 
-    assertThatSearchReturnsOnly(IssueQuery.builder().authors(asList("steph")), "I1");
+    assertThatSearchReturnsOnly(IssueQuery.builder().authors(singletonList("steph")), "I1");
     assertThatSearchReturnsOnly(IssueQuery.builder().authors(asList("steph", "marcel")), "I1", "I2");
-    assertThatSearchReturnsEmpty(IssueQuery.builder().authors(asList("unknown")));
+    assertThatSearchReturnsEmpty(IssueQuery.builder().authors(singletonList("unknown")));
   }
 
   @Test
   public void facets_on_authors() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
 
     indexIssues(
@@ -642,7 +644,7 @@ public class IssueIndexTest {
 
   @Test
   public void filter_by_created_after() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
 
     indexIssues(
@@ -658,7 +660,7 @@ public class IssueIndexTest {
 
   @Test
   public void filter_by_created_before() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
 
     indexIssues(
@@ -674,7 +676,7 @@ public class IssueIndexTest {
 
   @Test
   public void filter_by_created_after_and_before() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
 
     indexIssues(
@@ -714,7 +716,7 @@ public class IssueIndexTest {
 
   @Test
   public void filter_by_create_after_and_before_take_into_account_timezone() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
 
     indexIssues(
@@ -758,7 +760,7 @@ public class IssueIndexTest {
 
   @Test
   public void filter_by_created_at() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
 
     indexIssues(newDoc("I1", file).setFuncCreationDate(parseDate("2014-09-20")));
@@ -900,7 +902,7 @@ public class IssueIndexTest {
   }
 
   private SearchOptions fixtureForCreatedAtFacet() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
 
     IssueDoc issue0 = newDoc("ISSUE0", file).setFuncCreationDate(parseDateTime("2011-04-25T00:05:13+0000"));
@@ -918,7 +920,7 @@ public class IssueIndexTest {
 
   @Test
   public void paging() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
     for (int i = 0; i < 12; i++) {
       indexIssues(newDoc("I" + i, file));
@@ -941,7 +943,7 @@ public class IssueIndexTest {
 
   @Test
   public void search_with_max_limit() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
     List<IssueDoc> issues = new ArrayList<>();
     for (int i = 0; i < 500; i++) {
@@ -957,7 +959,7 @@ public class IssueIndexTest {
 
   @Test
   public void sort_by_status() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
 
     indexIssues(
@@ -974,7 +976,7 @@ public class IssueIndexTest {
 
   @Test
   public void sort_by_severity() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
 
     indexIssues(
@@ -993,7 +995,7 @@ public class IssueIndexTest {
 
   @Test
   public void sort_by_assignee() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
 
     indexIssues(
@@ -1009,7 +1011,7 @@ public class IssueIndexTest {
 
   @Test
   public void sort_by_creation_date() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
 
     indexIssues(
@@ -1026,7 +1028,7 @@ public class IssueIndexTest {
 
   @Test
   public void sort_by_update_date() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
 
     indexIssues(
@@ -1043,7 +1045,7 @@ public class IssueIndexTest {
 
   @Test
   public void sort_by_close_date() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
 
     indexIssues(
@@ -1061,7 +1063,7 @@ public class IssueIndexTest {
 
   @Test
   public void sort_by_file_and_line() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file1 = newFileDto(project, null, "F1").setPath("src/main/xoo/org/sonar/samples/File.xoo");
     ComponentDto file2 = newFileDto(project, null, "F2").setPath("src/main/xoo/org/sonar/samples/File2.xoo");
 
@@ -1118,9 +1120,9 @@ public class IssueIndexTest {
   @Test
   public void authorized_issues_on_groups() {
     OrganizationDto org = newOrganizationDto();
-    ComponentDto project1 = ComponentTesting.newPrivateProjectDto(org);
-    ComponentDto project2 = ComponentTesting.newPrivateProjectDto(org);
-    ComponentDto project3 = ComponentTesting.newPrivateProjectDto(org);
+    ComponentDto project1 = newPrivateProjectDto(org);
+    ComponentDto project2 = newPrivateProjectDto(org);
+    ComponentDto project3 = newPrivateProjectDto(org);
     ComponentDto file1 = newFileDto(project1, null);
     ComponentDto file2 = newFileDto(project2, null);
     ComponentDto file3 = newFileDto(project3, null);
@@ -1150,15 +1152,15 @@ public class IssueIndexTest {
     assertThatSearchReturnsEmpty(IssueQuery.builder());
 
     userSessionRule.logIn().setGroups(group1, group2);
-    assertThatSearchReturnsEmpty(IssueQuery.builder().projectUuids(asList(project3.uuid())));
+    assertThatSearchReturnsEmpty(IssueQuery.builder().projectUuids(singletonList(project3.uuid())));
   }
 
   @Test
   public void authorized_issues_on_user() {
     OrganizationDto org = newOrganizationDto();
-    ComponentDto project1 = ComponentTesting.newPrivateProjectDto(org);
-    ComponentDto project2 = ComponentTesting.newPrivateProjectDto(org);
-    ComponentDto project3 = ComponentTesting.newPrivateProjectDto(org);
+    ComponentDto project1 = newPrivateProjectDto(org);
+    ComponentDto project2 = newPrivateProjectDto(org);
+    ComponentDto project3 = newPrivateProjectDto(org);
     ComponentDto file1 = newFileDto(project1, null);
     ComponentDto file2 = newFileDto(project2, null);
     ComponentDto file3 = newFileDto(project3, null);
@@ -1186,7 +1188,7 @@ public class IssueIndexTest {
 
   @Test
   public void root_user_is_authorized_to_access_all_issues() {
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     indexIssue(newDoc("I1", project));
     userSessionRule.logIn().setRoot();
 
@@ -1201,14 +1203,14 @@ public class IssueIndexTest {
 
     OrganizationDto org = db.organizations().insert();
     OrganizationDto anotherOrg = db.organizations().insert();
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
+    ComponentDto project = newPrivateProjectDto(newOrganizationDto());
     ComponentDto file = newFileDto(project, null);
     indexIssues(
-      newDoc("I42", file).setOrganizationUuid(anotherOrg.getUuid()).setRuleKey(r1.getKey().toString()).setTags(of("another")),
-      newDoc("I1", file).setOrganizationUuid(org.getUuid()).setRuleKey(r1.getKey().toString()).setTags(of("convention", "java8", "bug")),
-      newDoc("I2", file).setOrganizationUuid(org.getUuid()).setRuleKey(r1.getKey().toString()).setTags(of("convention", "bug")),
-      newDoc("I3", file).setOrganizationUuid(org.getUuid()).setRuleKey(r2.getKey().toString()),
-      newDoc("I4", file).setOrganizationUuid(org.getUuid()).setRuleKey(r1.getKey().toString()).setTags(of("convention")));
+      newDoc("I42", file).setOrganizationUuid(anotherOrg.getUuid()).setRuleId(r1.getId()).setTags(of("another")),
+      newDoc("I1", file).setOrganizationUuid(org.getUuid()).setRuleId(r1.getId()).setTags(of("convention", "java8", "bug")),
+      newDoc("I2", file).setOrganizationUuid(org.getUuid()).setRuleId(r1.getId()).setTags(of("convention", "bug")),
+      newDoc("I3", file).setOrganizationUuid(org.getUuid()).setRuleId(r2.getId()),
+      newDoc("I4", file).setOrganizationUuid(org.getUuid()).setRuleId(r1.getId()).setTags(of("convention")));
 
     assertThat(underTest.listTags(org, null, 100)).containsOnly("convention", "java8", "bug");
     assertThat(underTest.listTags(org, null, 2)).containsOnly("bug", "convention");
@@ -1232,7 +1234,7 @@ public class IssueIndexTest {
   @Test
   public void test_listAuthors() {
     OrganizationDto org = newOrganizationDto();
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(org);
+    ComponentDto project = newPrivateProjectDto(org);
     indexIssues(
       newDoc("issue1", project).setAuthorLogin("luke.skywalker"),
       newDoc("issue2", project).setAuthorLogin("luke@skywalker.name"),
@@ -1252,7 +1254,7 @@ public class IssueIndexTest {
   @Test
   public void listAuthors_escapes_regexp_special_characters() {
     OrganizationDto org = newOrganizationDto();
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(org);
+    ComponentDto project = newPrivateProjectDto(org);
     indexIssues(
       newDoc("issue1", project).setAuthorLogin("name++"));
     IssueQuery query = IssueQuery.builder()
@@ -1268,9 +1270,9 @@ public class IssueIndexTest {
   @Test
   public void filter_by_organization() {
     OrganizationDto org1 = newOrganizationDto();
-    ComponentDto projectInOrg1 = ComponentTesting.newPrivateProjectDto(org1);
+    ComponentDto projectInOrg1 = newPrivateProjectDto(org1);
     OrganizationDto org2 = newOrganizationDto();
-    ComponentDto projectInOrg2 = ComponentTesting.newPrivateProjectDto(org2);
+    ComponentDto projectInOrg2 = newPrivateProjectDto(org2);
 
     indexIssues(newDoc("issueInOrg1", projectInOrg1), newDoc("issue1InOrg2", projectInOrg2), newDoc("issue2InOrg2", projectInOrg2));
 
@@ -1282,25 +1284,25 @@ public class IssueIndexTest {
   @Test
   public void filter_by_organization_and_project() {
     OrganizationDto org1 = newOrganizationDto();
-    ComponentDto projectInOrg1 = ComponentTesting.newPrivateProjectDto(org1);
+    ComponentDto projectInOrg1 = newPrivateProjectDto(org1);
     OrganizationDto org2 = newOrganizationDto();
-    ComponentDto projectInOrg2 = ComponentTesting.newPrivateProjectDto(org2);
+    ComponentDto projectInOrg2 = newPrivateProjectDto(org2);
 
     indexIssues(newDoc("issueInOrg1", projectInOrg1), newDoc("issue1InOrg2", projectInOrg2), newDoc("issue2InOrg2", projectInOrg2));
 
     // no conflict
-    IssueQuery.Builder query = IssueQuery.builder().organizationUuid(org1.getUuid()).projectUuids(asList(projectInOrg1.uuid()));
+    IssueQuery.Builder query = IssueQuery.builder().organizationUuid(org1.getUuid()).projectUuids(singletonList(projectInOrg1.uuid()));
     assertThatSearchReturnsOnly(query, "issueInOrg1");
 
     // conflict
-    query = IssueQuery.builder().organizationUuid(org1.getUuid()).projectUuids(asList(projectInOrg2.uuid()));
+    query = IssueQuery.builder().organizationUuid(org1.getUuid()).projectUuids(singletonList(projectInOrg2.uuid()));
     assertThatSearchReturnsEmpty(query);
   }
 
   @Test
   public void countTags() {
     OrganizationDto org = newOrganizationDto();
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(org);
+    ComponentDto project = newPrivateProjectDto(org);
     indexIssues(
       newDoc("issue1", project).setTags(ImmutableSet.of("convention", "java8", "bug")),
       newDoc("issue2", project).setTags(ImmutableSet.of("convention", "bug")),
@@ -1416,14 +1418,14 @@ public class IssueIndexTest {
   }
 
   private void assertThatFacetHasExactly(IssueQuery.Builder query, String facet, Map.Entry<String, Long>... expectedEntries) {
-    SearchResponse result = underTest.search(query.build(), new SearchOptions().addFacets(asList(facet)));
+    SearchResponse result = underTest.search(query.build(), new SearchOptions().addFacets(singletonList(facet)));
     Facets facets = new Facets(result, system2.getDefaultTimeZone());
     assertThat(facets.getNames()).containsOnly(facet);
     assertThat(facets.get(facet)).containsExactly(expectedEntries);
   }
 
   private void assertThatFacetHasOnly(IssueQuery.Builder query, String facet, Map.Entry<String, Long>... expectedEntries) {
-    SearchResponse result = underTest.search(query.build(), new SearchOptions().addFacets(asList(facet)));
+    SearchResponse result = underTest.search(query.build(), new SearchOptions().addFacets(singletonList(facet)));
     Facets facets = new Facets(result, system2.getDefaultTimeZone());
     assertThat(facets.getNames()).containsOnly(facet);
     assertThat(facets.get(facet)).containsOnly(expectedEntries);
index 633b0ab4f3c67060ce074a6050c93134667a912c..a4dce3409d1a607f24d16ca7b460359baef14eb1 100644 (file)
@@ -24,7 +24,6 @@ import com.google.common.collect.Maps;
 import java.util.Map;
 import org.junit.Rule;
 import org.junit.Test;
-import org.sonar.api.rule.RuleKey;
 import org.sonar.api.utils.System2;
 import org.sonar.db.DbTester;
 
@@ -50,7 +49,7 @@ public class IssueIteratorFactoryTest {
     assertThat(issue.assignee()).isEqualTo("guy1");
     assertThat(issue.authorLogin()).isEqualTo("guy2");
     assertThat(issue.line()).isEqualTo(444);
-    assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("squid", "AvoidCycles"));
+    assertThat(issue.ruleId()).isEqualTo(200);
     assertThat(issue.componentUuid()).isEqualTo("FILE1");
     assertThat(issue.projectUuid()).isEqualTo("PROJECT1");
     assertThat(issue.moduleUuid()).isEqualTo("PROJECT1");
index 1a64aa3a1ce6d98eb6999a0f7e1d86f59db47277..3b7f3fdce8daac63e48c60a18014be11daacce74 100644 (file)
@@ -19,7 +19,6 @@
  */
 package org.sonar.server.issue.ws;
 
-import java.io.IOException;
 import java.time.Clock;
 import java.util.Arrays;
 import java.util.Date;
@@ -104,7 +103,8 @@ public class SearchActionComponentsTest {
   private SearchResponseFormat searchResponseFormat = new SearchResponseFormat(new Durations(), new WsResponseCommonFormat(languages), languages, new AvatarResolverImpl());
   private PermissionIndexerTester permissionIndexer = new PermissionIndexerTester(es, issueIndexer);
 
-  private WsActionTester ws = new WsActionTester(new SearchAction(userSession, issueIndex, issueQueryFactory, searchResponseLoader, searchResponseFormat, System2.INSTANCE));
+  private WsActionTester ws = new WsActionTester(new SearchAction(userSession, issueIndex, issueQueryFactory, searchResponseLoader, searchResponseFormat, System2.INSTANCE,
+    dbClient));
 
   @Test
   public void search_all_issues_when_no_parameter() {
index 65abaa4ba0a7242d29b4eb346f2f03818d0d7c50..cf8cc73604aef01cb322eccb1fe61ef24642cb65 100644 (file)
@@ -80,6 +80,7 @@ import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CREATED_AFT
 import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_HIDE_COMMENTS;
 import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_PAGE_INDEX;
 import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_PAGE_SIZE;
+import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_RULES;
 
 public class SearchActionTest {
 
@@ -102,7 +103,8 @@ public class SearchActionTest {
   private SearchResponseLoader searchResponseLoader = new SearchResponseLoader(userSessionRule, dbClient, new TransitionService(userSessionRule, issueWorkflow));
   private Languages languages = new Languages();
   private SearchResponseFormat searchResponseFormat = new SearchResponseFormat(new Durations(), new WsResponseCommonFormat(languages), languages, new AvatarResolverImpl());
-  private WsActionTester ws = new WsActionTester(new SearchAction(userSessionRule, issueIndex, issueQueryFactory, searchResponseLoader, searchResponseFormat, System2.INSTANCE));
+  private WsActionTester ws = new WsActionTester(new SearchAction(userSessionRule, issueIndex, issueQueryFactory, searchResponseLoader, searchResponseFormat, System2.INSTANCE,
+    dbClient));
   private OrganizationDto defaultOrganization;
   private OrganizationDto otherOrganization1;
   private OrganizationDto otherOrganization2;
@@ -153,7 +155,7 @@ public class SearchActionTest {
 
   //SONAR-10217
   @Test
-  public void empty_search_with_unknown_branch() throws Exception {
+  public void empty_search_with_unknown_branch() {
     TestResponse result = ws.newRequest()
       .setParam("onComponentOnly", "true")
       .setParam("componentKeys", "foo")
@@ -165,7 +167,7 @@ public class SearchActionTest {
   }
 
   @Test
-  public void empty_search() throws Exception {
+  public void empty_search() {
     TestResponse result = ws.newRequest()
       .execute();
 
@@ -174,7 +176,7 @@ public class SearchActionTest {
   }
 
   @Test
-  public void response_contains_all_fields_except_additional_fields() throws Exception {
+  public void response_contains_all_fields_except_additional_fields() {
     dbClient.userDao().insert(session, new UserDto().setLogin("simon").setName("Simon").setEmail("simon@email.com"));
     dbClient.userDao().insert(session, new UserDto().setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com"));
 
@@ -203,7 +205,7 @@ public class SearchActionTest {
   }
 
   @Test
-  public void issue_with_comments() throws Exception {
+  public void issue_with_comments() {
     dbClient.userDao().insert(session, new UserDto().setLogin("john").setName("John"));
     dbClient.userDao().insert(session, new UserDto().setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com"));
 
@@ -239,7 +241,7 @@ public class SearchActionTest {
   }
 
   @Test
-  public void issue_with_comment_hidden() throws Exception {
+  public void issue_with_comment_hidden() {
     dbClient.userDao().insert(session, new UserDto().setLogin("john").setName("John").setEmail("john@email.com"));
     dbClient.userDao().insert(session, new UserDto().setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com"));
 
@@ -274,7 +276,7 @@ public class SearchActionTest {
   }
 
   @Test
-  public void load_additional_fields() throws Exception {
+  public void load_additional_fields() {
     dbClient.userDao().insert(session, new UserDto().setLogin("simon").setName("Simon").setEmail("simon@email.com"));
     dbClient.userDao().insert(session, new UserDto().setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com"));
     ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY").setLanguage("java"));
@@ -296,7 +298,7 @@ public class SearchActionTest {
   }
 
   @Test
-  public void load_additional_fields_with_issue_admin_permission() throws Exception {
+  public void load_additional_fields_with_issue_admin_permission() {
     dbClient.userDao().insert(session, new UserDto().setLogin("simon").setName("Simon").setEmail("simon@email.com"));
     dbClient.userDao().insert(session, new UserDto().setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com"));
     ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY").setLanguage("java"));
@@ -320,7 +322,29 @@ public class SearchActionTest {
   }
 
   @Test
-  public void issue_on_removed_file() throws Exception {
+  public void search_by_rule_key() {
+    RuleDto rule = newRule();
+    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY").setLanguage("java"));
+    ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY").setLanguage("java"));
+
+    IssueDto issue = IssueTesting.newIssue(rule.getDefinition(), project, file);
+    dbClient.issueDao().insert(session, issue);
+    session.commit();
+    indexIssues();
+
+    userSessionRule.logIn("john")
+      .addProjectPermission(ISSUE_ADMIN, project); // granted by Anyone
+    indexPermissions();
+
+    TestResponse execute = ws.newRequest()
+      .setParam(PARAM_RULES, rule.getKey().toString())
+      .setParam("additionalFields", "_all")
+      .execute();
+    execute.assertJson(this.getClass(), "result_for_rule_search.json");
+  }
+
+  @Test
+  public void issue_on_removed_file() {
     RuleDto rule = newRule();
     ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY"));
     indexPermissions();
@@ -345,7 +369,7 @@ public class SearchActionTest {
   }
 
   @Test
-  public void apply_paging_with_one_component() throws Exception {
+  public void apply_paging_with_one_component() {
     RuleDto rule = newRule();
     ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY"));
     indexPermissions();
@@ -362,7 +386,7 @@ public class SearchActionTest {
   }
 
   @Test
-  public void components_contains_sub_projects() throws Exception {
+  public void components_contains_sub_projects() {
     ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("ProjectHavingModule"));
     indexPermissions();
     ComponentDto module = insertComponent(ComponentTesting.newModuleDto(project).setDbKey("ModuleHavingFile"));
@@ -377,7 +401,7 @@ public class SearchActionTest {
   }
 
   @Test
-  public void display_facets() throws Exception {
+  public void display_facets() {
     ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY"));
     indexPermissions();
     ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
@@ -402,7 +426,7 @@ public class SearchActionTest {
   }
 
   @Test
-  public void display_facets_in_effort_mode() throws Exception {
+  public void display_facets_in_effort_mode() {
     ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY"));
     indexPermissions();
     ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
@@ -428,7 +452,7 @@ public class SearchActionTest {
   }
 
   @Test
-  public void display_zero_valued_facets_for_selected_items() throws Exception {
+  public void display_zero_valued_facets_for_selected_items() {
     ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY"));
     indexPermissions();
     ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
@@ -455,7 +479,7 @@ public class SearchActionTest {
   }
 
   @Test
-  public void assignedToMe_facet_must_escape_login_of_authenticated_user() throws Exception {
+  public void assignedToMe_facet_must_escape_login_of_authenticated_user() {
     // login looks like an invalid regexp
     userSessionRule.logIn("foo[");
 
@@ -468,7 +492,7 @@ public class SearchActionTest {
   }
 
   @Test
-  public void filter_by_assigned_to_me() throws Exception {
+  public void filter_by_assigned_to_me() {
     dbClient.userDao().insert(session, new UserDto().setLogin("john").setName("John").setEmail("john@email.com"));
 
     ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "PROJECT_ID").setDbKey("PROJECT_KEY"));
@@ -512,7 +536,7 @@ public class SearchActionTest {
   }
 
   @Test
-  public void filter_by_assigned_to_me_unauthenticated() throws Exception {
+  public void filter_by_assigned_to_me_unauthenticated() {
     userSessionRule.logIn();
 
     ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY"));
@@ -542,7 +566,7 @@ public class SearchActionTest {
   }
 
   @Test
-  public void assigned_to_me_facet_is_sticky_relative_to_assignees() throws Exception {
+  public void assigned_to_me_facet_is_sticky_relative_to_assignees() {
     dbClient.userDao().insert(session, new UserDto().setLogin("alice").setName("Alice").setEmail("alice@email.com"));
 
     ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY"));
@@ -586,7 +610,7 @@ public class SearchActionTest {
   }
 
   @Test
-  public void sort_by_updated_at() throws Exception {
+  public void sort_by_updated_at() {
     RuleDto rule = newRule();
     ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY"));
     indexPermissions();
@@ -611,7 +635,7 @@ public class SearchActionTest {
   }
 
   @Test
-  public void paging() throws Exception {
+  public void paging() {
     RuleDto rule = newRule();
     ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY"));
     indexPermissions();
@@ -631,7 +655,7 @@ public class SearchActionTest {
   }
 
   @Test
-  public void paging_with_page_size_to_minus_one() throws Exception {
+  public void paging_with_page_size_to_minus_one() {
     RuleDto rule = newRule();
     ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY"));
     indexPermissions();
@@ -651,7 +675,7 @@ public class SearchActionTest {
   }
 
   @Test
-  public void deprecated_paging() throws Exception {
+  public void deprecated_paging() {
     RuleDto rule = newRule();
     ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "PROJECT_ID").setDbKey("PROJECT_KEY"));
     indexPermissions();
@@ -671,14 +695,14 @@ public class SearchActionTest {
   }
 
   @Test
-  public void default_page_size_is_100() throws Exception {
+  public void default_page_size_is_100() {
     ws.newRequest()
       .execute()
       .assertJson(this.getClass(), "default_page_size_is_100.json");
   }
 
   @Test
-  public void display_deprecated_debt_fields() throws Exception {
+  public void display_deprecated_debt_fields() {
     ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY"));
     indexPermissions();
     ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/result_for_rule_search.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/result_for_rule_search.json
new file mode 100644 (file)
index 0000000..fc0bc4e
--- /dev/null
@@ -0,0 +1,45 @@
+{
+  "total": 1,
+  "p": 1,
+  "ps": 100,
+  "paging": {
+    "pageIndex": 1,
+    "pageSize": 100,
+    "total": 1
+  },
+  "issues": [    {
+    "rule": "xoo:x1",
+    "component": "FILE_KEY",
+    "project": "PROJECT_KEY",
+    "flows": [],
+    "status": "OPEN",
+    "organization": "my-org-1"
+  }],
+  "components": [    {
+    "organization": "my-org-1",
+    "key": "FILE_KEY",
+    "uuid": "FILE_ID",
+    "enabled": true,
+    "qualifier": "FIL",
+    "name": "NAME_FILE_ID",
+    "longName": "null/NAME_FILE_ID",
+    "path": "null/NAME_FILE_ID"
+  },
+    {
+      "organization": "my-org-1",
+      "key": "PROJECT_KEY",
+      "uuid": "PROJECT_ID",
+      "enabled": true,
+      "qualifier": "TRK",
+      "name": "NAME_PROJECT_ID",
+      "longName": "LONG_NAME_PROJECT_ID"
+    }],
+  "rules": [
+    {
+      "key": "xoo:x1",
+      "name": "Rule name",
+      "lang": "xoo",
+      "status": "READY"
+    }
+  ]
+}