Просмотр исходного кода

SONAR-7845 add scannerContext to /api/ce/task

tags/6.1-RC1
Sébastien Lesaint 7 лет назад
Родитель
Сommit
5a15f58bd1

+ 30
- 10
server/sonar-server/src/main/java/org/sonar/server/ce/ws/TaskAction.java Просмотреть файл

@@ -24,9 +24,9 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Set;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
@@ -99,8 +99,10 @@ public class TaskAction implements CeWsAction {
if (activityDto.isPresent()) {
CeActivityDto ceActivityDto = activityDto.get();
checkPermission(ceActivityDto.getComponentUuid());
maskErrorStacktrace(wsRequest, ceActivityDto);
wsTaskResponse.setTask(wsTaskFormatter.formatActivity(dbSession, ceActivityDto));
Set<AdditionalField> additionalFields = AdditionalField.getFromRequest(wsRequest);
maskErrorStacktrace(ceActivityDto, additionalFields);
wsTaskResponse.setTask(
wsTaskFormatter.formatActivity(dbSession, ceActivityDto, extractScannerContext(dbSession, taskUuid, additionalFields)));
} else {
throw new NotFoundException();
}
@@ -119,15 +121,34 @@ public class TaskAction implements CeWsAction {
}
}

private static void maskErrorStacktrace(Request wsRequest, CeActivityDto ceActivityDto) {
Set<AdditionalField> fromRequest = TaskAction.AdditionalField.getFromRequest(wsRequest);
if (!fromRequest.contains(TaskAction.AdditionalField.STACKTRACE)) {
private static void maskErrorStacktrace(CeActivityDto ceActivityDto, Set<AdditionalField> additionalFields) {
if (!additionalFields.contains(AdditionalField.STACKTRACE)) {
ceActivityDto.setErrorStacktrace(null);
}
}

@CheckForNull
private String extractScannerContext(DbSession dbSession, String taskUuid, Set<AdditionalField> additionalFields) {
if (additionalFields.contains(AdditionalField.SCANNER_CONTEXT)) {
return dbClient.scannerContextDao().selectScannerContext(dbSession, taskUuid)
.orElse(null);
}
return null;
}

private enum AdditionalField {
STACKTRACE;
STACKTRACE("stacktrace"),
SCANNER_CONTEXT("scannerContext");

private final String label;

AdditionalField(String label) {
this.label = label;
}

public String getLabel() {
return label;
}

public static Set<AdditionalField> getFromRequest(Request wsRequest) {
List<String> strings = wsRequest.paramAsStrings(PARAM_ADDITIONAL_FIELDS);
@@ -137,7 +158,7 @@ public class TaskAction implements CeWsAction {
return strings.stream()
.map(s -> {
for (AdditionalField field : AdditionalField.values()) {
if (field.name().equalsIgnoreCase(s)) {
if (field.label.equalsIgnoreCase(s)) {
return field;
}
}
@@ -149,8 +170,7 @@ public class TaskAction implements CeWsAction {

public static Collection<String> possibleValues() {
return Arrays.stream(values())
.map(Enum::name)
.map(s -> s.toLowerCase(Locale.ENGLISH))
.map(AdditionalField::getLabel)
.collect(Collectors.toList(values().length));
}
}

+ 10
- 3
server/sonar-server/src/main/java/org/sonar/server/ce/ws/TaskFormatter.java Просмотреть файл

@@ -89,15 +89,19 @@ public class TaskFormatter {
}

public WsCe.Task formatActivity(DbSession dbSession, CeActivityDto dto) {
return formatActivity(dto, new ComponentDtoCache(dbSession, dto.getComponentUuid()));
return formatActivity(dbSession, dto, null);
}

public WsCe.Task formatActivity(DbSession dbSession, CeActivityDto dto, @Nullable String scannerContext) {
return formatActivity(dto, new ComponentDtoCache(dbSession, dto.getComponentUuid()), scannerContext);
}

public List<WsCe.Task> formatActivity(DbSession dbSession, List<CeActivityDto> dtos) {
ComponentDtoCache cache = new ComponentDtoCache(dbSession, ceActivityDtoToComponentUuids(dtos));
return dtos.stream().map(input -> formatActivity(input, cache)).collect(Collectors.toList());
return dtos.stream().map(input -> formatActivity(input, cache, null)).collect(Collectors.toList());
}

private WsCe.Task formatActivity(CeActivityDto dto, ComponentDtoCache componentDtoCache) {
private WsCe.Task formatActivity(CeActivityDto dto, ComponentDtoCache componentDtoCache, @Nullable String scannerContext) {
WsCe.Task.Builder builder = WsCe.Task.newBuilder();
builder.setId(dto.getUuid());
builder.setStatus(WsCe.TaskStatus.valueOf(dto.getStatus().name()));
@@ -129,6 +133,9 @@ public class TaskFormatter {
if (dto.getErrorStacktrace() != null) {
builder.setErrorStacktrace(dto.getErrorStacktrace());
}
if (scannerContext != null) {
builder.setScannerContext(scannerContext);
}
return builder.build();
}


+ 2
- 1
server/sonar-server/src/main/resources/org/sonar/server/ce/ws/task-example.json Просмотреть файл

@@ -14,6 +14,7 @@
"executionTimeMs": 5286,
"errorMessage": "Fail to extract report AVaXuGAi_te3Ldc_YItm from database",
"hasErrorStacktrace": true,
"errorStacktrace": "java.lang.IllegalStateException: Fail to extract report AVaXuGAi_te3Ldc_YItm from database\\n\tat org.sonar.server.computation.task.projectanalysis.step.ExtractReportStep.execute(ExtractReportStep.java:50)"
"errorStacktrace": "java.lang.IllegalStateException: Fail to extract report AVaXuGAi_te3Ldc_YItm from database\n\tat org.sonar.server.computation.task.projectanalysis.step.ExtractReportStep.execute(ExtractReportStep.java:50)",
"scannerContext": "SonarQube plugins:\n\t- Git 1.0 (scmgit)\n\t- Java 3.13.1 (java)"
}
}

+ 76
- 27
server/sonar-server/src/test/java/org/sonar/server/ce/ws/TaskActionTest.java Просмотреть файл

@@ -32,6 +32,7 @@ import org.sonar.db.ce.CeQueueDto;
import org.sonar.db.ce.CeTaskTypes;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
import org.sonar.db.dialect.H2;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.tester.UserSessionRule;
@@ -42,6 +43,7 @@ import org.sonarqube.ws.WsCe;

import static java.util.Collections.singleton;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assume.assumeTrue;
import static org.sonar.core.permission.GlobalPermissions.PROVISIONING;
import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
@@ -53,6 +55,7 @@ public class TaskActionTest {
.setUuid("PROJECT_1")
.setName("Project One")
.setKey("P1");
private static final String SOME_TASK_UUID = "TASK_1";

@Rule
public UserSessionRule userSession = UserSessionRule.standalone();
@@ -78,7 +81,7 @@ public class TaskActionTest {

CeQueueDto queueDto = new CeQueueDto();
queueDto.setTaskType(CeTaskTypes.REPORT);
queueDto.setUuid("TASK_1");
queueDto.setUuid(SOME_TASK_UUID);
queueDto.setComponentUuid(PROJECT.uuid());
queueDto.setStatus(CeQueueDto.Status.PENDING);
queueDto.setSubmitterLogin("john");
@@ -86,11 +89,11 @@ public class TaskActionTest {

TestResponse wsResponse = ws.newRequest()
.setMediaType(PROTOBUF)
.setParam("id", "TASK_1")
.setParam("id", SOME_TASK_UUID)
.execute();

WsCe.TaskResponse taskResponse = Protobuf.read(wsResponse.getInputStream(), WsCe.TaskResponse.PARSER);
assertThat(taskResponse.getTask().getId()).isEqualTo("TASK_1");
assertThat(taskResponse.getTask().getId()).isEqualTo(SOME_TASK_UUID);
assertThat(taskResponse.getTask().getStatus()).isEqualTo(WsCe.TaskStatus.PENDING);
assertThat(taskResponse.getTask().getSubmitterLogin()).isEqualTo("john");
assertThat(taskResponse.getTask().getComponentId()).isEqualTo(PROJECT.uuid());
@@ -104,22 +107,22 @@ public class TaskActionTest {
public void task_is_archived() throws Exception {
userSession.login("john").setGlobalPermissions(SYSTEM_ADMIN);

CeActivityDto activityDto = createActivityDto("TASK_1");
CeActivityDto activityDto = createActivityDto(SOME_TASK_UUID);
persist(activityDto);

TestResponse wsResponse = ws.newRequest()
.setMediaType(PROTOBUF)
.setParam("id", "TASK_1")
.setParam("id", SOME_TASK_UUID)
.execute();

WsCe.TaskResponse taskResponse = Protobuf.read(wsResponse.getInputStream(), WsCe.TaskResponse.PARSER);
WsCe.Task task = taskResponse.getTask();
assertThat(task.getId()).isEqualTo("TASK_1");
assertThat(task.getId()).isEqualTo(SOME_TASK_UUID);
assertThat(task.getStatus()).isEqualTo(WsCe.TaskStatus.FAILED);
assertThat(task.getComponentId()).isEqualTo(PROJECT.uuid());
assertThat(task.getComponentKey()).isEqualTo(PROJECT.key());
assertThat(task.getComponentName()).isEqualTo(PROJECT.name());
assertThat(task.getAnalysisId()).isEqualTo("U1");
assertThat(task.getAnalysisId()).isEqualTo(activityDto.getAnalysisUuid());
assertThat(task.getExecutionTimeMs()).isEqualTo(500L);
assertThat(task.getLogs()).isFalse();
}
@@ -128,20 +131,20 @@ public class TaskActionTest {
public void return_stacktrace_of_failed_activity_with_stacktrace_when_additionalField_is_set() {
userSession.login("john").setGlobalPermissions(SYSTEM_ADMIN);

CeActivityDto activityDto = createActivityDto("TASK_1")
CeActivityDto activityDto = createActivityDto(SOME_TASK_UUID)
.setErrorMessage("error msg")
.setErrorStacktrace("error stack");
persist(activityDto);

TestResponse wsResponse = ws.newRequest()
.setMediaType(PROTOBUF)
.setParam("id", "TASK_1")
.setParam("id", SOME_TASK_UUID)
.setParam("additionalFields", "stacktrace")
.execute();

WsCe.TaskResponse taskResponse = Protobuf.read(wsResponse.getInputStream(), WsCe.TaskResponse.PARSER);
WsCe.Task task = taskResponse.getTask();
assertThat(task.getId()).isEqualTo("TASK_1");
assertThat(task.getId()).isEqualTo(SOME_TASK_UUID);
assertThat(task.getErrorMessage()).isEqualTo(activityDto.getErrorMessage());
assertThat(task.hasErrorStacktrace()).isTrue();
assertThat(task.getErrorStacktrace()).isEqualTo(activityDto.getErrorStacktrace());
@@ -151,39 +154,85 @@ public class TaskActionTest {
public void do_not_return_stacktrace_of_failed_activity_with_stacktrace_when_additionalField_is_not_set() {
userSession.login("john").setGlobalPermissions(SYSTEM_ADMIN);

CeActivityDto activityDto = createActivityDto("TASK_1")
CeActivityDto activityDto = createActivityDto(SOME_TASK_UUID)
.setErrorMessage("error msg")
.setErrorStacktrace("error stack");
persist(activityDto);

TestResponse wsResponse = ws.newRequest()
.setMediaType(PROTOBUF)
.setParam("id", "TASK_1")
.setParam("id", SOME_TASK_UUID)
.execute();

WsCe.TaskResponse taskResponse = Protobuf.read(wsResponse.getInputStream(), WsCe.TaskResponse.PARSER);
WsCe.Task task = taskResponse.getTask();
assertThat(task.getId()).isEqualTo("TASK_1");
assertThat(task.getId()).isEqualTo(SOME_TASK_UUID);
assertThat(task.getErrorMessage()).isEqualTo(activityDto.getErrorMessage());
assertThat(task.hasErrorStacktrace()).isFalse();
}

@Test
public void return_scannerContext_of_activity_with_scannerContext_when_additionalField_is_set() {
// H2 version we use (1.3.176) has lock bugs when table has CLOB columns which makes this test fail
assumeTrue(!dbTester.database().getDialect().getId().equals(H2.ID));

userSession.login("john").setGlobalPermissions(SYSTEM_ADMIN);

String scannerContext = "this is some scanner context, yeah!";
CeActivityDto activityDto = persist(createActivityDto(SOME_TASK_UUID));
persistScannerContext(activityDto.getAnalysisUuid(), scannerContext);

TestResponse wsResponse = ws.newRequest()
.setMediaType(PROTOBUF)
.setParam("id", SOME_TASK_UUID)
.setParam("additionalFields", "scannerContext")
.execute();

WsCe.TaskResponse taskResponse = Protobuf.read(wsResponse.getInputStream(), WsCe.TaskResponse.PARSER);
WsCe.Task task = taskResponse.getTask();
assertThat(task.getId()).isEqualTo(SOME_TASK_UUID);
assertThat(task.getScannerContext()).isEqualTo(scannerContext);
}

@Test
public void do_not_return_scannerContext_of_activity_with_scannerContext_when_additionalField_is_not_set() {
// H2 version we use (1.3.176) has lock bugs when table has CLOB columns which makes this test fail
assumeTrue(!dbTester.database().getDialect().getId().equals(H2.ID));

userSession.login("john").setGlobalPermissions(SYSTEM_ADMIN);

String scannerContext = "this is some scanner context, yeah!";
CeActivityDto activityDto = persist(createActivityDto(SOME_TASK_UUID));
persistScannerContext(activityDto.getAnalysisUuid(), scannerContext);

TestResponse wsResponse = ws.newRequest()
.setMediaType(PROTOBUF)
.setParam("id", SOME_TASK_UUID)
.setParam("additionalFields", "stacktrace")
.execute();

WsCe.TaskResponse taskResponse = Protobuf.read(wsResponse.getInputStream(), WsCe.TaskResponse.PARSER);
WsCe.Task task = taskResponse.getTask();
assertThat(task.getId()).isEqualTo(SOME_TASK_UUID);
assertThat(task.hasScannerContext()).isFalse();
}

@Test
public void do_not_return_stacktrace_of_failed_activity_without_stacktrace() {
userSession.login("john").setGlobalPermissions(SYSTEM_ADMIN);

CeActivityDto activityDto = createActivityDto("TASK_1")
CeActivityDto activityDto = createActivityDto(SOME_TASK_UUID)
.setErrorMessage("error msg");
persist(activityDto);

TestResponse wsResponse = ws.newRequest()
.setMediaType(PROTOBUF)
.setParam("id", "TASK_1")
.setParam("id", SOME_TASK_UUID)
.execute();

WsCe.TaskResponse taskResponse = Protobuf.read(wsResponse.getInputStream(), WsCe.TaskResponse.PARSER);
WsCe.Task task = taskResponse.getTask();
assertThat(task.getId()).isEqualTo("TASK_1");
assertThat(task.getId()).isEqualTo(SOME_TASK_UUID);
assertThat(task.getErrorMessage()).isEqualTo(activityDto.getErrorMessage());
assertThat(task.hasErrorStacktrace()).isFalse();
}
@@ -204,13 +253,13 @@ public class TaskActionTest {

CeQueueDto queueDto = new CeQueueDto();
queueDto.setTaskType("fake");
queueDto.setUuid("TASK_1");
queueDto.setUuid(SOME_TASK_UUID);
queueDto.setStatus(CeQueueDto.Status.PENDING);
persist(queueDto);

ws.newRequest()
.setMediaType(MediaTypes.JSON)
.setParam("id", "TASK_1")
.setParam("id", SOME_TASK_UUID)
.execute();
}

@@ -220,13 +269,13 @@ public class TaskActionTest {

CeQueueDto queueDto = new CeQueueDto();
queueDto.setTaskType("fake");
queueDto.setUuid("TASK_1");
queueDto.setUuid(SOME_TASK_UUID);
queueDto.setStatus(CeQueueDto.Status.PENDING);
persist(queueDto);

ws.newRequest()
.setMediaType(MediaTypes.JSON)
.setParam("id", "TASK_1")
.setParam("id", SOME_TASK_UUID)
.execute();
}

@@ -236,14 +285,14 @@ public class TaskActionTest {

CeQueueDto queueDto = new CeQueueDto();
queueDto.setTaskType("fake");
queueDto.setUuid("TASK_1");
queueDto.setUuid(SOME_TASK_UUID);
queueDto.setStatus(CeQueueDto.Status.PENDING);
persist(queueDto);

expectedException.expect(ForbiddenException.class);
ws.newRequest()
.setMediaType(PROTOBUF)
.setParam("id", "TASK_1")
.setParam("id", SOME_TASK_UUID)
.execute();
}

@@ -253,14 +302,14 @@ public class TaskActionTest {

CeQueueDto queueDto = new CeQueueDto();
queueDto.setTaskType("fake");
queueDto.setUuid("TASK_1");
queueDto.setUuid(SOME_TASK_UUID);
queueDto.setStatus(CeQueueDto.Status.PENDING);
queueDto.setComponentUuid(PROJECT.uuid());
persist(queueDto);

ws.newRequest()
.setMediaType(MediaTypes.JSON)
.setParam("id", "TASK_1")
.setParam("id", SOME_TASK_UUID)
.execute();
}

@@ -268,13 +317,13 @@ public class TaskActionTest {
public void not_fail_on_archived_task_linked_on_project_with_project_scan_permission() throws Exception {
userSession.login("john").addProjectUuidPermissions(SCAN_EXECUTION, PROJECT.uuid());

CeActivityDto activityDto = createActivityDto("TASK_1")
CeActivityDto activityDto = createActivityDto(SOME_TASK_UUID)
.setComponentUuid(PROJECT.uuid());
persist(activityDto);

ws.newRequest()
.setMediaType(PROTOBUF)
.setParam("id", "TASK_1")
.setParam("id", SOME_TASK_UUID)
.execute();
}

@@ -286,7 +335,7 @@ public class TaskActionTest {
CeActivityDto activityDto = new CeActivityDto(queueDto);
activityDto.setStatus(CeActivityDto.Status.FAILED);
activityDto.setExecutionTimeMs(500L);
activityDto.setAnalysisUuid("U1");
activityDto.setAnalysisUuid(uuid + "u1");
return activityDto;
}


+ 14
- 1
server/sonar-server/src/test/java/org/sonar/server/ce/ws/TaskFormatterTest.java Просмотреть файл

@@ -61,6 +61,7 @@ public class TaskFormatterTest {
assertThat(wsTask.getStatus()).isEqualTo(WsCe.TaskStatus.PENDING);
assertThat(wsTask.getLogs()).isFalse();
assertThat(wsTask.getSubmittedAt()).isEqualTo(DateUtils.formatDateTime(new Date(1_450_000_000_000L)));
assertThat(wsTask.hasScannerContext()).isFalse();

assertThat(wsTask.hasExecutionTimeMs()).isFalse();
assertThat(wsTask.hasSubmitterLogin()).isFalse();
@@ -100,6 +101,7 @@ public class TaskFormatterTest {
assertThat(wsTask.getSubmitterLogin()).isEqualTo("rob");
assertThat(wsTask.hasExecutionTimeMs()).isTrue();
assertThat(wsTask.hasExecutedAt()).isFalse();
assertThat(wsTask.hasScannerContext()).isFalse();
}

@Test
@@ -162,11 +164,22 @@ public class TaskFormatterTest {
assertThat(wsTask.getType()).isEqualTo(CeTaskTypes.REPORT);
assertThat(wsTask.getId()).isEqualTo("UUID");
assertThat(wsTask.getStatus()).isEqualTo(WsCe.TaskStatus.FAILED);
assertThat(wsTask.getLogs()).isFalse();
assertThat(wsTask.getSubmittedAt()).isEqualTo(DateUtils.formatDateTime(new Date(1_450_000_000_000L)));
assertThat(wsTask.getExecutionTimeMs()).isEqualTo(500L);
assertThat(wsTask.getAnalysisId()).isEqualTo("U1");
assertThat(wsTask.getLogs()).isFalse();
assertThat(wsTask.hasScannerContext()).isFalse();
}

@Test
public void formatActivity_set_scanner_context_if_argument_is_non_null() {
CeActivityDto dto = newActivity("UUID", "COMPONENT_UUID", CeActivityDto.Status.FAILED);

String expected = "scanner context baby!";
WsCe.Task wsTask = underTest.formatActivity(db.getSession(), dto, expected);

assertThat(wsTask.hasScannerContext()).isTrue();
assertThat(wsTask.getScannerContext()).isEqualTo(expected);
}

@Test

+ 1
- 0
sonar-ws/src/main/protobuf/ws-ce.proto Просмотреть файл

@@ -79,6 +79,7 @@ message Task {
optional bool logs = 15;
optional string errorMessage = 16;
optional string errorStacktrace = 17;
optional string scannerContext = 18;
}

enum TaskStatus {

Загрузка…
Отмена
Сохранить