aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2017-08-16 20:06:36 +0200
committerJanos Gyerik <janos.gyerik@sonarsource.com>2017-09-12 10:59:56 +0200
commitd9b502eb1f50437f06aeafde6bf0a4ff0694e0aa (patch)
tree6654645dfb1521eccced75fe27aeace021674f0e
parentf48d90a276b5e962d2658bbf1a9fe2dc5af1064f (diff)
downloadsonarqube-d9b502eb1f50437f06aeafde6bf0a4ff0694e0aa.tar.gz
sonarqube-d9b502eb1f50437f06aeafde6bf0a4ff0694e0aa.zip
SONAR-9616 Return branch info in api/ce ws
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeTaskCharacteristicDto.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/ce/ws/ActivityAction.java3
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/ce/ws/ComponentAction.java29
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/ce/ws/TaskAction.java4
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/ce/ws/TaskFormatter.java64
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/ce/ws/ActivityActionTest.java46
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/ce/ws/ComponentActionTest.java98
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/ce/ws/TaskActionTest.java48
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/ce/CeWsParameters.java1
-rw-r--r--sonar-ws/src/main/protobuf/ws-ce.proto2
10 files changed, 270 insertions, 27 deletions
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeTaskCharacteristicDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeTaskCharacteristicDto.java
index 06fbcfac5c8..7a60a07f986 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeTaskCharacteristicDto.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeTaskCharacteristicDto.java
@@ -22,6 +22,8 @@ package org.sonar.db.ce;
public class CeTaskCharacteristicDto {
public static final String INCREMENTAL_KEY = "incremental";
+ public static final String BRANCH_KEY = "branch";
+ public static final String BRANCH_TYPE_KEY = "branchType";
private String uuid;
private String taskUuid;
diff --git a/server/sonar-server/src/main/java/org/sonar/server/ce/ws/ActivityAction.java b/server/sonar-server/src/main/java/org/sonar/server/ce/ws/ActivityAction.java
index 928a4bdc80e..598a574e6fa 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/ce/ws/ActivityAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/ce/ws/ActivityAction.java
@@ -101,7 +101,8 @@ public class ActivityAction implements CeWsAction {
.setChangelog(
new Change("5.5", "it's no more possible to specify the page parameter.<"),
new Change("6.1", "field \"logs\" is deprecated and its value is always false"),
- new Change("6.6", "field \"incremental\" is added"))
+ new Change("6.6", "field \"incremental\" is added"),
+ new Change("6.6", "fields \"branch\" and \"branchType\" added"))
.setSince("5.2");
action.createParam(PARAM_COMPONENT_ID)
diff --git a/server/sonar-server/src/main/java/org/sonar/server/ce/ws/ComponentAction.java b/server/sonar-server/src/main/java/org/sonar/server/ce/ws/ComponentAction.java
index ae371a6b37c..a842073aaba 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/ce/ws/ComponentAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/ce/ws/ComponentAction.java
@@ -36,16 +36,18 @@ import org.sonar.server.component.ComponentFinder;
import org.sonar.server.user.UserSession;
import org.sonar.server.ws.KeyExamples;
+import static com.google.common.base.Preconditions.checkArgument;
import static org.sonar.db.Pagination.forPage;
import static org.sonar.server.component.ComponentFinder.ParamNames.COMPONENT_ID_AND_KEY;
+import static org.sonar.server.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
import static org.sonarqube.ws.WsCe.ProjectResponse;
+import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_BRANCH;
+import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_COMPONENT_ID;
+import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_COMPONENT_KEY;
public class ComponentAction implements CeWsAction {
- public static final String PARAM_COMPONENT_ID = "componentId";
- public static final String PARAM_COMPONENT_KEY = "componentKey";
-
private final UserSession userSession;
private final DbClient dbClient;
private final TaskFormatter formatter;
@@ -69,7 +71,8 @@ public class ComponentAction implements CeWsAction {
.setResponseExample(getClass().getResource("component-example.json"))
.setChangelog(
new Change("6.1", "field \"logs\" is deprecated and its value is always false"),
- new Change("6.6", "field \"incremental\" is added"))
+ new Change("6.6", "field \"incremental\" is added"),
+ new Change("6.6", "fields \"branch\" and \"branchType\" added"))
.setHandler(this);
action.createParam(PARAM_COMPONENT_ID)
@@ -79,12 +82,17 @@ public class ComponentAction implements CeWsAction {
action.createParam(PARAM_COMPONENT_KEY)
.setRequired(false)
.setExampleValue(KeyExamples.KEY_PROJECT_EXAMPLE_001);
+
+ action.createParam(PARAM_BRANCH)
+ .setDescription("Branch key")
+ .setInternal(true)
+ .setExampleValue(KEY_BRANCH_EXAMPLE_001);
}
@Override
public void handle(Request wsRequest, Response wsResponse) throws Exception {
try (DbSession dbSession = dbClient.openSession(false)) {
- ComponentDto component = componentFinder.getByUuidOrKey(dbSession, wsRequest.param(PARAM_COMPONENT_ID), wsRequest.param(PARAM_COMPONENT_KEY), COMPONENT_ID_AND_KEY);
+ ComponentDto component = loadComponent(dbSession, wsRequest);
userSession.checkComponentPermission(UserRole.USER, component);
List<CeQueueDto> queueDtos = dbClient.ceQueueDao().selectByComponentUuid(dbSession, component.uuid());
CeTaskQuery activityQuery = new CeTaskQuery()
@@ -100,4 +108,15 @@ public class ComponentAction implements CeWsAction {
writeProtobuf(wsResponseBuilder.build(), wsRequest, wsResponse);
}
}
+
+ private ComponentDto loadComponent(DbSession dbSession, Request wsRequest) {
+ String componentKey = wsRequest.param(PARAM_COMPONENT_KEY);
+ String componentId = wsRequest.param(PARAM_COMPONENT_ID);
+ String branch = wsRequest.param(PARAM_BRANCH);
+ checkArgument(componentId == null || branch == null, "'%s' and '%s' parameters cannot be used at the same time", PARAM_COMPONENT_ID,
+ PARAM_BRANCH);
+ return branch == null
+ ? componentFinder.getByUuidOrKey(dbSession, componentId, componentKey, COMPONENT_ID_AND_KEY)
+ : componentFinder.getByKeyAndBranch(dbSession, componentKey, branch);
+ }
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/ce/ws/TaskAction.java b/server/sonar-server/src/main/java/org/sonar/server/ce/ws/TaskAction.java
index ed086869839..40b7b408928 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/ce/ws/TaskAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/ce/ws/TaskAction.java
@@ -73,7 +73,9 @@ public class TaskAction implements CeWsAction {
"Since 6.1, field \"logs\" is deprecated and its value is always false.")
.setResponseExample(getClass().getResource("task-example.json"))
.setSince("5.2")
- .setChangelog(new Change("6.6", "field \"incremental\" is added"))
+ .setChangelog(
+ new Change("6.6", "field \"incremental\" is added"),
+ new Change("6.6", "fields \"branch\" and \"branchType\" added"))
.setHandler(this);
action
diff --git a/server/sonar-server/src/main/java/org/sonar/server/ce/ws/TaskFormatter.java b/server/sonar-server/src/main/java/org/sonar/server/ce/ws/TaskFormatter.java
index a148896ab15..6e218184800 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/ce/ws/TaskFormatter.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/ce/ws/TaskFormatter.java
@@ -27,6 +27,7 @@ import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.CheckForNull;
@@ -39,12 +40,15 @@ import org.sonar.db.DbSession;
import org.sonar.db.ce.CeActivityDto;
import org.sonar.db.ce.CeQueueDto;
import org.sonar.db.ce.CeTaskCharacteristicDto;
+import org.sonar.db.component.BranchDto;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.SnapshotDto;
import org.sonar.db.organization.OrganizationDto;
+import org.sonarqube.ws.Common;
import org.sonarqube.ws.WsCe;
import static com.google.common.base.Preconditions.checkState;
+import static java.lang.String.format;
import static java.util.Collections.singletonList;
import static org.sonar.api.utils.DateUtils.formatDateTime;
import static org.sonar.core.util.Protobuf.setNullable;
@@ -79,7 +83,7 @@ public class TaskFormatter {
setNullable(organizationKey, builder::setOrganization);
if (dto.getComponentUuid() != null) {
builder.setComponentId(dto.getComponentUuid());
- buildComponent(builder, componentDtoCache.getComponent(dto.getComponentUuid()));
+ buildComponent(builder, dto.getComponentUuid(), componentDtoCache);
}
builder.setId(dto.getUuid());
builder.setStatus(WsCe.TaskStatus.valueOf(dto.getStatus().name()));
@@ -90,6 +94,12 @@ public class TaskFormatter {
setNullable(dto.getStartedAt(), builder::setStartedAt, DateUtils::formatDateTime);
setNullable(computeExecutionTimeMs(dto), builder::setExecutionTimeMs);
builder.setIncremental(componentDtoCache.hasIncrementalCharacteristic(dto.getUuid()));
+ componentDtoCache.getBranchName(dto.getUuid()).ifPresent(
+ b -> {
+ builder.setBranch(b);
+ builder.setBranchType(componentDtoCache.getBranchType(dto.getUuid())
+ .orElseThrow(() -> new IllegalStateException(format("Could not find branch type of '%s'", dto.getUuid()))));
+ });
return builder.build();
}
@@ -113,7 +123,7 @@ public class TaskFormatter {
builder.setStatus(WsCe.TaskStatus.valueOf(dto.getStatus().name()));
builder.setType(dto.getTaskType());
builder.setLogs(false);
- setNullable(dto.getComponentUuid(), uuid -> buildComponent(builder, componentDtoCache.getComponent(uuid)).setComponentId(uuid));
+ setNullable(dto.getComponentUuid(), uuid -> buildComponent(builder, uuid, componentDtoCache).setComponentId(uuid));
String analysisUuid = dto.getAnalysisUuid();
if (analysisUuid != null) {
builder.setAnalysisId(analysisUuid);
@@ -133,12 +143,20 @@ public class TaskFormatter {
return builder.build();
}
- private static WsCe.Task.Builder buildComponent(WsCe.Task.Builder builder, @Nullable ComponentDto componentDto) {
- if (componentDto != null) {
- builder.setComponentKey(componentDto.getDbKey());
- builder.setComponentName(componentDto.name());
- builder.setComponentQualifier(componentDto.qualifier());
+ private static WsCe.Task.Builder buildComponent(WsCe.Task.Builder builder, @Nullable String componentUuid, DtoCache componentDtoCache) {
+ ComponentDto componentDto = componentDtoCache.getComponent(componentUuid);
+ if (componentDto == null) {
+ return builder;
}
+ builder.setComponentKey(componentDto.getKey());
+ builder.setComponentName(componentDto.name());
+ builder.setComponentQualifier(componentDto.qualifier());
+ String branch = componentDto.getBranch();
+ if (branch == null) {
+ return builder;
+ }
+ builder.setBranch(branch);
+ builder.setBranchType(Common.BranchType.valueOf(componentDtoCache.getBranch(componentUuid).getBranchType().name()));
return builder;
}
@@ -146,14 +164,16 @@ public class TaskFormatter {
private final Map<String, ComponentDto> componentsByUuid;
private final Map<String, OrganizationDto> organizationsByUuid;
private final Map<String, SnapshotDto> analysisByUuid;
+ private final Map<String, BranchDto> branchesByUuid;
private final Multimap<String, CeTaskCharacteristicDto> characteristicsByTaskUuid;
private DtoCache(Map<String, ComponentDto> componentsByUuid, Map<String, OrganizationDto> organizationsByUuid, Map<String, SnapshotDto> analysisByUuid,
- Multimap<String, CeTaskCharacteristicDto> characteristicsByTaskUuid) {
+ Multimap<String, CeTaskCharacteristicDto> characteristicsByTaskUuid, Map<String, BranchDto> branchesByUuid) {
this.componentsByUuid = componentsByUuid;
this.organizationsByUuid = organizationsByUuid;
this.analysisByUuid = analysisByUuid;
this.characteristicsByTaskUuid = characteristicsByTaskUuid;
+ this.branchesByUuid = branchesByUuid;
}
static DtoCache forQueueDtos(DbClient dbClient, DbSession dbSession, Collection<CeQueueDto> ceQueueDtos) {
@@ -163,7 +183,10 @@ public class TaskFormatter {
Multimap<String, CeTaskCharacteristicDto> characteristicsByTaskUuid = dbClient.ceTaskCharacteristicsDao()
.selectByTaskUuids(dbSession, ceQueueDtos.stream().map(CeQueueDto::getUuid).collect(Collectors.toList()))
.stream().collect(MoreCollectors.index(CeTaskCharacteristicDto::getTaskUuid));
- return new DtoCache(componentsByUuid, buildOrganizationsByUuid(dbClient, dbSession, componentsByUuid), Collections.emptyMap(), characteristicsByTaskUuid);
+ Map<String, BranchDto> branchesByUuid = dbClient.branchDao().selectByUuids(dbSession, componentsByUuid.keySet()).stream()
+ .collect(MoreCollectors.uniqueIndex(BranchDto::getUuid));
+ return new DtoCache(componentsByUuid, buildOrganizationsByUuid(dbClient, dbSession, componentsByUuid), Collections.emptyMap(), characteristicsByTaskUuid,
+ branchesByUuid);
}
private static Set<String> uuidOfCeQueueDtos(Collection<CeQueueDto> ceQueueDtos) {
@@ -182,8 +205,10 @@ public class TaskFormatter {
.collect(MoreCollectors.uniqueIndex(ComponentDto::uuid));
Set<String> analysisUuids = ceActivityDtos.stream().map(CeActivityDto::getAnalysisUuid).filter(Objects::nonNull).collect(MoreCollectors.toSet());
Map<String, SnapshotDto> analysisByUuid = dbClient.snapshotDao().selectByUuids(dbSession, analysisUuids).stream().collect(MoreCollectors.uniqueIndex(SnapshotDto::getUuid));
+ Map<String, BranchDto> branchesByUuid = dbClient.branchDao().selectByUuids(dbSession, componentsByUuid.keySet()).stream()
+ .collect(MoreCollectors.uniqueIndex(BranchDto::getUuid));
return new DtoCache(componentsByUuid, buildOrganizationsByUuid(dbClient, dbSession, componentsByUuid), analysisByUuid,
- ImmutableMultimap.<String, CeTaskCharacteristicDto>builder().build());
+ ImmutableMultimap.<String, CeTaskCharacteristicDto>builder().build(), branchesByUuid);
}
private static Set<String> uuidOfCeActivityDtos(Collection<CeActivityDto> ceActivityDtos) {
@@ -232,11 +257,30 @@ public class TaskFormatter {
return analysisByUuid.get(analysisUuid);
}
+ @CheckForNull
+ BranchDto getBranch(String componentUuid) {
+ return branchesByUuid.get(componentUuid);
+ }
+
boolean hasIncrementalCharacteristic(String taskUuid) {
return characteristicsByTaskUuid.get(taskUuid).stream()
.filter(c -> c.getKey().equals(CeTaskCharacteristicDto.INCREMENTAL_KEY))
.anyMatch(c -> c.getValue().equals("true"));
}
+
+ Optional<String> getBranchName(String taskUuid) {
+ return characteristicsByTaskUuid.get(taskUuid).stream()
+ .filter(c -> c.getKey().equals(CeTaskCharacteristicDto.BRANCH_KEY))
+ .map(CeTaskCharacteristicDto::getValue)
+ .findAny();
+ }
+
+ Optional<Common.BranchType> getBranchType(String taskUuid) {
+ return characteristicsByTaskUuid.get(taskUuid).stream()
+ .filter(c -> c.getKey().equals(CeTaskCharacteristicDto.BRANCH_TYPE_KEY))
+ .map(c -> Common.BranchType.valueOf(c.getValue()))
+ .findAny();
+ }
}
/**
diff --git a/server/sonar-server/src/test/java/org/sonar/server/ce/ws/ActivityActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/ce/ws/ActivityActionTest.java
index 590ccb33ce0..57e4354b7e4 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/ce/ws/ActivityActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/ce/ws/ActivityActionTest.java
@@ -50,6 +50,7 @@ import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.TestResponse;
import org.sonar.server.ws.WsActionTester;
import org.sonar.test.JsonAssert;
+import org.sonarqube.ws.Common;
import org.sonarqube.ws.MediaTypes;
import org.sonarqube.ws.WsCe;
import org.sonarqube.ws.WsCe.ActivityResponse;
@@ -65,7 +66,10 @@ import static org.sonar.db.ce.CeActivityDto.Status.FAILED;
import static org.sonar.db.ce.CeActivityDto.Status.SUCCESS;
import static org.sonar.db.ce.CeQueueDto.Status.IN_PROGRESS;
import static org.sonar.db.ce.CeQueueDto.Status.PENDING;
+import static org.sonar.db.ce.CeTaskCharacteristicDto.BRANCH_KEY;
+import static org.sonar.db.ce.CeTaskCharacteristicDto.BRANCH_TYPE_KEY;
import static org.sonar.db.ce.CeTaskCharacteristicDto.INCREMENTAL_KEY;
+import static org.sonar.db.component.BranchType.LONG;
import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_COMPONENT_ID;
import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_COMPONENT_QUERY;
import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_MAX_EXECUTED_AT;
@@ -405,8 +409,46 @@ public class ActivityActionTest {
.extracting(Task::getId, Task::getIncremental)
.containsExactlyInAnyOrder(
tuple("T1", true),
- tuple("T2", true)
- );
+ tuple("T2", true));
+ }
+
+ @Test
+ public void long_living_branch_in_past_activity() {
+ logInAsSystemAdministrator();
+ ComponentDto project = db.components().insertMainBranch();
+ userSession.addProjectPermission(UserRole.USER, project);
+ ComponentDto longLivingBranch = db.components().insertProjectBranch(project, b -> b.setBranchType(LONG));
+ SnapshotDto analysis = db.components().insertSnapshot(longLivingBranch);
+ insertActivity("T1", longLivingBranch, SUCCESS, analysis);
+
+ ActivityResponse response = ws.newRequest().executeProtobuf(ActivityResponse.class);
+
+ assertThat(response.getTasksList())
+ .extracting(Task::getId, WsCe.Task::getBranch, WsCe.Task::getBranchType, WsCe.Task::getStatus, WsCe.Task::getComponentKey)
+ .containsExactlyInAnyOrder(
+ tuple("T1", longLivingBranch.getBranch(), Common.BranchType.LONG, WsCe.TaskStatus.SUCCESS, longLivingBranch.getKey()));
+ }
+
+ @Test
+ public void long_living_branch_in_queue_analysis() {
+ logInAsSystemAdministrator();
+ String branch = "ny_branch";
+ CeQueueDto queue1 = insertQueue("T1", null, IN_PROGRESS);
+ insertCharacteristic(queue1, BRANCH_KEY, branch);
+ insertCharacteristic(queue1, BRANCH_TYPE_KEY, LONG.name());
+ CeQueueDto queue2 = insertQueue("T2", null, PENDING);
+ insertCharacteristic(queue2, BRANCH_KEY, branch);
+ insertCharacteristic(queue2, BRANCH_TYPE_KEY, LONG.name());
+
+ ActivityResponse response = ws.newRequest()
+ .setParam("status", "FAILED,IN_PROGRESS,PENDING")
+ .executeProtobuf(ActivityResponse.class);
+
+ assertThat(response.getTasksList())
+ .extracting(Task::getId, WsCe.Task::getBranch, WsCe.Task::getBranchType, WsCe.Task::getStatus)
+ .containsExactlyInAnyOrder(
+ tuple("T1", branch, Common.BranchType.LONG, WsCe.TaskStatus.IN_PROGRESS),
+ tuple("T2", branch, Common.BranchType.LONG, WsCe.TaskStatus.PENDING));
}
@Test
diff --git a/server/sonar-server/src/test/java/org/sonar/server/ce/ws/ComponentActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/ce/ws/ComponentActionTest.java
index afecd31d24a..9672520e1eb 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/ce/ws/ComponentActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/ce/ws/ComponentActionTest.java
@@ -40,15 +40,23 @@ import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.WsActionTester;
+import org.sonarqube.ws.Common;
import org.sonarqube.ws.MediaTypes;
import org.sonarqube.ws.WsCe;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Java6Assertions.tuple;
import static org.sonar.db.ce.CeActivityDto.Status.SUCCESS;
+import static org.sonar.db.ce.CeQueueDto.Status.IN_PROGRESS;
+import static org.sonar.db.ce.CeQueueDto.Status.PENDING;
+import static org.sonar.db.ce.CeTaskCharacteristicDto.BRANCH_KEY;
+import static org.sonar.db.ce.CeTaskCharacteristicDto.BRANCH_TYPE_KEY;
import static org.sonar.db.ce.CeTaskCharacteristicDto.INCREMENTAL_KEY;
-import static org.sonar.server.ce.ws.ComponentAction.PARAM_COMPONENT_ID;
-import static org.sonar.server.ce.ws.ComponentAction.PARAM_COMPONENT_KEY;
+import static org.sonar.db.component.BranchType.LONG;
+import static org.sonar.db.component.ComponentTesting.newFileDto;
+import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_COMPONENT_ID;
+import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_COMPONENT_KEY;
+import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_BRANCH;
public class ComponentActionTest {
@@ -86,8 +94,8 @@ public class ComponentActionTest {
insertActivity("T1", project1, CeActivityDto.Status.SUCCESS, analysisProject1);
insertActivity("T2", project2, CeActivityDto.Status.FAILED, null);
insertActivity("T3", project1, CeActivityDto.Status.FAILED, null);
- insertQueue("T4", project1, CeQueueDto.Status.IN_PROGRESS);
- insertQueue("T5", project1, CeQueueDto.Status.PENDING);
+ insertQueue("T4", project1, IN_PROGRESS);
+ insertQueue("T5", project1, PENDING);
WsCe.ProjectResponse response = ws.newRequest()
.setParam("componentId", project1.uuid())
@@ -177,9 +185,9 @@ public class ComponentActionTest {
OrganizationDto organization = db.organizations().insert();
ComponentDto project = db.components().insertPrivateProject(organization);
userSession.addProjectPermission(UserRole.USER, project);
- CeQueueDto queue1 = insertQueue("T1", project, CeQueueDto.Status.IN_PROGRESS);
+ CeQueueDto queue1 = insertQueue("T1", project, IN_PROGRESS);
insertCharacteristic(queue1, INCREMENTAL_KEY, "true");
- CeQueueDto queue2 = insertQueue("T2", project, CeQueueDto.Status.PENDING);
+ CeQueueDto queue2 = insertQueue("T2", project, PENDING);
insertCharacteristic(queue2, INCREMENTAL_KEY, "true");
WsCe.ProjectResponse response = ws.newRequest()
@@ -190,8 +198,50 @@ public class ComponentActionTest {
.extracting(WsCe.Task::getId, WsCe.Task::getIncremental)
.containsOnly(
tuple("T1", true),
- tuple("T2", true)
- );
+ tuple("T2", true));
+ }
+
+ @Test
+ public void long_living_branch_in_activity() {
+ ComponentDto project = db.components().insertMainBranch();
+ userSession.addProjectPermission(UserRole.USER, project);
+ ComponentDto longLivingBranch = db.components().insertProjectBranch(project, b -> b.setBranchType(LONG));
+ SnapshotDto analysis = db.components().insertSnapshot(longLivingBranch);
+ insertActivity("T1", longLivingBranch, SUCCESS, analysis);
+
+ WsCe.ProjectResponse response = ws.newRequest()
+ .setParam("componentKey", longLivingBranch.getKey())
+ .setParam("branch", longLivingBranch.getBranch())
+ .executeProtobuf(WsCe.ProjectResponse.class);
+
+ assertThat(response.getCurrent())
+ .extracting(WsCe.Task::getId, WsCe.Task::getBranch, WsCe.Task::getBranchType, WsCe.Task::getStatus, WsCe.Task::getComponentKey)
+ .containsOnly(
+ "T1", longLivingBranch.getBranch(), Common.BranchType.LONG, WsCe.TaskStatus.SUCCESS, longLivingBranch.getKey());
+ }
+
+ @Test
+ public void long_living_branch_in_queue_analysis() {
+ ComponentDto project = db.components().insertMainBranch();
+ userSession.addProjectPermission(UserRole.USER, project);
+ ComponentDto longLivingBranch = db.components().insertProjectBranch(project, b -> b.setBranchType(LONG));
+ CeQueueDto queue1 = insertQueue("T1", longLivingBranch, IN_PROGRESS);
+ insertCharacteristic(queue1, BRANCH_KEY, longLivingBranch.getBranch());
+ insertCharacteristic(queue1, BRANCH_TYPE_KEY, LONG.name());
+ CeQueueDto queue2 = insertQueue("T2", longLivingBranch, PENDING);
+ insertCharacteristic(queue2, BRANCH_KEY, longLivingBranch.getBranch());
+ insertCharacteristic(queue2, BRANCH_TYPE_KEY, LONG.name());
+
+ WsCe.ProjectResponse response = ws.newRequest()
+ .setParam("componentKey", longLivingBranch.getKey())
+ .setParam("branch", longLivingBranch.getBranch())
+ .executeProtobuf(WsCe.ProjectResponse.class);
+
+ assertThat(response.getQueueList())
+ .extracting(WsCe.Task::getId, WsCe.Task::getBranch, WsCe.Task::getBranchType, WsCe.Task::getStatus, WsCe.Task::getComponentKey)
+ .containsOnly(
+ tuple("T1", longLivingBranch.getBranch(), Common.BranchType.LONG, WsCe.TaskStatus.IN_PROGRESS, longLivingBranch.getKey()),
+ tuple("T2", longLivingBranch.getBranch(), Common.BranchType.LONG, WsCe.TaskStatus.PENDING, longLivingBranch.getKey()));
}
@Test
@@ -224,6 +274,38 @@ public class ComponentActionTest {
ws.newRequest().execute();
}
+ @Test
+ public void fail_if_branch_does_not_exist() {
+ ComponentDto project = db.components().insertPrivateProject();
+ ComponentDto file = db.components().insertComponent(newFileDto(project));
+ userSession.addProjectPermission(UserRole.USER, project);
+ db.components().insertProjectBranch(project, b -> b.setKey("my_branch"));
+
+ expectedException.expect(NotFoundException.class);
+ expectedException.expectMessage(String.format("Component '%s' on branch '%s' not found", file.getKey(), "another_branch"));
+
+ ws.newRequest()
+ .setParam(PARAM_COMPONENT_KEY, file.getKey())
+ .setParam(PARAM_BRANCH, "another_branch")
+ .execute();
+ }
+
+ @Test
+ public void fail_when_componentId_and_branch_params_are_used_together() {
+ ComponentDto project = db.components().insertPrivateProject();
+ ComponentDto file = db.components().insertComponent(newFileDto(project));
+ userSession.addProjectPermission(UserRole.USER, project);
+ db.components().insertProjectBranch(project, b -> b.setKey("my_branch"));
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("'componentId' and 'branch' parameters cannot be used at the same time");
+
+ ws.newRequest()
+ .setParam(PARAM_COMPONENT_ID, file.uuid())
+ .setParam(PARAM_BRANCH, "my_branch")
+ .execute();
+ }
+
private void logInWithBrowsePermission(ComponentDto project) {
userSession.logIn().addProjectPermission(UserRole.USER, project);
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/ce/ws/TaskActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/ce/ws/TaskActionTest.java
index 038f227104b..efee0ee2c4d 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/ce/ws/TaskActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/ce/ws/TaskActionTest.java
@@ -26,6 +26,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.utils.System2;
+import org.sonar.api.web.UserRole;
import org.sonar.core.permission.GlobalPermissions;
import org.sonar.core.util.CloseableIterator;
import org.sonar.core.util.Uuids;
@@ -41,10 +42,14 @@ import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.WsActionTester;
+import org.sonarqube.ws.Common;
import org.sonarqube.ws.WsCe;
import static java.util.Collections.singleton;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.db.ce.CeTaskCharacteristicDto.BRANCH_KEY;
+import static org.sonar.db.ce.CeTaskCharacteristicDto.BRANCH_TYPE_KEY;
+import static org.sonar.db.component.BranchType.LONG;
import static org.sonar.db.permission.OrganizationPermission.SCAN;
public class TaskActionTest {
@@ -160,6 +165,49 @@ public class TaskActionTest {
}
@Test
+ public void long_living_branch_in_past_activity() {
+ logInAsRoot();
+ ComponentDto project = db.components().insertMainBranch();
+ userSession.addProjectPermission(UserRole.USER, project);
+ ComponentDto longLivingBranch = db.components().insertProjectBranch(project, b -> b.setBranchType(LONG));
+ SnapshotDto analysis = db.components().insertSnapshot(longLivingBranch);
+ CeQueueDto queueDto = new CeQueueDto()
+ .setTaskType(CeTaskTypes.REPORT)
+ .setUuid(SOME_TASK_UUID)
+ .setComponentUuid(longLivingBranch.uuid());
+ CeActivityDto activityDto = new CeActivityDto(queueDto)
+ .setStatus(CeActivityDto.Status.FAILED)
+ .setExecutionTimeMs(500L)
+ .setAnalysisUuid(analysis.getUuid());
+ persist(activityDto);
+
+ WsCe.TaskResponse taskResponse = ws.newRequest()
+ .setParam("id", SOME_TASK_UUID)
+ .executeProtobuf(WsCe.TaskResponse.class);
+
+ assertThat(taskResponse.getTask())
+ .extracting(WsCe.Task::getId, WsCe.Task::getBranch, WsCe.Task::getBranchType, WsCe.Task::getComponentKey)
+ .containsExactlyInAnyOrder(SOME_TASK_UUID, longLivingBranch.getBranch(), Common.BranchType.LONG, longLivingBranch.getKey());
+ }
+
+ @Test
+ public void long_living_branch_in_queue_analysis() {
+ logInAsRoot();
+ String branch = "my_branch";
+ CeQueueDto queueDto = createAndPersistQueueTask(null);
+ insertCharacteristic(queueDto, BRANCH_KEY, branch);
+ insertCharacteristic(queueDto, BRANCH_TYPE_KEY, LONG.name());
+
+ WsCe.TaskResponse taskResponse = ws.newRequest()
+ .setParam("id", SOME_TASK_UUID)
+ .executeProtobuf(WsCe.TaskResponse.class);
+
+ assertThat(taskResponse.getTask())
+ .extracting(WsCe.Task::getId, WsCe.Task::getBranch, WsCe.Task::getBranchType, WsCe.Task::hasComponentKey)
+ .containsExactlyInAnyOrder(SOME_TASK_UUID, branch, Common.BranchType.LONG, false);
+ }
+
+ @Test
public void return_stacktrace_of_failed_activity_with_stacktrace_when_additionalField_is_set() {
logInAsRoot();
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/ce/CeWsParameters.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/ce/CeWsParameters.java
index 77cbbd673e0..680051f2dd2 100644
--- a/sonar-ws/src/main/java/org/sonarqube/ws/client/ce/CeWsParameters.java
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/ce/CeWsParameters.java
@@ -31,6 +31,7 @@ public class CeWsParameters {
public static final String PARAM_ONLY_CURRENTS = "onlyCurrents";
public static final String PARAM_MIN_SUBMITTED_AT = "minSubmittedAt";
public static final String PARAM_MAX_EXECUTED_AT = "maxExecutedAt";
+ public static final String PARAM_BRANCH = "branch";
private CeWsParameters() {
// prevent instantiation
diff --git a/sonar-ws/src/main/protobuf/ws-ce.proto b/sonar-ws/src/main/protobuf/ws-ce.proto
index a268b7bcbd6..87ec36a7fcf 100644
--- a/sonar-ws/src/main/protobuf/ws-ce.proto
+++ b/sonar-ws/src/main/protobuf/ws-ce.proto
@@ -90,6 +90,8 @@ message Task {
optional bool hasScannerContext = 19;
optional string organization = 20;
optional bool incremental = 21;
+ optional string branch = 22;
+ optional sonarqube.ws.commons.BranchType branchType = 23;
}
enum TaskStatus {