aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien HENRY <julien.henry@sonarsource.com>2017-07-26 17:48:32 +0200
committerJulien HENRY <julien.henry@sonarsource.com>2017-07-26 17:48:32 +0200
commitf4c2e0eb9afe66f5e71e9f1447f059dd15b143ff (patch)
treefe33a427dd5901f8b3c5557cac2fd31166540d9c
parent104fffdee215450819881fa7ce8a92272c292c84 (diff)
downloadsonarqube-f4c2e0eb9afe66f5e71e9f1447f059dd15b143ff.tar.gz
sonarqube-f4c2e0eb9afe66f5e71e9f1447f059dd15b143ff.zip
SONAR-9584 Add root project key to response of api/components/search
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDto.java17
-rw-r--r--server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml7
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentDaoTest.java21
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchAction.java3
-rw-r--r--server/sonar-server/src/main/resources/org/sonar/server/component/ws/search-components-example.json12
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java23
-rw-r--r--sonar-ws/src/main/protobuf/ws-components.proto2
7 files changed, 76 insertions, 9 deletions
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDto.java
index 215a248c0c4..797dfb1f57a 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDto.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDto.java
@@ -61,6 +61,11 @@ public class ComponentDto implements Component {
private String kee;
/**
+ * Key of the root component this component belongs to. Consistent with projectUUid.
+ */
+ private String projectKey;
+
+ /**
* Not empty . Max size is 50 (note that effective UUID values are 40 characters with
* the current algorithm in use). Obviously it is unique.
* It is generated by Compute Engine.
@@ -221,6 +226,18 @@ public class ComponentDto implements Component {
return this;
}
+ /**
+ * Return the root project key. On a root project, return itself
+ */
+ public String projectKey() {
+ return projectKey;
+ }
+
+ public ComponentDto setProjectKey(String projectKey) {
+ this.projectKey = projectKey;
+ return this;
+ }
+
public boolean isRoot() {
return UUID_PATH_OF_ROOT.equals(uuidPath);
}
diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml
index fecf8cf8715..b9939aabb1c 100644
--- a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml
+++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml
@@ -238,18 +238,21 @@
<select id="selectByQuery" resultType="Component">
select
- <include refid="componentColumns"/>
+ <include refid="componentColumns"/>,
+ root.kee as projectKey
+ from projects p
+ inner join projects root on p.project_uuid=root.uuid and p.organization_uuid=root.organization_uuid
<include refid="sqlSelectByQuery"/>
ORDER BY LOWER(p.name), p.name, p.id
</select>
<select id="countByQuery" resultType="int">
select count(p.id)
+ from projects p
<include refid="sqlSelectByQuery"/>
</select>
<sql id="sqlSelectByQuery">
- from projects p
where
p.enabled=${_true}
AND p.copy_component_uuid is null
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentDaoTest.java
index c9c83436a8e..997131fb86b 100644
--- a/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentDaoTest.java
+++ b/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentDaoTest.java
@@ -47,6 +47,7 @@ import static java.util.Collections.emptyList;
import static java.util.Collections.emptySet;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
import static org.assertj.guava.api.Assertions.assertThat;
import static org.sonar.db.component.ComponentTesting.newDirectory;
import static org.sonar.db.component.ComponentTesting.newFileDto;
@@ -547,7 +548,8 @@ public class ComponentDaoTest {
@Test
public void select_provisioned() {
OrganizationDto organization = db.organizations().insert();
- ComponentDto provisionedProject = db.components().insertComponent(ComponentTesting.newPrivateProjectDto(organization).setKey("provisioned.project").setName("Provisioned Project"));
+ ComponentDto provisionedProject = db.components()
+ .insertComponent(ComponentTesting.newPrivateProjectDto(organization).setKey("provisioned.project").setName("Provisioned Project"));
ComponentDto provisionedView = db.components().insertView(organization);
String projectUuid = db.components().insertProjectAndSnapshot(ComponentTesting.newPrivateProjectDto(organization)).getComponentUuid();
String disabledProjectUuid = db.components().insertProjectAndSnapshot(ComponentTesting.newPrivateProjectDto(organization).setEnabled(false)).getComponentUuid();
@@ -967,6 +969,23 @@ public class ComponentDaoTest {
}
@Test
+ public void selectByQuery_returns_projectKey() {
+ ComponentDto project = ComponentTesting.newPublicProjectDto(db.getDefaultOrganization()).setKey("project-key");
+ db.components().insertComponent(project);
+ ComponentDto module = ComponentTesting.newModuleDto(project).setKey("module-key");
+ db.components().insertComponent(module);
+ ComponentDto file = ComponentTesting.newFileDto(module).setKey("file-key");
+ db.components().insertComponent(file);
+
+ ComponentQuery allQuery = ComponentQuery.builder().setQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE, Qualifiers.FILE).build();
+
+ assertThat(underTest.selectByQuery(dbSession, allQuery, 0, 10)).extracting(ComponentDto::getKey, ComponentDto::projectKey)
+ .containsOnly(tuple("project-key", "project-key"),
+ tuple("module-key", "project-key"),
+ tuple("file-key", "project-key"));
+ }
+
+ @Test
public void selectByQuery_on_empty_list_of_component_id() {
ComponentQuery dbQuery = ComponentQuery.builder().setQualifiers(Qualifiers.PROJECT).setComponentIds(emptySet()).build();
List<ComponentDto> result = underTest.selectByQuery(dbSession, dbQuery, 0, 10);
diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchAction.java
index 658de71faa9..b26ae50b54c 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchAction.java
@@ -46,8 +46,8 @@ import static com.google.common.base.Preconditions.checkArgument;
import static org.sonar.core.util.Protobuf.setNullable;
import static org.sonar.server.util.LanguageParamUtils.getExampleValue;
import static org.sonar.server.util.LanguageParamUtils.getLanguageKeys;
-import static org.sonar.server.ws.WsParameterBuilder.QualifierParameterContext.newQualifierParameterContext;
import static org.sonar.server.ws.WsParameterBuilder.createQualifiersParameter;
+import static org.sonar.server.ws.WsParameterBuilder.QualifierParameterContext.newQualifierParameterContext;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_SEARCH;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_LANGUAGE;
@@ -179,6 +179,7 @@ public class SearchAction implements ComponentsWsAction {
.setOrganization(organization.getKey())
.setId(dto.uuid())
.setKey(dto.key())
+ .setProjectKey(dto.projectKey())
.setName(dto.name())
.setQualifier(dto.qualifier());
setNullable(dto.language(), builder::setLanguage);
diff --git a/server/sonar-server/src/main/resources/org/sonar/server/component/ws/search-components-example.json b/server/sonar-server/src/main/resources/org/sonar/server/component/ws/search-components-example.json
index dafce933828..8f86a13f6ed 100644
--- a/server/sonar-server/src/main/resources/org/sonar/server/component/ws/search-components-example.json
+++ b/server/sonar-server/src/main/resources/org/sonar/server/component/ws/search-components-example.json
@@ -10,7 +10,8 @@
"id": "directory-uuid",
"key": "directory-key",
"qualifier": "DIR",
- "name": "Directory Name"
+ "name": "Directory Name",
+ "projectKey": "project-key"
},
{
"organization": "my-org-1",
@@ -18,21 +19,24 @@
"key": "file-key",
"qualifier": "FIL",
"name": "File Name",
- "language": "java"
+ "language": "java",
+ "projectKey": "project-key"
},
{
"organization": "my-org-1",
"id": "module-uuid",
"key": "module-key",
"qualifier": "BRC",
- "name": "Module Name"
+ "name": "Module Name",
+ "projectKey": "project-key"
},
{
"organization": "my-org-1",
"id": "project-uuid",
"key": "project-key",
"qualifier": "TRK",
- "name": "Project Name"
+ "name": "Project Name",
+ "projectKey": "project-key"
}
]
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java
index 0a22c4c68da..ac1651bc67d 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java
@@ -45,11 +45,14 @@ import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.WsActionTester;
import org.sonarqube.ws.MediaTypes;
+import org.sonarqube.ws.WsComponents.Component;
import org.sonarqube.ws.WsComponents.SearchWsResponse;
import org.sonarqube.ws.client.component.SearchWsRequest;
+import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.api.resources.Qualifiers.DIRECTORY;
@@ -66,7 +69,6 @@ import static org.sonar.db.component.ComponentTesting.newModuleDto;
import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
import static org.sonar.db.component.ComponentTesting.newView;
import static org.sonar.test.JsonAssert.assertJson;
-import static org.sonarqube.ws.WsComponents.Component;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_LANGUAGE;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_ORGANIZATION;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_QUALIFIERS;
@@ -186,6 +188,25 @@ public class SearchActionTest {
}
@Test
+ public void return_project_key() throws IOException {
+ ComponentDto project = ComponentTesting.newPublicProjectDto(db.getDefaultOrganization());
+ ComponentDto module = ComponentTesting.newModuleDto(project);
+ ComponentDto file1 = newFileDto(module).setKey("file1");
+ ComponentDto file2 = newFileDto(module).setKey("file2");
+ ComponentDto file3 = newFileDto(project).setKey("file3");
+ db.components().insertComponents(project, module, file1, file2, file3);
+
+ SearchWsResponse response = call(new SearchWsRequest().setQualifiers(asList(PROJECT, MODULE, FILE)));
+
+ assertThat(response.getComponentsList()).extracting(Component::getKey, Component::getProjectKey)
+ .containsOnly(tuple(project.getKey(), project.getKey()),
+ tuple(module.getKey(), project.getKey()),
+ tuple(file1.getKey(), project.getKey()),
+ tuple(file2.getKey(), project.getKey()),
+ tuple(file3.getKey(), project.getKey()));
+ }
+
+ @Test
public void do_not_verify_permissions_if_user_is_root() throws IOException {
OrganizationDto org = db.organizations().insert();
ComponentDto project1 = ComponentTesting.newPrivateProjectDto(org);
diff --git a/sonar-ws/src/main/protobuf/ws-components.proto b/sonar-ws/src/main/protobuf/ws-components.proto
index 58b02d9687c..4a7fe369ced 100644
--- a/sonar-ws/src/main/protobuf/ws-components.proto
+++ b/sonar-ws/src/main/protobuf/ws-components.proto
@@ -118,6 +118,8 @@ message Component {
optional Tags tags = 14;
optional string visibility = 15;
optional string leakPeriodDate = 16;
+ // Root project key
+ optional string projectKey = 17;
message Tags {
repeated string tags = 1;