Browse Source

SONAR-7843 add error stacktrace to /api/ce/task

tags/6.1-RC1
Sébastien Lesaint 7 years ago
parent
commit
b3305db9ff

+ 44
- 3
server/sonar-server/src/main/java/org/sonar/server/ce/ws/TaskAction.java View File

@@ -78,6 +78,10 @@ public class TaskAction implements CeWsAction {
.setRequired(true)
.setDescription("Id of task")
.setExampleValue(Uuids.UUID_EXAMPLE_01);
action.createParam(PARAM_ADDITIONAL_FIELDS)
.setSince("6.1")
.setDescription("Comma-separated list of the optional fields to be returned in response.")
.setPossibleValues(AdditionalField.possibleValues());
}

@Override
@@ -93,14 +97,15 @@ public class TaskAction implements CeWsAction {
} else {
Optional<CeActivityDto> activityDto = dbClient.ceActivityDao().selectByUuid(dbSession, taskUuid);
if (activityDto.isPresent()) {
checkPermission(activityDto.get().getComponentUuid());
wsTaskResponse.setTask(wsTaskFormatter.formatActivity(dbSession, activityDto.get()));
CeActivityDto ceActivityDto = activityDto.get();
checkPermission(ceActivityDto.getComponentUuid());
maskErrorStacktrace(wsRequest, ceActivityDto);
wsTaskResponse.setTask(wsTaskFormatter.formatActivity(dbSession, ceActivityDto));
} else {
throw new NotFoundException();
}
}
writeProtobuf(wsTaskResponse.build(), wsRequest, wsResponse);

} finally {
dbClient.closeSession(dbSession);
}
@@ -113,4 +118,40 @@ public class TaskAction implements CeWsAction {
throw insufficientPrivilegesException();
}
}

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

private enum AdditionalField {
STACKTRACE;

public static Set<AdditionalField> getFromRequest(Request wsRequest) {
List<String> strings = wsRequest.paramAsStrings(PARAM_ADDITIONAL_FIELDS);
if (strings == null) {
return Collections.emptySet();
}
return strings.stream()
.map(s -> {
for (AdditionalField field : AdditionalField.values()) {
if (field.name().equalsIgnoreCase(s)) {
return field;
}
}
return null;
})
.filter(Objects::nonNull)
.collect(Collectors.toSet());
}

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

+ 3
- 1
server/sonar-server/src/main/java/org/sonar/server/ce/ws/TaskFormatter.java View File

@@ -129,7 +129,9 @@ public class TaskFormatter {
if (dto.getErrorMessage() != null) {
builder.setErrorMessage(dto.getErrorMessage());
}
builder.setHasErrorStacktrace(dto.isHasErrorStacktrace());
if (dto.getErrorStacktrace() != null) {
builder.setErrorStacktrace(dto.getErrorStacktrace());
}
return builder.build();
}


+ 3
- 2
server/sonar-server/src/main/resources/org/sonar/server/ce/ws/task-example.json View File

@@ -12,7 +12,8 @@
"startedAt": "2015-10-02T11:32:16+0200",
"executedAt": "2015-10-02T11:32:22+0200",
"executionTimeMs": 5286,
"errorMessage": "Failed to unzip analysis report",
"hasErrorStacktrace": true
"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)"
}
}

+ 4
- 9
server/sonar-server/src/test/java/org/sonar/server/ce/ws/TaskActionTest.java View File

@@ -45,7 +45,6 @@ import static org.mockito.Mockito.mock;
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;
import static org.sonar.db.ce.CeActivityDtoTestHelper.setHasErrorStacktrace;
import static org.sonarqube.ws.MediaTypes.PROTOBUF;

public class TaskActionTest {
@@ -133,7 +132,6 @@ public class TaskActionTest {
CeActivityDto activityDto = createActivityDto("TASK_1")
.setErrorMessage("error msg")
.setErrorStacktrace("error stack");
setHasErrorStacktrace(activityDto, true);
persist(activityDto);

TestResponse wsResponse = ws.newRequest()
@@ -146,8 +144,8 @@ public class TaskActionTest {
WsCe.Task task = taskResponse.getTask();
assertThat(task.getId()).isEqualTo("TASK_1");
assertThat(task.getErrorMessage()).isEqualTo(activityDto.getErrorMessage());
assertThat(task.hasHasErrorStacktrace()).isTrue();
assertThat(task.getHasErrorStacktrace()).isTrue();
assertThat(task.hasErrorStacktrace()).isTrue();
assertThat(task.getErrorStacktrace()).isEqualTo(activityDto.getErrorStacktrace());
}

@Test
@@ -157,7 +155,6 @@ public class TaskActionTest {
CeActivityDto activityDto = createActivityDto("TASK_1")
.setErrorMessage("error msg")
.setErrorStacktrace("error stack");
setHasErrorStacktrace(activityDto, true);
persist(activityDto);

TestResponse wsResponse = ws.newRequest()
@@ -169,8 +166,7 @@ public class TaskActionTest {
WsCe.Task task = taskResponse.getTask();
assertThat(task.getId()).isEqualTo("TASK_1");
assertThat(task.getErrorMessage()).isEqualTo(activityDto.getErrorMessage());
assertThat(task.hasHasErrorStacktrace()).isTrue();
assertThat(task.getHasErrorStacktrace()).isTrue();
assertThat(task.hasErrorStacktrace()).isFalse();
}

@Test
@@ -190,8 +186,7 @@ public class TaskActionTest {
WsCe.Task task = taskResponse.getTask();
assertThat(task.getId()).isEqualTo("TASK_1");
assertThat(task.getErrorMessage()).isEqualTo(activityDto.getErrorMessage());
assertThat(task.hasHasErrorStacktrace()).isTrue();
assertThat(task.getHasErrorStacktrace()).isFalse();
assertThat(task.hasErrorStacktrace()).isFalse();
}

@Test

+ 35
- 0
server/sonar-server/src/test/java/org/sonar/server/ce/ws/TaskFormatterTest.java View File

@@ -20,6 +20,7 @@
package org.sonar.server.ce.ws;

import java.io.IOException;
import java.util.Collections;
import java.util.Date;
import org.junit.Rule;
import org.junit.Test;
@@ -185,6 +186,40 @@ public class TaskFormatterTest {
assertThat(wsTasks).extracting("id").containsExactly("UUID1", "UUID2");
}

@Test
public void formatActivity_with_both_error_message_and_stacktrace() {
CeActivityDto dto = newActivity("UUID", "COMPONENT_UUID", CeActivityDto.Status.FAILED)
.setErrorMessage("error msg")
.setErrorStacktrace("error stacktrace");

WsCe.Task task = underTest.formatActivity(db.getSession(), Collections.singletonList(dto)).iterator().next();

assertThat(task.getErrorMessage()).isEqualTo(dto.getErrorMessage());
assertThat(task.getErrorStacktrace()).isEqualTo(dto.getErrorStacktrace());
}

@Test
public void formatActivity_with_both_error_message_only() {
CeActivityDto dto = newActivity("UUID", "COMPONENT_UUID", CeActivityDto.Status.FAILED)
.setErrorMessage("error msg");

WsCe.Task task = underTest.formatActivity(db.getSession(), Collections.singletonList(dto)).iterator().next();

assertThat(task.getErrorMessage()).isEqualTo(dto.getErrorMessage());
assertThat(task.hasErrorStacktrace()).isFalse();
}

@Test
public void formatActivity_with_both_error_message_and_only_stacktrace_flag() {
CeActivityDto dto = newActivity("UUID", "COMPONENT_UUID", CeActivityDto.Status.FAILED)
.setErrorMessage("error msg");

WsCe.Task task = underTest.formatActivity(db.getSession(), Collections.singletonList(dto)).iterator().next();

assertThat(task.getErrorMessage()).isEqualTo(dto.getErrorMessage());
assertThat(task.hasErrorStacktrace()).isFalse();
}

private CeActivityDto newActivity(String taskUuid, String componentUuid, CeActivityDto.Status status) {
CeQueueDto queueDto = new CeQueueDto();
queueDto.setCreatedAt(1_450_000_000_000L);

+ 1
- 1
sonar-ws/src/main/protobuf/ws-ce.proto View File

@@ -78,7 +78,7 @@ message Task {
optional int64 executionTimeMs = 14;
optional bool logs = 15;
optional string errorMessage = 16;
optional bool hasErrorStacktrace = 17;
optional string errorStacktrace = 17;
}

enum TaskStatus {

Loading…
Cancel
Save