Browse Source

SONAR-13592 add facet to filter by file paths

tags/8.5.0.37579
Jacek 3 years ago
parent
commit
41784809b3

+ 5
- 5
server/sonar-server-common/src/main/java/org/sonar/server/issue/SearchRequest.java View File

@@ -42,7 +42,7 @@ public class SearchRequest {
private List<String> directories;
private String facetMode;
private List<String> facets;
private List<String> fileUuids;
private List<String> files;
private List<String> issues;
private Set<String> scopes;
private List<String> languages;
@@ -213,12 +213,12 @@ public class SearchRequest {
}

@CheckForNull
public List<String> getFileUuids() {
return fileUuids;
public List<String> getFiles() {
return files;
}

public SearchRequest setFileUuids(@Nullable List<String> fileUuids) {
this.fileUuids = fileUuids;
public SearchRequest setFiles(@Nullable List<String> files) {
this.files = files;
return this;
}


+ 2
- 2
server/sonar-server-common/src/test/java/org/sonar/server/issue/SearchRequestTest.java View File

@@ -38,7 +38,7 @@ public class SearchRequestTest {
.setProjects(singletonList("project-a"))
.setModuleUuids(singletonList("module-a"))
.setDirectories(singletonList("aDirPath"))
.setFileUuids(asList("file-a", "file-b"))
.setFiles(asList("file-a", "file-b"))
.setAssigneesUuid(asList("user-a", "user-b"))
.setScopes(asList("MAIN", "TEST"))
.setLanguages(singletonList("xoo"))
@@ -59,7 +59,7 @@ public class SearchRequestTest {
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.getFiles()).containsExactly("file-a", "file-b");
assertThat(underTest.getAssigneeUuids()).containsExactly("user-a", "user-b");
assertThat(underTest.getScopes()).containsExactly("MAIN", "TEST");
assertThat(underTest.getLanguages()).containsExactly("xoo");

+ 16
- 19
server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java View File

@@ -37,7 +37,6 @@ import java.util.stream.IntStream;
import java.util.stream.Stream;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
@@ -119,7 +118,7 @@ import static org.sonar.server.issue.index.IssueIndex.Facet.AUTHORS;
import static org.sonar.server.issue.index.IssueIndex.Facet.CREATED_AT;
import static org.sonar.server.issue.index.IssueIndex.Facet.CWE;
import static org.sonar.server.issue.index.IssueIndex.Facet.DIRECTORIES;
import static org.sonar.server.issue.index.IssueIndex.Facet.FILE_UUIDS;
import static org.sonar.server.issue.index.IssueIndex.Facet.FILES;
import static org.sonar.server.issue.index.IssueIndex.Facet.LANGUAGES;
import static org.sonar.server.issue.index.IssueIndex.Facet.MODULE_UUIDS;
import static org.sonar.server.issue.index.IssueIndex.Facet.OWASP_TOP_10;
@@ -178,7 +177,7 @@ import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_AUTHOR;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CREATED_AT;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CWE;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_DIRECTORIES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_FILE_UUIDS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_FILES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_LANGUAGES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_MODULE_UUIDS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_OWASP_TOP_10;
@@ -242,7 +241,7 @@ public class IssueIndex {
AUTHOR(PARAM_AUTHOR, FIELD_ISSUE_AUTHOR_LOGIN, STICKY, MAX_FACET_SIZE),
PROJECT_UUIDS(FACET_PROJECTS, FIELD_ISSUE_PROJECT_UUID, STICKY, MAX_FACET_SIZE),
MODULE_UUIDS(PARAM_MODULE_UUIDS, FIELD_ISSUE_MODULE_UUID, STICKY, MAX_FACET_SIZE),
FILE_UUIDS(PARAM_FILE_UUIDS, FIELD_ISSUE_COMPONENT_UUID, STICKY, MAX_FACET_SIZE),
FILES(PARAM_FILES, FIELD_ISSUE_FILE_PATH, STICKY, MAX_FACET_SIZE),
DIRECTORIES(PARAM_DIRECTORIES, FIELD_ISSUE_DIRECTORY_PATH, STICKY, MAX_FACET_SIZE),
ASSIGNEES(PARAM_ASSIGNEES, FIELD_ISSUE_ASSIGNEE_UUID, STICKY, MAX_FACET_SIZE),
ASSIGNED_TO_ME(FACET_ASSIGNED_TO_ME, FIELD_ISSUE_ASSIGNEE_UUID, STICKY, 1),
@@ -404,16 +403,16 @@ public class IssueIndex {
filters.addFilter("__authorization", new SimpleFieldFilterScope("parent"), createAuthorizationFilter());

// Issue is assigned Filter
if (BooleanUtils.isTrue(query.assigned())) {
if (Boolean.TRUE.equals(query.assigned())) {
filters.addFilter(IS_ASSIGNED_FILTER, Facet.ASSIGNEES.getFilterScope(), existsQuery(FIELD_ISSUE_ASSIGNEE_UUID));
} else if (BooleanUtils.isFalse(query.assigned())) {
} else if (Boolean.FALSE.equals(query.assigned())) {
filters.addFilter(IS_ASSIGNED_FILTER, ASSIGNEES.getFilterScope(), boolQuery().mustNot(existsQuery(FIELD_ISSUE_ASSIGNEE_UUID)));
}

// Issue is Resolved Filter
if (BooleanUtils.isTrue(query.resolved())) {
if (Boolean.TRUE.equals(query.resolved())) {
filters.addFilter("__isResolved", Facet.RESOLUTIONS.getFilterScope(), existsQuery(FIELD_ISSUE_RESOLUTION));
} else if (BooleanUtils.isFalse(query.resolved())) {
} else if (Boolean.FALSE.equals(query.resolved())) {
filters.addFilter("__isResolved", Facet.RESOLUTIONS.getFilterScope(), boolQuery().mustNot(existsQuery(FIELD_ISSUE_RESOLUTION)));
}

@@ -488,12 +487,10 @@ public class IssueIndex {
}

private static void addCommonComponentRelatedFilters(IssueQuery query, AllFilters filters) {
QueryBuilder componentFilter = createTermsFilter(FIELD_ISSUE_COMPONENT_UUID, query.componentUuids());
QueryBuilder fileFilter = createTermsFilter(FIELD_ISSUE_COMPONENT_UUID, query.fileUuids());
filters.addFilter(FIELD_ISSUE_COMPONENT_UUID, new SimpleFieldFilterScope(FIELD_ISSUE_COMPONENT_UUID),
createTermsFilter(FIELD_ISSUE_COMPONENT_UUID, query.componentUuids()));

if (BooleanUtils.isTrue(query.onComponentOnly())) {
filters.addFilter(FIELD_ISSUE_COMPONENT_UUID, new SimpleFieldFilterScope(FIELD_ISSUE_COMPONENT_UUID), componentFilter);
} else {
if (!Boolean.TRUE.equals(query.onComponentOnly())) {
filters.addFilter(
FIELD_ISSUE_PROJECT_UUID, new SimpleFieldFilterScope(FIELD_ISSUE_PROJECT_UUID),
createTermsFilter(FIELD_ISSUE_PROJECT_UUID, query.projectUuids()));
@@ -507,13 +504,13 @@ public class IssueIndex {
FIELD_ISSUE_DIRECTORY_PATH, new SimpleFieldFilterScope(FIELD_ISSUE_DIRECTORY_PATH),
createTermsFilter(FIELD_ISSUE_DIRECTORY_PATH, query.directories()));
filters.addFilter(
FIELD_ISSUE_COMPONENT_UUID, new SimpleFieldFilterScope(FIELD_ISSUE_COMPONENT_UUID),
fileFilter == null ? componentFilter : fileFilter);
FIELD_ISSUE_FILE_PATH, new SimpleFieldFilterScope(FIELD_ISSUE_FILE_PATH),
createTermsFilter(FIELD_ISSUE_FILE_PATH, query.files()));
}
}

private static void addBranchComponentRelatedFilters(IssueQuery query, AllFilters allFilters) {
if (BooleanUtils.isTrue(query.onComponentOnly())) {
if (Boolean.TRUE.equals(query.onComponentOnly())) {
return;
}
allFilters.addFilter(
@@ -525,7 +522,7 @@ public class IssueIndex {
}

private static void addViewRelatedFilters(IssueQuery query, AllFilters allFilters) {
if (BooleanUtils.isTrue(query.onComponentOnly())) {
if (Boolean.TRUE.equals(query.onComponentOnly())) {
return;
}
Collection<String> viewUuids = query.viewUuids();
@@ -606,7 +603,7 @@ public class IssueIndex {
private List<FieldSortBuilder> createSortBuilders(IssueQuery query) {
String sortField = query.sort();
if (sortField != null) {
boolean asc = BooleanUtils.isTrue(query.asc());
boolean asc = Boolean.TRUE.equals(query.asc());
return sorting.fill(sortField, asc);
}
return sorting.fillDefault();
@@ -666,7 +663,7 @@ public class IssueIndex {
addFacetIfNeeded(options, aggregationHelper, esRequest, PROJECT_UUIDS, query.projectUuids().toArray());
addFacetIfNeeded(options, aggregationHelper, esRequest, MODULE_UUIDS, query.moduleUuids().toArray());
addFacetIfNeeded(options, aggregationHelper, esRequest, DIRECTORIES, query.directories().toArray());
addFacetIfNeeded(options, aggregationHelper, esRequest, FILE_UUIDS, query.fileUuids().toArray());
addFacetIfNeeded(options, aggregationHelper, esRequest, FILES, query.files().toArray());
addFacetIfNeeded(options, aggregationHelper, esRequest, SCOPES, query.scopes().toArray());
addFacetIfNeeded(options, aggregationHelper, esRequest, LANGUAGES, query.languages().toArray());
addFacetIfNeeded(options, aggregationHelper, esRequest, RULES, query.rules().stream().map(RuleDefinitionDto::getUuid).toArray());

+ 2
- 2
server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQuery.java View File

@@ -171,7 +171,7 @@ public class IssueQuery {
return directories;
}

public Collection<String> fileUuids() {
public Collection<String> files() {
return files;
}

@@ -380,7 +380,7 @@ public class IssueQuery {
return this;
}

public Builder fileUuids(@Nullable Collection<String> l) {
public Builder files(@Nullable Collection<String> l) {
this.files = l;
return this;
}

+ 2
- 2
server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java View File

@@ -237,7 +237,7 @@ public class IssueQueryFactory {
}
builder.moduleUuids(request.getModuleUuids());
builder.directories(request.getDirectories());
builder.fileUuids(request.getFileUuids());
builder.files(request.getFiles());

addComponentsBasedOnQualifier(builder, session, components, request);
}
@@ -276,7 +276,7 @@ public class IssueQueryFactory {
break;
case Qualifiers.FILE:
case Qualifiers.UNIT_TEST_FILE:
builder.fileUuids(components.stream().map(ComponentDto::uuid).collect(toList()));
builder.componentUuids(components.stream().map(ComponentDto::uuid).collect(toList()));
break;
default:
throw new IllegalArgumentException("Unable to set search root context for components " + Joiner.on(',').join(components));

+ 4
- 4
server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexDebtTest.java View File

@@ -101,10 +101,10 @@ public class IssueIndexDebtTest {
IssueDocTesting.newDoc("I4", file2).setEffort(10L),
IssueDocTesting.newDoc("I5", file3).setEffort(10L));

Facets facets = search("fileUuids");
assertThat(facets.getNames()).containsOnly("fileUuids", FACET_MODE_EFFORT);
assertThat(facets.get("fileUuids"))
.containsOnly(entry("A", 10L), entry("ABCD", 10L), entry("BCDE", 20L), entry("CDEF", 10L));
Facets facets = search("files");
assertThat(facets.getNames()).containsOnly("files", FACET_MODE_EFFORT);
assertThat(facets.get("files"))
.containsOnly(entry(file1.path(), 10L), entry(file2.path(), 20L), entry(file3.path(), 10L));
assertThat(facets.get(FACET_MODE_EFFORT)).containsOnly(entry("total", 50L));
}


+ 7
- 6
server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFacetsTest.java View File

@@ -118,9 +118,10 @@ public class IssueIndexFacetsTest {
@Test
public void facets_on_files() {
ComponentDto project = newPrivateProjectDto(newOrganizationDto(), "A");
ComponentDto file1 = newFileDto(project, null, "ABCD");
ComponentDto file2 = newFileDto(project, null, "BCDE");
ComponentDto file3 = newFileDto(project, null, "CDEF");
ComponentDto dir = newDirectory(project, "src");
ComponentDto file1 = newFileDto(project, dir, "ABCD");
ComponentDto file2 = newFileDto(project, dir, "BCDE");
ComponentDto file3 = newFileDto(project, dir, "CDEF");

indexIssues(
newDoc("I1", project),
@@ -129,7 +130,7 @@ public class IssueIndexFacetsTest {
newDoc("I4", file2),
newDoc("I5", file3));

assertThatFacetHasOnly(IssueQuery.builder(), "fileUuids", entry("A", 1L), entry("ABCD", 1L), entry("BCDE", 2L), entry("CDEF", 1L));
assertThatFacetHasOnly(IssueQuery.builder(), "files", entry("src/NAME_ABCD", 1L), entry("src/NAME_BCDE", 2L), entry("src/NAME_CDEF", 1L));
}

@Test
@@ -141,8 +142,8 @@ public class IssueIndexFacetsTest {
IssueDoc issue2 = newDoc(newFileDto(project, null, "file2"));
indexIssues(issue1, issue2);

assertThatFacetHasSize(IssueQuery.builder().build(), "fileUuids", 100);
assertThatFacetHasSize(IssueQuery.builder().fileUuids(asList(issue1.componentUuid(), issue2.componentUuid())).build(), "fileUuids", 102);
assertThatFacetHasSize(IssueQuery.builder().build(), "files", 100);
assertThatFacetHasSize(IssueQuery.builder().files(asList(issue1.filePath(), issue2.filePath())).build(), "files", 102);
}

@Test

+ 10
- 10
server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFiltersTest.java View File

@@ -155,8 +155,8 @@ public class IssueIndexFiltersTest {
newDoc("I5", subModule),
newDoc("I6", file3));

assertThatSearchReturnsOnly(IssueQuery.builder().fileUuids(asList(file1.uuid(), file2.uuid(), file3.uuid())), "I2", "I4", "I6");
assertThatSearchReturnsOnly(IssueQuery.builder().fileUuids(singletonList(file1.uuid())), "I2");
assertThatSearchReturnsOnly(IssueQuery.builder().files(asList(file1.path(), file2.path(), file3.path())), "I2", "I4", "I6");
assertThatSearchReturnsOnly(IssueQuery.builder().files(singletonList(file1.path())), "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");
@@ -188,8 +188,8 @@ public class IssueIndexFiltersTest {
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");
assertThatSearchReturnsOnly(IssueQuery.builder().files(singletonList(file1.path())), "I2");
assertThatSearchReturnsOnly(IssueQuery.builder().files(asList(file1.path(), file2.path(), file3.path())), "I2", "I4", "I6");
}

@Test
@@ -228,7 +228,7 @@ public class IssueIndexFiltersTest {
assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(asList(portfolio1.uuid(), portfolio2.uuid())), issueOnProject1.key(), issueOnFile.key(), issueOnProject2.key());
assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(singletonList(portfolio1.uuid())).projectUuids(singletonList(project1.uuid())), issueOnProject1.key(),
issueOnFile.key());
assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(singletonList(portfolio1.uuid())).fileUuids(singletonList(file.uuid())), issueOnFile.key());
assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(singletonList(portfolio1.uuid())).files(singletonList(file.path())), issueOnFile.key());
assertThatSearchReturnsEmpty(IssueQuery.builder().viewUuids(singletonList("unknown")));
}

@@ -302,8 +302,8 @@ public class IssueIndexFiltersTest {

assertThatSearchReturnsOnly(IssueQuery.builder().branchUuid(branch.uuid()).mainBranch(false), "I4", "I5", "I6");
assertThatSearchReturnsOnly(IssueQuery.builder().moduleUuids(singletonList(branchModule.uuid())).branchUuid(branch.uuid()).mainBranch(false), "I5", "I6");
assertThatSearchReturnsOnly(IssueQuery.builder().fileUuids(singletonList(branchFile.uuid())).branchUuid(branch.uuid()).mainBranch(false), "I6");
assertThatSearchReturnsEmpty(IssueQuery.builder().fileUuids(singletonList(branchFile.uuid())).mainBranch(false).branchUuid("unknown"));
assertThatSearchReturnsOnly(IssueQuery.builder().files(singletonList(branchFile.path())).branchUuid(branch.uuid()).mainBranch(false), "I6");
assertThatSearchReturnsEmpty(IssueQuery.builder().files(singletonList(branchFile.uuid())).mainBranch(false).branchUuid("unknown"));
}

@Test
@@ -355,7 +355,7 @@ public class IssueIndexFiltersTest {
assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(asList(application1.uuid(), application2.uuid())), issueOnProject1.key(), issueOnFile.key(), issueOnProject2.key());
assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(singletonList(application1.uuid())).projectUuids(singletonList(project1.uuid())), issueOnProject1.key(),
issueOnFile.key());
assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(singletonList(application1.uuid())).fileUuids(singletonList(file.uuid())), issueOnFile.key());
assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(singletonList(application1.uuid())).files(singletonList(file.path())), issueOnFile.key());
assertThatSearchReturnsEmpty(IssueQuery.builder().viewUuids(singletonList("unknown")));
}

@@ -380,7 +380,7 @@ public class IssueIndexFiltersTest {
assertThatSearchReturnsOnly(
IssueQuery.builder().viewUuids(singletonList(branch1.uuid())).projectUuids(singletonList(project1.uuid())).branchUuid(branch1.uuid()).mainBranch(false),
issueOnProject1.key(), issueOnFile.key());
assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(singletonList(branch1.uuid())).fileUuids(singletonList(file.uuid())).branchUuid(branch1.uuid()).mainBranch(false),
assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(singletonList(branch1.uuid())).files(singletonList(file.path())).branchUuid(branch1.uuid()).mainBranch(false),
issueOnFile.key());
assertThatSearchReturnsEmpty(IssueQuery.builder().branchUuid("unknown"));
}
@@ -411,7 +411,7 @@ public class IssueIndexFiltersTest {
IssueQuery.builder().viewUuids(singletonList(applicationBranch1.uuid())).projectUuids(singletonList(project1.uuid())).branchUuid(applicationBranch1.uuid()).mainBranch(false),
issueOnProject1Branch1.key(), issueOnFileOnProject1Branch1.key());
assertThatSearchReturnsOnly(
IssueQuery.builder().viewUuids(singletonList(applicationBranch1.uuid())).fileUuids(singletonList(fileOnProject1Branch1.uuid())).branchUuid(applicationBranch1.uuid())
IssueQuery.builder().viewUuids(singletonList(applicationBranch1.uuid())).files(singletonList(fileOnProject1Branch1.path())).branchUuid(applicationBranch1.uuid())
.mainBranch(false),
issueOnFileOnProject1Branch1.key());
assertThatSearchReturnsEmpty(

+ 12
- 12
server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryFactoryTest.java View File

@@ -91,7 +91,7 @@ public class IssueQueryFactoryTest {
.setProjects(asList(project.getDbKey()))
.setModuleUuids(asList(module.uuid()))
.setDirectories(asList("aDirPath"))
.setFileUuids(asList(file.uuid()))
.setFiles(asList(file.uuid()))
.setAssigneesUuid(asList(user.getUuid()))
.setScopes(asList("MAIN", "TEST"))
.setLanguages(asList("xoo"))
@@ -113,7 +113,7 @@ public class IssueQueryFactoryTest {
assertThat(query.resolved()).isTrue();
assertThat(query.projectUuids()).containsOnly(project.uuid());
assertThat(query.moduleUuids()).containsOnly(module.uuid());
assertThat(query.fileUuids()).containsOnly(file.uuid());
assertThat(query.files()).containsOnly(file.uuid());
assertThat(query.assignees()).containsOnly(user.getUuid());
assertThat(query.scopes()).containsOnly("TEST", "MAIN");
assertThat(query.languages()).containsOnly("xoo");
@@ -206,7 +206,7 @@ public class IssueQueryFactoryTest {
assertThat(query.moduleUuids()).isEmpty();
assertThat(query.moduleRootUuids()).isEmpty();
assertThat(query.directories()).isEmpty();
assertThat(query.fileUuids()).isEmpty();
assertThat(query.files()).isEmpty();
assertThat(query.viewUuids()).isEmpty();
assertThat(query.organizationUuid()).isNull();
assertThat(query.branchUuid()).isNull();
@@ -348,7 +348,7 @@ public class IssueQueryFactoryTest {

IssueQuery query = underTest.create(request);

assertThat(query.fileUuids()).containsExactly(file.uuid());
assertThat(query.componentUuids()).containsExactly(file.uuid());
}

@Test
@@ -360,7 +360,7 @@ public class IssueQueryFactoryTest {

IssueQuery query = underTest.create(request);

assertThat(query.fileUuids()).containsExactly(file.uuid());
assertThat(query.componentUuids()).containsExactly(file.uuid());
}

@Test
@@ -390,22 +390,22 @@ public class IssueQueryFactoryTest {
assertThat(underTest.create(new SearchRequest()
.setComponents(singletonList(file.getKey()))
.setBranch(branch.getBranch())))
.extracting(IssueQuery::branchUuid, query -> new ArrayList<>(query.fileUuids()), IssueQuery::isMainBranch)
.extracting(IssueQuery::branchUuid, query -> new ArrayList<>(query.componentUuids()), IssueQuery::isMainBranch)
.containsOnly(branch.uuid(), singletonList(file.uuid()), false);

assertThat(underTest.create(new SearchRequest()
.setComponents(singletonList(branch.getKey()))
.setFileUuids(singletonList(file.uuid()))
.setFiles(singletonList(file.path()))
.setBranch(branch.getBranch())))
.extracting(IssueQuery::branchUuid, query -> new ArrayList<>(query.fileUuids()), IssueQuery::isMainBranch)
.containsOnly(branch.uuid(), singletonList(file.uuid()), false);
.extracting(IssueQuery::branchUuid, query -> new ArrayList<>(query.files()), IssueQuery::isMainBranch)
.containsOnly(branch.uuid(), singletonList(file.path()), false);

assertThat(underTest.create(new SearchRequest()
.setProjects(singletonList(branch.getKey()))
.setFileUuids(singletonList(file.uuid()))
.setFiles(singletonList(file.path()))
.setBranch(branch.getBranch())))
.extracting(IssueQuery::branchUuid, query -> new ArrayList<>(query.fileUuids()), IssueQuery::isMainBranch)
.containsOnly(branch.uuid(), singletonList(file.uuid()), false);
.extracting(IssueQuery::branchUuid, query -> new ArrayList<>(query.files()), IssueQuery::isMainBranch)
.containsOnly(branch.uuid(), singletonList(file.path()), false);
}

@Test

+ 12
- 11
server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchAction.java View File

@@ -109,7 +109,7 @@ import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CREATED_BEF
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CREATED_IN_LAST;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CWE;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_DIRECTORIES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_FILE_UUIDS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_FILES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_ISSUES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_LANGUAGES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_MODULE_UUIDS;
@@ -139,7 +139,7 @@ public class SearchAction implements IssuesWsAction {
static final List<String> SUPPORTED_FACETS = ImmutableList.of(
FACET_PROJECTS,
PARAM_MODULE_UUIDS,
PARAM_FILE_UUIDS,
PARAM_FILES,
FACET_ASSIGNED_TO_ME,
PARAM_SEVERITIES,
PARAM_STATUSES,
@@ -160,7 +160,7 @@ public class SearchAction implements IssuesWsAction {
PARAM_SONARSOURCE_SECURITY);

private static final String INTERNAL_PARAMETER_DISCLAIMER = "This parameter is mostly used by the Issues page, please prefer usage of the componentKeys parameter. ";
private static final Set<String> FACETS_REQUIRING_PROJECT_OR_ORGANIZATION = newHashSet(PARAM_MODULE_UUIDS, PARAM_FILE_UUIDS, PARAM_DIRECTORIES);
private static final Set<String> FACETS_REQUIRING_PROJECT_OR_ORGANIZATION = newHashSet(PARAM_MODULE_UUIDS, PARAM_FILES, PARAM_DIRECTORIES);

private final UserSession userSession;
private final IssueIndex issueIndex;
@@ -192,6 +192,9 @@ public class SearchAction implements IssuesWsAction {
+ "<br/>When issue indexation is in progress returns 503 service unavailable HTTP code.")
.setSince("3.6")
.setChangelog(
new Change("8.5", "Facet 'fileUuids' is dropped in favour of the new facet 'files'" +
"Note that they are not strictly identical, the latter returns the file paths."),
new Change("8.5", "Internal parameter 'fileUuids' has been dropped"),
new Change("8.4", "parameters 'componentUuids', 'projectKeys' has been dropped."),
new Change("8.2", "'REVIEWED', 'TO_REVIEW' status param values are no longer supported"),
new Change("8.2", "Security hotspots are no longer returned as type 'SECURITY_HOTSPOT' is not supported anymore, use dedicated api/hotspots"),
@@ -322,7 +325,7 @@ public class SearchAction implements IssuesWsAction {
private static void addComponentRelatedParams(WebService.NewAction action) {
action.createParam(PARAM_ON_COMPONENT_ONLY)
.setDescription("Return only issues at a component's level, not on its descendants (modules, directories, files, etc). " +
"This parameter is only considered when componentKeys or componentUuids is set.")
"This parameter is only considered when componentKeys is set.")
.setBooleanPossibleValues()
.setDefaultValue("false");

@@ -353,11 +356,11 @@ public class SearchAction implements IssuesWsAction {
.setSince("5.1")
.setExampleValue("src/main/java/org/sonar/server/");

action.createParam(PARAM_FILE_UUIDS)
.setDescription("To retrieve issues associated to a specific list of files (comma-separated list of file IDs). " +
action.createParam(PARAM_FILES)
.setDescription("To retrieve issues associated to a specific list of files (comma-separated list of file paths). " +
INTERNAL_PARAMETER_DISCLAIMER)
.setInternal(true)
.setExampleValue("bdd82933-3070-4903-9188-7d8749e8bb92");
.setExampleValue("src/main/java/org/sonar/server/Test.java");

action.createParam(PARAM_BRANCH)
.setDescription("Branch key. Not available in the community edition.")
@@ -447,7 +450,7 @@ public class SearchAction implements IssuesWsAction {
addMandatoryValuesToFacet(facets, PARAM_RESOLUTIONS, concat(singletonList(""), RESOLUTIONS));
addMandatoryValuesToFacet(facets, FACET_PROJECTS, query.projectUuids());
addMandatoryValuesToFacet(facets, PARAM_MODULE_UUIDS, query.moduleUuids());
addMandatoryValuesToFacet(facets, PARAM_FILE_UUIDS, query.fileUuids());
addMandatoryValuesToFacet(facets, PARAM_FILES, query.files());

List<String> assignees = Lists.newArrayList("");
List<String> assigneesFromRequest = request.getAssigneeUuids();
@@ -498,13 +501,11 @@ public class SearchAction implements IssuesWsAction {
private static void collectFacets(SearchResponseLoader.Collector collector, Facets facets) {
collector.addProjectUuids(facets.getBucketKeys(FACET_PROJECTS));
collector.addComponentUuids(facets.getBucketKeys(PARAM_MODULE_UUIDS));
collector.addComponentUuids(facets.getBucketKeys(PARAM_FILE_UUIDS));
collector.addRuleIds(facets.getBucketKeys(PARAM_RULES));
collector.addUserUuids(facets.getBucketKeys(PARAM_ASSIGNEES));
}

private static void collectRequestParams(SearchResponseLoader.Collector collector, SearchRequest request) {
collector.addComponentUuids(request.getFileUuids());
collector.addComponentUuids(request.getModuleUuids());
collector.addUserUuids(request.getAssigneeUuids());
}
@@ -524,7 +525,7 @@ public class SearchAction implements IssuesWsAction {
.setDirectories(request.paramAsStrings(PARAM_DIRECTORIES))
.setFacetMode(request.mandatoryParam(FACET_MODE))
.setFacets(request.paramAsStrings(FACETS))
.setFileUuids(request.paramAsStrings(PARAM_FILE_UUIDS))
.setFiles(request.paramAsStrings(PARAM_FILES))
.setIssues(request.paramAsStrings(PARAM_ISSUES))
.setScopes(request.paramAsStrings(PARAM_SCOPES))
.setLanguages(request.paramAsStrings(PARAM_LANGUAGES))

+ 5
- 6
server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/SearchActionComponentsTest.java View File

@@ -77,7 +77,7 @@ import static org.sonar.db.component.ComponentTesting.newView;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_BRANCH;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_COMPONENT_KEYS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_DIRECTORIES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_FILE_UUIDS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_FILES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_MODULE_UUIDS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_PROJECTS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_PULL_REQUEST;
@@ -111,7 +111,7 @@ public class SearchActionComponentsTest {

private WsActionTester ws = new WsActionTester(
new SearchAction(userSession, issueIndex, issueQueryFactory, issueIndexSyncProgressChecker, searchResponseLoader, searchResponseFormat,
System2.INSTANCE, dbClient));
System2.INSTANCE, dbClient));

@Test
public void search_all_issues_when_no_parameter() {
@@ -242,7 +242,7 @@ public class SearchActionComponentsTest {

ws.newRequest()
.setParam(PARAM_COMPONENT_KEYS, project.getDbKey())
.setParam(PARAM_FILE_UUIDS, file.uuid())
.setParam(PARAM_FILES, file.path())
.setParam(PARAM_SINCE_LEAK_PERIOD, "true")
.execute()
.assertJson(this.getClass(), "search_since_leak_period.json");
@@ -258,12 +258,12 @@ public class SearchActionComponentsTest {
indexIssues();

ws.newRequest()
.setParam(PARAM_FILE_UUIDS, file.uuid())
.setParam(PARAM_FILES, file.path())
.execute()
.assertJson(this.getClass(), "search_by_file_uuid.json");

ws.newRequest()
.setParam(PARAM_FILE_UUIDS, "unknown")
.setParam(PARAM_FILES, "unknown")
.execute()
.assertJson(this.getClass(), "no_issue.json");
}
@@ -672,7 +672,6 @@ public class SearchActionComponentsTest {
.executeProtobuf(SearchWsResponse.class).getIssuesList())
.extracting(Issue::getKey, Issue::getComponent, Issue::getBranch)
.containsExactlyInAnyOrder(tuple(branchIssue.getKey(), branchFile.getKey(), branchFile.getBranch()));

// On file key + branch
assertThat(ws.newRequest()
.setParam(PARAM_COMPONENT_KEYS, branchFile.getKey())

+ 20
- 20
server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/SearchActionFacetsTest.java View File

@@ -68,7 +68,7 @@ import static org.sonar.server.tester.UserSessionRule.standalone;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.FACET_MODE_EFFORT;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_COMPONENT_KEYS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_COMPONENT_UUIDS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_FILE_UUIDS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_FILES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_MODULE_UUIDS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_ORGANIZATION;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_PROJECTS;
@@ -117,7 +117,7 @@ public class SearchActionFacetsTest {

SearchWsResponse response = ws.newRequest()
.setParam(PARAM_COMPONENT_KEYS, project.getKey())
.setParam(FACETS, "severities,statuses,resolutions,rules,types,languages,projects,moduleUuids,fileUuids,assignees")
.setParam(FACETS, "severities,statuses,resolutions,rules,types,languages,projects,moduleUuids,files,assignees")
.executeProtobuf(SearchWsResponse.class);

Map<String, Number> expectedStatuses = ImmutableMap.<String, Number>builder().put("OPEN", 1L).put("CONFIRMED", 0L)
@@ -134,7 +134,7 @@ public class SearchActionFacetsTest {
tuple("languages", of(rule.getLanguage(), 1L)),
tuple("projects", of(project.getKey(), 1L)),
tuple("moduleUuids", of(module.uuid(), 1L)),
tuple("fileUuids", of(file.uuid(), 1L)),
tuple("files", of(file.path(), 1L)),
tuple("assignees", of("", 0L, user.getLogin(), 1L)));
}

@@ -154,7 +154,7 @@ public class SearchActionFacetsTest {

SearchWsResponse response = ws.newRequest()
.setParam(PARAM_COMPONENT_KEYS, project.getKey())
.setParam(FACETS, "severities,statuses,resolutions,rules,types,languages,projects,fileUuids,assignees")
.setParam(FACETS, "severities,statuses,resolutions,rules,types,languages,projects,files,assignees")
.setParam("facetMode", FACET_MODE_EFFORT)
.executeProtobuf(SearchWsResponse.class);

@@ -171,7 +171,7 @@ public class SearchActionFacetsTest {
tuple("types", of("CODE_SMELL", 10L, "BUG", 0L, "VULNERABILITY", 0L)),
tuple("languages", of(rule.getLanguage(), 10L)),
tuple("projects", of(project.getKey(), 10L)),
tuple("fileUuids", of(file.uuid(), 10L)),
tuple("files", of(file.path(), 10L)),
tuple("assignees", of("", 10L)));
}

@@ -358,7 +358,7 @@ public class SearchActionFacetsTest {
}

@Test
public void display_fileUuids_facet_with_project() {
public void display_files_facet_with_project() {
OrganizationDto organization = db.organizations().insert();
ComponentDto project = db.components().insertPublicProject(organization);
ComponentDto file1 = db.components().insertComponent(newFileDto(project));
@@ -372,13 +372,13 @@ public class SearchActionFacetsTest {

SearchWsResponse response = ws.newRequest()
.setParam(PARAM_COMPONENT_KEYS, project.getKey())
.setParam(PARAM_FILE_UUIDS, file1.uuid())
.setParam(WebService.Param.FACETS, "fileUuids")
.setParam(PARAM_FILES, file1.path())
.setParam(WebService.Param.FACETS, "files")
.executeProtobuf(SearchWsResponse.class);

assertThat(response.getFacets().getFacetsList())
.extracting(Common.Facet::getProperty, facet -> facet.getValuesList().stream().collect(toMap(FacetValue::getVal, FacetValue::getCount)))
.containsExactlyInAnyOrder(tuple("fileUuids", of(file1.uuid(), 1L, file2.uuid(), 1L)));
.containsExactlyInAnyOrder(tuple("files", of(file1.path(), 1L, file2.path(), 1L)));
}

@Test
@@ -396,13 +396,13 @@ public class SearchActionFacetsTest {

SearchWsResponse response = ws.newRequest()
.setParam(PARAM_ORGANIZATION, organization.getKey())
.setParam(PARAM_FILE_UUIDS, file1.uuid())
.setParam(WebService.Param.FACETS, "fileUuids")
.setParam(PARAM_FILES, file1.path())
.setParam(WebService.Param.FACETS, "files")
.executeProtobuf(SearchWsResponse.class);

assertThat(response.getFacets().getFacetsList())
.extracting(Common.Facet::getProperty, facet -> facet.getValuesList().stream().collect(toMap(FacetValue::getVal, FacetValue::getCount)))
.containsExactlyInAnyOrder(tuple("fileUuids", of(file1.uuid(), 1L, file2.uuid(), 1L)));
.containsExactlyInAnyOrder(tuple("files", of(file1.path(), 1L, file2.path(), 1L)));
}

@Test
@@ -415,11 +415,11 @@ public class SearchActionFacetsTest {
indexIssues();

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Facet(s) 'fileUuids' require to also filter by project or organization");
expectedException.expectMessage("Facet(s) 'files' require to also filter by project or organization");

ws.newRequest()
.setParam(PARAM_FILE_UUIDS, file.uuid())
.setParam(WebService.Param.FACETS, "fileUuids")
.setParam(PARAM_FILES, file.path())
.setParam(WebService.Param.FACETS, "files")
.execute();
}

@@ -457,13 +457,13 @@ public class SearchActionFacetsTest {

SearchWsResponse response = ws.newRequest()
.setParam(PARAM_COMPONENT_KEYS, project.getKey())
.setParam(FACETS, "fileUuids,directories,moduleUuids,statuses,resolutions,severities,types,rules,languages,assignees")
.setParam(FACETS, "files,directories,moduleUuids,statuses,resolutions,severities,types,rules,languages,assignees")
.executeProtobuf(SearchWsResponse.class);

assertThat(response.getFacets().getFacetsList())
.extracting(Common.Facet::getProperty, Common.Facet::getValuesCount)
.containsExactlyInAnyOrder(
tuple("fileUuids", 100),
tuple("files", 100),
tuple("directories", 100),
tuple("moduleUuids", 100),
tuple("rules", 100),
@@ -521,12 +521,12 @@ public class SearchActionFacetsTest {
SearchWsResponse response = ws.newRequest()
.setParam(PARAM_PROJECTS, project1.getKey() + "," + project2.getKey())
.setParam(PARAM_MODULE_UUIDS, module1.uuid() + "," + module2.uuid())
.setParam(PARAM_FILE_UUIDS, file1.uuid() + "," + file2.uuid())
.setParam(PARAM_FILES, file1.path() + "," + file2.path())
.setParam("rules", rule1.getKey().toString() + "," + rule2.getKey().toString())
.setParam("severities", "MAJOR,MINOR")
.setParam("languages", rule1.getLanguage() + "," + rule2.getLanguage())
.setParam("assignees", user1.getLogin() + "," + user2.getLogin())
.setParam(FACETS, "severities,statuses,resolutions,rules,types,languages,projects,moduleUuids,fileUuids,assignees")
.setParam(FACETS, "severities,statuses,resolutions,rules,types,languages,projects,moduleUuids,files,assignees")
.executeProtobuf(SearchWsResponse.class);

Map<String, Number> expectedStatuses = ImmutableMap.<String, Number>builder().put("OPEN", 1L).put("CONFIRMED", 0L)
@@ -543,7 +543,7 @@ public class SearchActionFacetsTest {
tuple("languages", of(rule1.getLanguage(), 1L, rule2.getLanguage(), 0L)),
tuple("projects", of(project1.getKey(), 1L, project2.getKey(), 0L)),
tuple("moduleUuids", of(module1.uuid(), 1L, module2.uuid(), 0L)),
tuple("fileUuids", of(file1.uuid(), 1L, file2.uuid(), 0L)),
tuple("files", of(file1.path(), 1L, file2.path(), 0L)),
tuple("assignees", of("", 0L, user1.getLogin(), 1L, user2.getLogin(), 0L)));
}


+ 1
- 1
server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/SearchActionTest.java View File

@@ -1329,7 +1329,7 @@ public class SearchActionTest {
assertThat(def.params()).extracting("key").containsExactlyInAnyOrder(
"additionalFields", "asc", "assigned", "assignees", "authors", "author", "componentKeys", "branch",
"pullRequest", "organization",
"createdAfter", "createdAt", "createdBefore", "createdInLast", "directories", "facetMode", "facets", "fileUuids", "issues", "scopes", "languages", "moduleUuids",
"createdAfter", "createdAt", "createdBefore", "createdInLast", "directories", "facetMode", "facets", "files", "issues", "scopes", "languages", "moduleUuids",
"onComponentOnly",
"p", "projects", "ps", "resolutions", "resolved", "rules", "s", "severities", "sinceLeakPeriod",
"statuses", "tags", "types", "owaspTop10", "sansTop25", "cwe", "sonarsourceSecurity");

+ 1
- 1
sonar-ws/src/main/java/org/sonarqube/ws/client/issue/IssuesWsParameters.java View File

@@ -58,7 +58,7 @@ public class IssuesWsParameters {
public static final String PARAM_MODULE_UUIDS = "moduleUuids";
public static final String PARAM_PROJECTS = "projects";
public static final String PARAM_DIRECTORIES = "directories";
public static final String PARAM_FILE_UUIDS = "fileUuids";
public static final String PARAM_FILES = "files";
public static final String PARAM_ON_COMPONENT_ONLY = "onComponentOnly";
public static final String PARAM_BRANCH = "branch";
public static final String PARAM_PULL_REQUEST = "pullRequest";

Loading…
Cancel
Save