diff options
author | Sébastien Lesaint <sebastien.lesaint@sonarsource.com> | 2016-08-18 12:07:27 +0200 |
---|---|---|
committer | Sébastien Lesaint <sebastien.lesaint@sonarsource.com> | 2016-08-22 10:25:43 +0200 |
commit | 5a15f58bd1ec2fc67bdba15470b827ad0b95c547 (patch) | |
tree | ff1defea0132da156eba5c37638f26101aa2decc | |
parent | 3cdbd91927c88959d933b2f14ef7da43e090e533 (diff) | |
download | sonarqube-5a15f58bd1ec2fc67bdba15470b827ad0b95c547.tar.gz sonarqube-5a15f58bd1ec2fc67bdba15470b827ad0b95c547.zip |
SONAR-7845 add scannerContext to /api/ce/task
6 files changed, 133 insertions, 42 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 99547db167a..b10e3a767a4 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 @@ -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)); } } 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 0f260829843..9137a3de63e 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 @@ -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(); } 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 65ee61da9c5..3d43de5e682 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 @@ -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)" } } 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 5a9e1893a73..269f6209913 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 @@ -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; } 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 0c75a8e0fd0..a5851054d7a 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 @@ -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 diff --git a/sonar-ws/src/main/protobuf/ws-ce.proto b/sonar-ws/src/main/protobuf/ws-ce.proto index 69caa3cb99e..125b79257fb 100644 --- a/sonar-ws/src/main/protobuf/ws-ce.proto +++ b/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 { |