diff options
author | Michal Duda <michal.duda@sonarsource.com> | 2020-07-10 15:13:44 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2020-09-03 20:07:20 +0000 |
commit | 6b84d18a99ca282fc029d62f8807270537cf80ef (patch) | |
tree | 57128c2a3f4dc047b8d7729aba640d58a382a10a /server/sonar-server-common | |
parent | 8d9c4602c56ad138b22306b5ddac60e9fdf8c220 (diff) | |
download | sonarqube-6b84d18a99ca282fc029d62f8807270537cf80ef.tar.gz sonarqube-6b84d18a99ca282fc029d62f8807270537cf80ef.zip |
SONAR-13597 Add new 'Scope' facet to list of issue facets
Diffstat (limited to 'server/sonar-server-common')
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)); |