@@ -32,6 +32,7 @@ import javax.annotation.Nullable; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.issue.IssueChangeDto; | |||
import org.sonar.db.issue.IssueDto; | |||
import org.sonar.db.organization.OrganizationDto; | |||
import org.sonar.db.rule.RuleDto; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.server.issue.workflow.Transition; | |||
@@ -48,6 +49,7 @@ public class SearchResponseData { | |||
private Long effortTotal = null; | |||
private List<UserDto> users = null; | |||
private List<RuleDto> rules = null; | |||
private final Map<String, String> organizationKeysByUuid = new HashMap<>(); | |||
private final Map<String, ComponentDto> componentsByUuid = new HashMap<>(); | |||
private final ListMultimap<String, IssueChangeDto> commentsByIssueKey = ArrayListMultimap.create(); | |||
private final ListMultimap<String, String> actionsByIssueKey = ArrayListMultimap.create(); | |||
@@ -83,6 +85,12 @@ public class SearchResponseData { | |||
return rules; | |||
} | |||
public String getOrganizationKey(String organizationUuid) { | |||
String organizationKey = organizationKeysByUuid.get(organizationUuid); | |||
checkNotNull(organizationKey, "Organization for uuid '%s' not found", organizationUuid); | |||
return organizationKey; | |||
} | |||
@CheckForNull | |||
public List<IssueChangeDto> getCommentsForIssueKey(String issueKey) { | |||
if (commentsByIssueKey.containsKey(issueKey)) { | |||
@@ -153,4 +161,8 @@ public class SearchResponseData { | |||
public void setEffortTotal(@Nullable Long effortTotal) { | |||
this.effortTotal = effortTotal; | |||
} | |||
public void addOrganization(OrganizationDto organizationDto) { | |||
this.organizationKeysByUuid.put(organizationDto.getUuid(), organizationDto.getKey()); | |||
} | |||
} |
@@ -146,6 +146,7 @@ public class SearchResponseFormat { | |||
setNullable(dto.getType(), issueBuilder::setType, Common.RuleType::valueOf); | |||
ComponentDto component = data.getComponentByUuid(dto.getComponentUuid()); | |||
issueBuilder.setOrganization(data.getOrganizationKey(component.getOrganizationUuid())); | |||
issueBuilder.setComponent(component.key()); | |||
// Only used for the compatibility with the Java WS Client <= 4.4 used by Eclipse | |||
issueBuilder.setComponentId(component.getId()); | |||
@@ -285,36 +286,38 @@ public class SearchResponseFormat { | |||
} | |||
private static List<Issues.Component> formatComponents(SearchResponseData data) { | |||
List<Issues.Component> result = new ArrayList<>(); | |||
Collection<ComponentDto> components = data.getComponents(); | |||
if (components != null) { | |||
for (ComponentDto dto : components) { | |||
String uuid = dto.uuid(); | |||
Issues.Component.Builder builder = Issues.Component.newBuilder() | |||
.setId(dto.getId()) | |||
.setKey(dto.key()) | |||
.setUuid(uuid) | |||
.setQualifier(dto.qualifier()) | |||
.setName(nullToEmpty(dto.name())) | |||
.setLongName(nullToEmpty(dto.longName())) | |||
.setEnabled(dto.isEnabled()); | |||
String path = dto.path(); | |||
// path is not applicable to the components that are not files. | |||
// Value must not be "" in this case. | |||
if (!Strings.isNullOrEmpty(path)) { | |||
builder.setPath(path); | |||
} | |||
if (components == null) { | |||
return Collections.emptyList(); | |||
} | |||
List<Issues.Component> result = new ArrayList<>(); | |||
for (ComponentDto dto : components) { | |||
String uuid = dto.uuid(); | |||
Issues.Component.Builder builder = Issues.Component.newBuilder() | |||
.setOrganization(data.getOrganizationKey(dto.getOrganizationUuid())) | |||
.setId(dto.getId()) | |||
.setKey(dto.key()) | |||
.setUuid(uuid) | |||
.setQualifier(dto.qualifier()) | |||
.setName(nullToEmpty(dto.name())) | |||
.setLongName(nullToEmpty(dto.longName())) | |||
.setEnabled(dto.isEnabled()); | |||
String path = dto.path(); | |||
// path is not applicable to the components that are not files. | |||
// Value must not be "" in this case. | |||
if (!Strings.isNullOrEmpty(path)) { | |||
builder.setPath(path); | |||
} | |||
// On a root project, parentProjectId is null but projectId is equal to itself, which make no sense. | |||
if (!uuid.equals(dto.getRootUuid())) { | |||
ComponentDto project = data.getComponentByUuid(dto.projectUuid()); | |||
setNullable(project, builder::setProjectId, ComponentDto::getId); | |||
// On a root project, parentProjectId is null but projectId is equal to itself, which make no sense. | |||
if (!uuid.equals(dto.getRootUuid())) { | |||
ComponentDto project = data.getComponentByUuid(dto.projectUuid()); | |||
setNullable(project, builder::setProjectId, ComponentDto::getId); | |||
ComponentDto subProject = data.getComponentByUuid(dto.getRootUuid()); | |||
setNullable(subProject, builder::setSubProjectId, ComponentDto::getId); | |||
} | |||
result.add(builder.build()); | |||
ComponentDto subProject = data.getComponentByUuid(dto.getRootUuid()); | |||
setNullable(subProject, builder::setSubProjectId, ComponentDto::getId); | |||
} | |||
result.add(builder.build()); | |||
} | |||
return result; | |||
} |
@@ -30,6 +30,7 @@ import java.util.Set; | |||
import javax.annotation.Nullable; | |||
import org.sonar.api.rule.RuleKey; | |||
import org.sonar.core.issue.DefaultIssue; | |||
import org.sonar.core.util.stream.Collectors; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.component.ComponentDto; | |||
@@ -81,6 +82,7 @@ public class SearchResponseLoader { | |||
loadComments(collector, dbSession, result); | |||
loadUsers(collector, dbSession, result); | |||
loadComponents(collector, dbSession, result); | |||
loadOrganizations(dbSession, result); | |||
loadActionsAndTransitions(collector, result); | |||
completeTotalEffortFromFacet(facets, result); | |||
return result; | |||
@@ -130,6 +132,17 @@ public class SearchResponseLoader { | |||
result.addComponents(projects); | |||
} | |||
private void loadOrganizations(DbSession dbSession, SearchResponseData result) { | |||
Collection<ComponentDto> components = result.getComponents(); | |||
if (components == null) { | |||
return; | |||
} | |||
dbClient.organizationDao().selectByUuids( | |||
dbSession, | |||
components.stream().map(ComponentDto::getOrganizationUuid).collect(Collectors.toSet())) | |||
.forEach(result::addOrganization); | |||
} | |||
private void loadActionsAndTransitions(Collector collector, SearchResponseData result) { | |||
if (collector.contains(ACTIONS) || collector.contains(TRANSITIONS)) { | |||
for (IssueDto dto : result.getIssues()) { |
@@ -172,7 +172,7 @@ public class SearchActionMediumTest { | |||
db.userDao().insert(session, new UserDto().setLogin("john").setName("John")); | |||
db.userDao().insert(session, new UserDto().setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com")); | |||
ComponentDto project = insertComponent(ComponentTesting.newProjectDto(defaultOrganization, "PROJECT_ID").setKey("PROJECT_KEY")); | |||
ComponentDto project = insertComponent(ComponentTesting.newProjectDto(otherOrganization2, "PROJECT_ID").setKey("PROJECT_KEY")); | |||
setDefaultProjectPermission(project); | |||
ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setKey("FILE_KEY")); | |||
IssueDto issue = IssueTesting.newDto(newRule(), file, project) | |||
@@ -283,7 +283,7 @@ public class SearchActionMediumTest { | |||
@Test | |||
public void issue_on_removed_file() throws Exception { | |||
RuleDto rule = newRule(); | |||
ComponentDto project = insertComponent(ComponentTesting.newProjectDto(defaultOrganization, "PROJECT_ID").setKey("PROJECT_KEY")); | |||
ComponentDto project = insertComponent(ComponentTesting.newProjectDto(otherOrganization2, "PROJECT_ID").setKey("PROJECT_KEY")); | |||
setDefaultProjectPermission(project); | |||
ComponentDto removedFile = insertComponent(ComponentTesting.newFileDto(project, null).setUuid("REMOVED_FILE_ID") | |||
.setKey("REMOVED_FILE_KEY") | |||
@@ -338,7 +338,7 @@ public class SearchActionMediumTest { | |||
@Test | |||
public void components_contains_sub_projects() throws Exception { | |||
ComponentDto project = insertComponent(ComponentTesting.newProjectDto(defaultOrganization, "PROJECT_ID").setKey("ProjectHavingModule")); | |||
ComponentDto project = insertComponent(ComponentTesting.newProjectDto(otherOrganization1, "PROJECT_ID").setKey("ProjectHavingModule")); | |||
setDefaultProjectPermission(project); | |||
ComponentDto module = insertComponent(ComponentTesting.newModuleDto(project).setKey("ModuleHavingFile")); | |||
ComponentDto file = insertComponent(ComponentTesting.newFileDto(module, null, "BCDE").setKey("FileLinkedToModule")); | |||
@@ -377,7 +377,7 @@ public class SearchActionMediumTest { | |||
@Test | |||
public void display_facets_in_effort_mode() throws Exception { | |||
ComponentDto project = insertComponent(ComponentTesting.newProjectDto(defaultOrganization, "PROJECT_ID").setKey("PROJECT_KEY")); | |||
ComponentDto project = insertComponent(ComponentTesting.newProjectDto(otherOrganization2, "PROJECT_ID").setKey("PROJECT_KEY")); | |||
setDefaultProjectPermission(project); | |||
ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setKey("FILE_KEY")); | |||
IssueDto issue = IssueTesting.newDto(newRule(), file, project) | |||
@@ -560,7 +560,7 @@ public class SearchActionMediumTest { | |||
@Test | |||
public void sort_by_updated_at() throws Exception { | |||
RuleDto rule = newRule(); | |||
ComponentDto project = insertComponent(ComponentTesting.newProjectDto(defaultOrganization, "PROJECT_ID").setKey("PROJECT_KEY")); | |||
ComponentDto project = insertComponent(ComponentTesting.newProjectDto(otherOrganization2, "PROJECT_ID").setKey("PROJECT_KEY")); | |||
setDefaultProjectPermission(project); | |||
ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setKey("FILE_KEY")); | |||
db.issueDao().insert(session, IssueTesting.newDto(rule, file, project) |
@@ -1,6 +1,7 @@ | |||
{ | |||
"issues": [ | |||
{ | |||
"organization": "my-org-2", | |||
"key": "7b112bd4-b650-4037-80bc-82fd47d4eac2", | |||
"component": "FILE_KEY", | |||
"rule": "xoo:x1", |
@@ -1,12 +1,15 @@ | |||
{ | |||
"components": [ | |||
{ | |||
"organization": "my-org-1", | |||
"key": "FileLinkedToModule" | |||
}, | |||
{ | |||
"organization": "my-org-1", | |||
"key": "ModuleHavingFile" | |||
}, | |||
{ | |||
"organization": "my-org-1", | |||
"key": "ProjectHavingModule" | |||
} | |||
] |
@@ -3,6 +3,7 @@ | |||
"effortTotal": 10, | |||
"issues": [ | |||
{ | |||
"organization": "my-org-1", | |||
"key": "82fd47d4-b650-4037-80bc-7b112bd4eac2", | |||
"component": "FILE_KEY", | |||
"project": "PROJECT_KEY", |
@@ -1,6 +1,7 @@ | |||
{ | |||
"issues": [ | |||
{ | |||
"organization": "my-org-1", | |||
"key": "82fd47d4-b650-4037-80bc-7b112bd4eac2", | |||
"component": "FILE_KEY", | |||
"rule": "xoo:x1", |
@@ -2,6 +2,7 @@ | |||
"effortTotal": 10, | |||
"issues": [ | |||
{ | |||
"organization": "my-org-2", | |||
"key": "82fd47d4-b650-4037-80bc-7b112bd4eac2", | |||
"component": "FILE_KEY", | |||
"project": "PROJECT_KEY", |
@@ -1,6 +1,7 @@ | |||
{ | |||
"issues": [ | |||
{ | |||
"organization": "my-org-1", | |||
"key": "82fd47d4-b650-4037-80bc-7b112bd4eac2", | |||
"component": "FILE_KEY", | |||
"project": "PROJECT_KEY", |
@@ -1,6 +1,7 @@ | |||
{ | |||
"issues": [ | |||
{ | |||
"organization": "my-org-2", | |||
"key": "82fd47d4-b650-4037-80bc-7b112bd4eac2", | |||
"component": "REMOVED_FILE_KEY", | |||
"project": "PROJECT_KEY", | |||
@@ -13,10 +14,12 @@ | |||
], | |||
"components": [ | |||
{ | |||
"organization": "my-org-2", | |||
"key": "REMOVED_FILE_KEY", | |||
"enabled" : false | |||
}, | |||
{ | |||
"organization": "my-org-2", | |||
"key": "PROJECT_KEY", | |||
"enabled" : true | |||
} |
@@ -1,17 +0,0 @@ | |||
{ | |||
"issues": [ | |||
{ | |||
"key": "82fd47d4-b650-4037-80bc-7b112bd4eac2", | |||
"actionPlan": "AP-ABCD" | |||
} | |||
], | |||
"actionPlans": [ | |||
{ | |||
"key": "AP-ABCD", | |||
"name": "1.0", | |||
"status": "OPEN", | |||
"deadLine": "2014-01-24T19:10:03+0000", | |||
"project": "PROJECT_KEY" | |||
} | |||
] | |||
} |
@@ -1,10 +0,0 @@ | |||
{ | |||
"issues": [ | |||
{ | |||
"key": "82fd47d4-b650-4037-80bc-7b112bd4eac2", | |||
"attr": { | |||
"jira-issue-key": "SONAR-1234" | |||
} | |||
} | |||
] | |||
} |
@@ -1,6 +1,7 @@ | |||
{ | |||
"issues": [ | |||
{ | |||
"organization": "my-org-1", | |||
"key": "82fd47d4-b650-4037-80bc-7b112bd4eac2" | |||
} | |||
] |
@@ -1,6 +1,7 @@ | |||
{ | |||
"issues": [ | |||
{ | |||
"organization": "my-org-2", | |||
"key": "82fd47d4-b650-4037-80bc-7b112bd4eac2", | |||
"rule": "xoo:x1", | |||
"severity": "MAJOR", |
@@ -1,6 +1,7 @@ | |||
{ | |||
"issues": [ | |||
{ | |||
"organization": "my-org-2", | |||
"key": "82fd47d4-b650-4037-80bc-7b112bd4eac2", | |||
"assignee": "simon", | |||
"actions": [ |
@@ -1,6 +1,7 @@ | |||
{ | |||
"issues": [ | |||
{ | |||
"organization": "my-org-1", | |||
"key": "82fd47d4-b650-4037-80bc-7b112bd4eac2", | |||
"assignee": "simon", | |||
"actions": [ |
@@ -1,6 +1,7 @@ | |||
{ | |||
"issues": [ | |||
{ | |||
"organization": "my-org-2", | |||
"key": "82fd47d4-b650-4037-80bc-7b112bd4eac2", | |||
"rule": "xoo:x1", | |||
"severity": "MAJOR", |
@@ -1,6 +1,7 @@ | |||
{ | |||
"issues": [ | |||
{ | |||
"organization": "my-org-2", | |||
"key": "82fd47d4-b650-4037-80bc-7b112bd4eac2", | |||
"component": "FILE_KEY", | |||
"project": "PROJECT_KEY", | |||
@@ -8,6 +9,7 @@ | |||
"updateDate": "2014-11-01T00:00:00+0100" | |||
}, | |||
{ | |||
"organization": "my-org-2", | |||
"key": "82fd47d4-b650-4037-80bc-7b112bd4eac1", | |||
"component": "FILE_KEY", | |||
"project": "PROJECT_KEY", | |||
@@ -15,6 +17,7 @@ | |||
"updateDate": "2014-11-02T00:00:00+0100" | |||
}, | |||
{ | |||
"organization": "my-org-2", | |||
"key": "82fd47d4-b650-4037-80bc-7b112bd4eac3", | |||
"component": "FILE_KEY", | |||
"project": "PROJECT_KEY", |
@@ -60,6 +60,7 @@ message Operation { | |||
} | |||
message Issue { | |||
optional string organization = 29; | |||
optional string key = 1; | |||
optional string rule = 2; | |||
optional sonarqube.ws.commons.Severity severity = 3; | |||
@@ -170,6 +171,7 @@ message Languages { | |||
} | |||
message Component { | |||
optional string organization = 11; | |||
optional int64 id = 1; | |||
optional string key = 2; | |||
optional string uuid = 3; |