aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-server-common
diff options
context:
space:
mode:
authorMichal Duda <michal.duda@sonarsource.com>2020-07-10 15:13:44 +0200
committersonartech <sonartech@sonarsource.com>2020-09-03 20:07:20 +0000
commit6b84d18a99ca282fc029d62f8807270537cf80ef (patch)
tree57128c2a3f4dc047b8d7729aba640d58a382a10a /server/sonar-server-common
parent8d9c4602c56ad138b22306b5ddac60e9fdf8c220 (diff)
downloadsonarqube-6b84d18a99ca282fc029d62f8807270537cf80ef.tar.gz
sonarqube-6b84d18a99ca282fc029d62f8807270537cf80ef.zip
SONAR-13597 Add new 'Scope' facet to list of issue facets
Diffstat (limited to 'server/sonar-server-common')
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/issue/SearchRequest.java15
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueDoc.java9
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java2
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java6
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueScope.java27
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/issue/SearchRequestTest.java82
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/issue/index/IssueIndexerTest.java52
-rw-r--r--server/sonar-server-common/src/testFixtures/java/org/sonar/server/issue/IssueDocTesting.java2
8 files changed, 193 insertions, 2 deletions
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/SearchRequest.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/SearchRequest.java
index cd3b8174d90..587b8fae9e1 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/SearchRequest.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/SearchRequest.java
@@ -44,6 +44,7 @@ public class SearchRequest {
private List<String> facets;
private List<String> fileUuids;
private List<String> issues;
+ private Set<String> scopes;
private List<String> languages;
private List<String> moduleUuids;
private Boolean onComponentOnly;
@@ -67,6 +68,10 @@ public class SearchRequest {
private List<String> sonarsourceSecurity;
private List<String> cwe;
+ public SearchRequest() {
+ // nothing to do here
+ }
+
@CheckForNull
public List<String> getActionPlans() {
return actionPlans;
@@ -228,6 +233,16 @@ public class SearchRequest {
}
@CheckForNull
+ public Set<String> getScopes() {
+ return scopes;
+ }
+
+ public SearchRequest setScopes(@Nullable Collection<String> scopes) {
+ this.scopes = scopes == null ? null : ImmutableSet.copyOf(scopes);
+ return this;
+ }
+
+ @CheckForNull
public List<String> getLanguages() {
return languages;
}
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueDoc.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueDoc.java
index c5854408c1d..f08ca6222f2 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueDoc.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueDoc.java
@@ -83,6 +83,10 @@ public class IssueDoc extends BaseDoc {
return getField(IssueIndexDefinition.FIELD_ISSUE_RULE_UUID);
}
+ public IssueScope scope() {
+ return IssueScope.valueOf(getField(IssueIndexDefinition.FIELD_ISSUE_SCOPE));
+ }
+
public String language() {
return getField(IssueIndexDefinition.FIELD_ISSUE_LANGUAGE);
}
@@ -195,6 +199,11 @@ public class IssueDoc extends BaseDoc {
return this;
}
+ public IssueDoc setScope(IssueScope s) {
+ setField(IssueIndexDefinition.FIELD_ISSUE_SCOPE, s.toString());
+ return this;
+ }
+
public IssueDoc setLanguage(@Nullable String s) {
setField(IssueIndexDefinition.FIELD_ISSUE_LANGUAGE, s);
return this;
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java
index fb9e19da2f0..d73bc110179 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java
@@ -57,6 +57,7 @@ public class IssueIndexDefinition implements IndexDefinition {
*/
public static final String FIELD_ISSUE_FUNC_CLOSED_AT = "issueClosedAt";
public static final String FIELD_ISSUE_KEY = "key";
+ public static final String FIELD_ISSUE_SCOPE = "scope";
public static final String FIELD_ISSUE_LANGUAGE = "language";
public static final String FIELD_ISSUE_LINE = "line";
public static final String FIELD_ISSUE_MODULE_UUID = "module";
@@ -142,6 +143,7 @@ public class IssueIndexDefinition implements IndexDefinition {
mapping.createDateTimeField(FIELD_ISSUE_FUNC_UPDATED_AT);
mapping.createDateTimeField(FIELD_ISSUE_FUNC_CLOSED_AT);
mapping.keywordFieldBuilder(FIELD_ISSUE_KEY).disableNorms().addSubFields(SORTABLE_ANALYZER).build();
+ mapping.keywordFieldBuilder(FIELD_ISSUE_SCOPE).disableNorms().build();
mapping.keywordFieldBuilder(FIELD_ISSUE_LANGUAGE).disableNorms().build();
mapping.createIntegerField(FIELD_ISSUE_LINE);
mapping.keywordFieldBuilder(FIELD_ISSUE_MODULE_UUID).disableNorms().build();
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java
index d77b094947c..d4749a46d89 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java
@@ -32,6 +32,7 @@ import java.util.stream.IntStream;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
+import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.Scopes;
import org.sonar.api.rules.RuleType;
import org.sonar.db.DatabaseUtils;
@@ -80,7 +81,8 @@ class IssueIteratorForSingleChunk implements IssueIterator {
// column 21
"i.tags",
"i.issue_type",
- "r.security_standards"
+ "r.security_standards",
+ "c.qualifier"
};
private static final String SQL_ALL = "select " + StringUtils.join(FIELDS, ",") + " from issues i " +
@@ -235,6 +237,8 @@ class IssueIteratorForSingleChunk implements IssueIterator {
doc.setSansTop25(securityStandards.getSansTop25());
doc.setSonarSourceSecurityCategory(sqCategory);
doc.setVulnerabilityProbability(sqCategory.getVulnerability());
+
+ doc.setScope(Qualifiers.UNIT_TEST_FILE.equals(rs.getString(24)) ? IssueScope.TEST : IssueScope.MAIN);
return doc;
}
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueScope.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueScope.java
new file mode 100644
index 00000000000..92e31216530
--- /dev/null
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueScope.java
@@ -0,0 +1,27 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.issue.index;
+
+/**
+ * @since 8.5
+ */
+public enum IssueScope {
+ MAIN, TEST
+}
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/SearchRequestTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/SearchRequestTest.java
new file mode 100644
index 00000000000..8ce9da76e6d
--- /dev/null
+++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/SearchRequestTest.java
@@ -0,0 +1,82 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.issue;
+
+import org.junit.Test;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class SearchRequestTest {
+
+ @Test
+ public void settersAndGetters() {
+ SearchRequest underTest = new SearchRequest()
+ .setIssues(singletonList("anIssueKey"))
+ .setSeverities(asList("MAJOR", "MINOR"))
+ .setStatuses(singletonList("CLOSED"))
+ .setResolutions(singletonList("FALSE-POSITIVE"))
+ .setResolved(true)
+ .setProjects(singletonList("project-a"))
+ .setModuleUuids(singletonList("module-a"))
+ .setDirectories(singletonList("aDirPath"))
+ .setFileUuids(asList("file-a", "file-b"))
+ .setAssigneesUuid(asList("user-a", "user-b"))
+ .setScopes(asList("MAIN", "TEST"))
+ .setLanguages(singletonList("xoo"))
+ .setTags(asList("tag1", "tag2"))
+ .setOrganization("org-a")
+ .setAssigned(true)
+ .setCreatedAfter("2013-04-16T09:08:24+0200")
+ .setCreatedBefore("2013-04-17T09:08:24+0200")
+ .setRules(asList("key-a", "key-b"))
+ .setSort("CREATION_DATE")
+ .setAsc(true);
+
+ assertThat(underTest.getIssues()).containsOnlyOnce("anIssueKey");
+ assertThat(underTest.getSeverities()).containsExactly("MAJOR", "MINOR");
+ assertThat(underTest.getStatuses()).containsExactly("CLOSED");
+ assertThat(underTest.getResolutions()).containsExactly("FALSE-POSITIVE");
+ assertThat(underTest.getResolved()).isTrue();
+ assertThat(underTest.getProjects()).containsExactly("project-a");
+ assertThat(underTest.getModuleUuids()).containsExactly("module-a");
+ assertThat(underTest.getDirectories()).containsExactly("aDirPath");
+ assertThat(underTest.getFileUuids()).containsExactly("file-a", "file-b");
+ assertThat(underTest.getAssigneeUuids()).containsExactly("user-a", "user-b");
+ assertThat(underTest.getScopes()).containsExactly("MAIN", "TEST");
+ assertThat(underTest.getLanguages()).containsExactly("xoo");
+ assertThat(underTest.getTags()).containsExactly("tag1", "tag2");
+ assertThat(underTest.getOrganization()).isEqualTo("org-a");
+ assertThat(underTest.getAssigned()).isTrue();
+ assertThat(underTest.getCreatedAfter()).isEqualTo("2013-04-16T09:08:24+0200");
+ assertThat(underTest.getCreatedBefore()).isEqualTo("2013-04-17T09:08:24+0200");
+ assertThat(underTest.getRules()).containsExactly("key-a", "key-b");
+ assertThat(underTest.getSort()).isEqualTo("CREATION_DATE");
+ assertThat(underTest.getAsc()).isTrue();
+ }
+
+ @Test
+ public void setScopesAcceptsNull() {
+ SearchRequest underTest = new SearchRequest().setScopes(null);
+
+ assertThat(underTest.getScopes()).isNull();
+ }
+}
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/index/IssueIndexerTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/index/IssueIndexerTest.java
index 07da774c810..326e8399ef8 100644
--- a/server/sonar-server-common/src/test/java/org/sonar/server/issue/index/IssueIndexerTest.java
+++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/index/IssueIndexerTest.java
@@ -136,6 +136,7 @@ public class IssueIndexerTest {
assertThat(doc.creationDate()).isEqualToIgnoringMillis(issue.getIssueCreationDate());
assertThat(doc.directoryPath()).isEqualTo(dir.path());
assertThat(doc.filePath()).isEqualTo(file.path());
+ assertThat(doc.scope()).isEqualTo(IssueScope.MAIN);
assertThat(doc.language()).isEqualTo(issue.getLanguage());
assertThat(doc.line()).isEqualTo(issue.getLine());
// functional date
@@ -507,10 +508,59 @@ public class IssueIndexerTest {
assertThat(doc.projectUuid()).isEqualTo(branch.getMainBranchProjectUuid());
assertThat(doc.branchUuid()).isEqualTo(branch.uuid());
assertThat(doc.isMainBranch()).isFalse();
+ assertThat(doc.scope()).isEqualTo(IssueScope.MAIN);
}
@Test
- public void getType(){
+ public void issue_on_test_file_has_test_scope() {
+ RuleDefinitionDto rule = db.rules().insert();
+ ComponentDto project = db.components().insertPrivateProject(organization);
+ ComponentDto dir = db.components().insertComponent(ComponentTesting.newDirectory(project, "src/main/java/foo"));
+ ComponentDto file = db.components().insertComponent(newFileDto(project, dir, "F1").setQualifier("UTS"));
+ IssueDto issue = db.issues().insert(rule, project, file);
+
+ underTest.indexAllIssues();
+
+ IssueDoc doc = es.getDocuments(TYPE_ISSUE, IssueDoc.class).get(0);
+ assertThat(doc.getId()).isEqualTo(issue.getKey());
+ assertThat(doc.organizationUuid()).isEqualTo(organization.getUuid());
+ assertThat(doc.componentUuid()).isEqualTo(file.uuid());
+ assertThat(doc.scope()).isEqualTo(IssueScope.TEST);
+ }
+
+ @Test
+ public void issue_on_directory_has_main_code_scope() {
+ RuleDefinitionDto rule = db.rules().insert();
+ ComponentDto project = db.components().insertPrivateProject(organization);
+ ComponentDto dir = db.components().insertComponent(ComponentTesting.newDirectory(project, "src/main/java/foo"));
+ IssueDto issue = db.issues().insert(rule, project, dir);
+
+ underTest.indexAllIssues();
+
+ IssueDoc doc = es.getDocuments(TYPE_ISSUE, IssueDoc.class).get(0);
+ assertThat(doc.getId()).isEqualTo(issue.getKey());
+ assertThat(doc.organizationUuid()).isEqualTo(organization.getUuid());
+ assertThat(doc.componentUuid()).isEqualTo(dir.uuid());
+ assertThat(doc.scope()).isEqualTo(IssueScope.MAIN);
+ }
+
+ @Test
+ public void issue_on_project_has_main_code_scope() {
+ RuleDefinitionDto rule = db.rules().insert();
+ ComponentDto project = db.components().insertPrivateProject(organization);
+ IssueDto issue = db.issues().insert(rule, project, project);
+
+ underTest.indexAllIssues();
+
+ IssueDoc doc = es.getDocuments(TYPE_ISSUE, IssueDoc.class).get(0);
+ assertThat(doc.getId()).isEqualTo(issue.getKey());
+ assertThat(doc.organizationUuid()).isEqualTo(organization.getUuid());
+ assertThat(doc.componentUuid()).isEqualTo(project.uuid());
+ assertThat(doc.scope()).isEqualTo(IssueScope.MAIN);
+ }
+
+ @Test
+ public void getType() {
Assertions.assertThat(underTest.getType()).isEqualTo(StartupIndexer.Type.ASYNCHRONOUS);
}
diff --git a/server/sonar-server-common/src/testFixtures/java/org/sonar/server/issue/IssueDocTesting.java b/server/sonar-server-common/src/testFixtures/java/org/sonar/server/issue/IssueDocTesting.java
index fbe410e598f..16340cc2ea5 100644
--- a/server/sonar-server-common/src/testFixtures/java/org/sonar/server/issue/IssueDocTesting.java
+++ b/server/sonar-server-common/src/testFixtures/java/org/sonar/server/issue/IssueDocTesting.java
@@ -27,6 +27,7 @@ import org.sonar.api.rules.RuleType;
import org.sonar.core.util.Uuids;
import org.sonar.db.component.ComponentDto;
import org.sonar.server.issue.index.IssueDoc;
+import org.sonar.server.issue.index.IssueScope;
import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
import static org.apache.commons.lang.math.RandomUtils.nextInt;
@@ -60,6 +61,7 @@ public class IssueDocTesting {
doc.setType(RuleType.CODE_SMELL);
doc.setAssigneeUuid("assignee_uuid_" + randomAlphabetic(26));
doc.setAuthorLogin("author_" + randomAlphabetic(5));
+ doc.setScope(IssueScope.MAIN);
doc.setLanguage("language_" + randomAlphabetic(5));
doc.setComponentUuid(Uuids.createFast());
doc.setFilePath("filePath_" + randomAlphabetic(5));