diff options
author | Sébastien Lesaint <sebastien.lesaint@sonarsource.com> | 2016-08-17 11:03:46 +0200 |
---|---|---|
committer | Sébastien Lesaint <sebastien.lesaint@sonarsource.com> | 2016-08-18 12:37:32 +0200 |
commit | b3305db9ff2fd99996cb86f8a49f15194f3a3d91 (patch) | |
tree | e502be43421a914264c053f31245fb2d6d643c5c /server | |
parent | f7417645a148d2adacc1764f3fdb63a0c1d935a0 (diff) | |
download | sonarqube-b3305db9ff2fd99996cb86f8a49f15194f3a3d91.tar.gz sonarqube-b3305db9ff2fd99996cb86f8a49f15194f3a3d91.zip |
SONAR-7843 add error stacktrace to /api/ce/task
Diffstat (limited to 'server')
5 files changed, 89 insertions, 15 deletions
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 7ab69094164..99547db167a 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 @@ -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)); + } + } } 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 e17d2ac8f88..fddba7c4a65 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 @@ -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(); } diff --git a/server/sonar-server/src/main/resources/org/sonar/server/ce/ws/task-example.json b/server/sonar-server/src/main/resources/org/sonar/server/ce/ws/task-example.json index fd82567ebaa..65ee61da9c5 100644 --- a/server/sonar-server/src/main/resources/org/sonar/server/ce/ws/task-example.json +++ b/server/sonar-server/src/main/resources/org/sonar/server/ce/ws/task-example.json @@ -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)" } } 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 c38d7bbeeb5..0b18db34215 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 @@ -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 diff --git a/server/sonar-server/src/test/java/org/sonar/server/ce/ws/TaskFormatterTest.java b/server/sonar-server/src/test/java/org/sonar/server/ce/ws/TaskFormatterTest.java index 05435fb5156..6d4a2826502 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/ce/ws/TaskFormatterTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/ce/ws/TaskFormatterTest.java @@ -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); |