From: Sébastien Lesaint Date: Mon, 25 Sep 2017 09:49:34 +0000 (+0200) Subject: SONAR-9869 add changedAt to webhook payload X-Git-Tag: 6.7-RC1~216 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=71ef1938601a0da3c192f1fbad4062052c970b92;p=sonarqube.git SONAR-9869 add changedAt to webhook payload --- diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPayloadFactoryImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPayloadFactoryImpl.java index e465cdd778a..abde30e6469 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPayloadFactoryImpl.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPayloadFactoryImpl.java @@ -21,6 +21,7 @@ package org.sonar.server.computation.task.projectanalysis.webhook; import java.io.StringWriter; import java.io.Writer; +import java.util.Date; import javax.annotation.Nullable; import org.sonar.api.ce.ComputeEngineSide; import org.sonar.api.ce.posttask.Branch; @@ -30,6 +31,7 @@ import org.sonar.api.ce.posttask.Project; import org.sonar.api.ce.posttask.QualityGate; import org.sonar.api.ce.posttask.ScannerContext; import org.sonar.api.platform.Server; +import org.sonar.api.utils.System2; import org.sonar.api.utils.text.JsonWriter; import static org.sonar.core.config.WebhookProperties.ANALYSIS_PROPERTY_PREFIX; @@ -38,9 +40,11 @@ import static org.sonar.core.config.WebhookProperties.ANALYSIS_PROPERTY_PREFIX; public class WebhookPayloadFactoryImpl implements WebhookPayloadFactory { private final Server server; + private final System2 system2; - public WebhookPayloadFactoryImpl(Server server) { + public WebhookPayloadFactoryImpl(Server server, System2 system2) { this.server = server; + this.system2 = system2; } @Override @@ -50,7 +54,7 @@ public class WebhookPayloadFactoryImpl implements WebhookPayloadFactory { writer.beginObject(); writeServer(writer); writeTask(writer, analysis.getCeTask()); - analysis.getAnalysisDate().ifPresent(date -> writer.propDateTime("analysedAt", date)); + writeDates(writer, analysis, system2); writeProject(analysis, writer, analysis.getProject()); analysis.getBranch().ifPresent(b -> writeBranch(writer, b)); writeQualityGate(writer, analysis.getQualityGate()); @@ -64,6 +68,20 @@ public class WebhookPayloadFactoryImpl implements WebhookPayloadFactory { writer.prop("serverUrl", server.getPublicRootUrl()); } + private static void writeDates(JsonWriter writer, PostProjectAnalysisTask.ProjectAnalysis analysis, System2 system2) { + analysis.getAnalysisDate().ifPresent(date -> writer.propDateTime("analysedAt", date)); + writer.propDateTime("changedAt", analysis.getAnalysisDate().orElseGet(() -> new Date(system2.now()))); + } + + private void writeProject(PostProjectAnalysisTask.ProjectAnalysis analysis, JsonWriter writer, Project project) { + writer + .name("project") + .beginObject() + .prop("key", project.getKey()) + .prop("name", analysis.getProject().getName()) + .endObject(); + } + private static void writeAnalysisProperties(JsonWriter writer, ScannerContext scannerContext) { writer .name("properties") @@ -81,16 +99,7 @@ public class WebhookPayloadFactoryImpl implements WebhookPayloadFactory { .prop("status", ceTask.getStatus().toString()); } - private static void writeProject(PostProjectAnalysisTask.ProjectAnalysis analysis, JsonWriter writer, Project project) { - writer - .name("project") - .beginObject() - .prop("key", project.getKey()) - .prop("name", analysis.getProject().getName()) - .endObject(); - } - - private static void writeBranch(JsonWriter writer, Branch branch) { + private void writeBranch(JsonWriter writer, Branch branch) { writer .name("branch") .beginObject() diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPayloadFactoryImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPayloadFactoryImplTest.java index 67a0cc4564e..e86609131ad 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPayloadFactoryImplTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPayloadFactoryImplTest.java @@ -33,6 +33,7 @@ import org.sonar.api.ce.posttask.Project; import org.sonar.api.ce.posttask.QualityGate; import org.sonar.api.ce.posttask.ScannerContext; import org.sonar.api.platform.Server; +import org.sonar.api.utils.System2; import org.sonar.server.computation.task.projectanalysis.api.posttask.BranchImpl; import static java.util.Collections.emptyMap; @@ -51,12 +52,13 @@ public class WebhookPayloadFactoryImplTest { private static final String PROJECT_KEY = "P1"; private Server server = mock(Server.class); - private WebhookPayloadFactory underTest = new WebhookPayloadFactoryImpl(server); + private System2 system2 = mock(System2.class); + private WebhookPayloadFactory underTest = new WebhookPayloadFactoryImpl(server, system2); @Before public void setUp() throws Exception { when(server.getPublicRootUrl()).thenReturn("http://foo"); - + when(system2.now()).thenReturn(1_500_999L); } @Test @@ -77,11 +79,39 @@ public class WebhookPayloadFactoryImplTest { .setErrorThreshold("70.0") .build(QualityGate.EvaluationStatus.WARN, "74.0")) .build(); - PostProjectAnalysisTask.ProjectAnalysis analysis = newAnalysis(task, gate, null, emptyMap()); + PostProjectAnalysisTask.ProjectAnalysis analysis = newAnalysis(task, gate, null, 1_500_000_000_000L, emptyMap()); WebhookPayload payload = underTest.create(analysis); assertThat(payload.getProjectKey()).isEqualTo(PROJECT_KEY); - assertJson(payload.getJson()).isSimilarTo(getClass().getResource("WebhookPayloadTest/success.json")); + assertJson(payload.getJson()) + .isSimilarTo("{" + + " \"serverUrl\": \"http://foo\"," + + " \"taskId\": \"#1\"," + + " \"status\": \"SUCCESS\"," + + " \"analysedAt\": \"2017-07-14T04:40:00+0200\"," + + " \"changedAt\": \"2017-07-14T04:40:00+0200\"," + + " \"project\": {" + + " \"key\": \"P1\"," + + " \"name\": \"Project One\"" + + " }," + + " \"qualityGate\": {" + + " \"name\": \"Gate One\"," + + " \"status\": \"WARN\"," + + " \"conditions\": [" + + " {" + + " \"metric\": \"coverage\"," + + " \"operator\": \"GREATER_THAN\"," + + " \"value\": \"74.0\"," + + " \"status\": \"WARN\"," + + " \"onLeakPeriod\": true," + + " \"errorThreshold\": \"70.0\"," + + " \"warningThreshold\": \"75.0\"" + + " }" + + " ]" + + " }," + + " \"properties\": {" + + " }" + + "}"); } @Test @@ -101,11 +131,36 @@ public class WebhookPayloadFactoryImplTest { .setErrorThreshold("70.0") .buildNoValue()) .build(); - PostProjectAnalysisTask.ProjectAnalysis analysis = newAnalysis(task, gate, null, emptyMap()); + PostProjectAnalysisTask.ProjectAnalysis analysis = newAnalysis(task, gate, null, 1_500_000_000_000L, emptyMap()); WebhookPayload payload = underTest.create(analysis); assertThat(payload.getProjectKey()).isEqualTo(PROJECT_KEY); - assertJson(payload.getJson()).isSimilarTo(getClass().getResource("WebhookPayloadTest/gate_condition_without_value.json")); + assertJson(payload.getJson()) + .isSimilarTo("{" + + " \"serverUrl\": \"http://foo\"," + + " \"taskId\": \"#1\"," + + " \"status\": \"SUCCESS\"," + + " \"analysedAt\": \"2017-07-14T04:40:00+0200\"," + + " \"changedAt\": \"2017-07-14T04:40:00+0200\"," + + " \"project\": {" + + " \"key\": \"P1\"," + + " \"name\": \"Project One\"" + + " }," + + " \"qualityGate\": {" + + " \"name\": \"Gate One\"," + + " \"status\": \"WARN\"," + + " \"conditions\": [" + + " {" + + " \"metric\": \"coverage\"," + + " \"operator\": \"GREATER_THAN\"," + + " \"status\": \"NO_VALUE\"," + + " \"onLeakPeriod\": false," + + " \"errorThreshold\": \"70.0\"," + + " \"warningThreshold\": \"75.0\"" + + " }" + + " ]" + + " }" + + "}"); } @Test @@ -124,10 +179,31 @@ public class WebhookPayloadFactoryImplTest { "sonar.analysis.buildNumber", "B123", "not.prefixed.with.sonar.analysis", "should be ignored", "ignored", "should be ignored too"); - PostProjectAnalysisTask.ProjectAnalysis analysis = newAnalysis(task, gate, null, scannerProperties); + PostProjectAnalysisTask.ProjectAnalysis analysis = newAnalysis(task, gate, null, 1_500_000_000_000L, scannerProperties); WebhookPayload payload = underTest.create(analysis); - assertJson(payload.getJson()).isSimilarTo(getClass().getResource("WebhookPayloadTest/with_analysis_properties.json")); + assertJson(payload.getJson()) + .isSimilarTo("{" + + " \"serverUrl\": \"http://foo\"," + + " \"taskId\": \"#1\"," + + " \"status\": \"SUCCESS\"," + + " \"analysedAt\": \"2017-07-14T04:40:00+0200\"," + + " \"changedAt\": \"2017-07-14T04:40:00+0200\"," + + " \"project\": {" + + " \"key\": \"P1\"," + + " \"name\": \"Project One\"" + + " }," + + " \"qualityGate\": {" + + " \"name\": \"Gate One\"," + + " \"status\": \"WARN\"," + + " \"conditions\": [" + + " ]" + + " }," + + " \"properties\": {" + + " \"sonar.analysis.revision\": \"ab45d24\"," + + " \"sonar.analysis.buildNumber\": \"B123\"" + + " }" + + "}"); assertThat(payload.getJson()) .doesNotContain("not.prefixed.with.sonar.analysis") .doesNotContain("ignored"); @@ -136,12 +212,47 @@ public class WebhookPayloadFactoryImplTest { @Test public void create_payload_for_failed_analysis() { CeTask ceTask = newCeTaskBuilder().setStatus(CeTask.Status.FAILED).setId("#1").build(); - PostProjectAnalysisTask.ProjectAnalysis analysis = newAnalysis(ceTask, null, null, emptyMap()); + PostProjectAnalysisTask.ProjectAnalysis analysis = newAnalysis(ceTask, null, null, 1_500_000_000_000L, emptyMap()); + + WebhookPayload payload = underTest.create(analysis); + + assertThat(payload.getProjectKey()).isEqualTo(PROJECT_KEY); + assertJson(payload.getJson()) + .isSimilarTo("{" + + " \"serverUrl\": \"http://foo\"," + + " \"taskId\": \"#1\"," + + " \"status\": \"FAILED\"," + + " \"changedAt\": \"2017-07-14T04:40:00+0200\"," + + " \"project\": {" + + " \"key\": \"P1\"," + + " \"name\": \"Project One\"" + + " }," + + " \"properties\": {" + + " }" + + "}"); + } + + @Test + public void create_payload_for_no_analysis_date() { + CeTask ceTask = newCeTaskBuilder().setStatus(CeTask.Status.FAILED).setId("#1").build(); + PostProjectAnalysisTask.ProjectAnalysis analysis = newAnalysis(ceTask, null, null, null, emptyMap()); WebhookPayload payload = underTest.create(analysis); assertThat(payload.getProjectKey()).isEqualTo(PROJECT_KEY); - assertJson(payload.getJson()).isSimilarTo(getClass().getResource("WebhookPayloadTest/failed.json")); + assertJson(payload.getJson()) + .isSimilarTo("{" + + " \"serverUrl\": \"http://foo\"," + + " \"taskId\": \"#1\"," + + " \"status\": \"FAILED\"," + + " \"changedAt\": \"1970-01-01T01:25:00+0100\"," + + " \"project\": {" + + " \"key\": \"P1\"," + + " \"name\": \"Project One\"" + + " }," + + " \"properties\": {" + + " }" + + "}"); } @Test @@ -150,7 +261,7 @@ public class WebhookPayloadFactoryImplTest { .setStatus(CeTask.Status.SUCCESS) .setId("#1") .build(); - PostProjectAnalysisTask.ProjectAnalysis analysis = newAnalysis(task, null, new BranchImpl(false, "feature/foo", Branch.Type.SHORT), emptyMap()); + PostProjectAnalysisTask.ProjectAnalysis analysis = newAnalysis(task, null, new BranchImpl(false, "feature/foo", Branch.Type.SHORT), 1_500_000_000_000L, emptyMap()); WebhookPayload payload = underTest.create(analysis); assertJson(payload.getJson()).isSimilarTo("{" + @@ -168,7 +279,7 @@ public class WebhookPayloadFactoryImplTest { .setStatus(CeTask.Status.SUCCESS) .setId("#1") .build(); - PostProjectAnalysisTask.ProjectAnalysis analysis = newAnalysis(task, null, new BranchImpl(true, null, Branch.Type.LONG), emptyMap()); + PostProjectAnalysisTask.ProjectAnalysis analysis = newAnalysis(task, null, new BranchImpl(true, null, Branch.Type.LONG), 1_500_000_000_000L, emptyMap()); WebhookPayload payload = underTest.create(analysis); assertJson(payload.getJson()).isSimilarTo("{" + @@ -179,8 +290,8 @@ public class WebhookPayloadFactoryImplTest { "}"); } - private static PostProjectAnalysisTask.ProjectAnalysis newAnalysis(CeTask task, @Nullable QualityGate gate, @Nullable Branch branch, - Map scannerProperties) { + private static PostProjectAnalysisTask.ProjectAnalysis newAnalysis(CeTask task, @Nullable QualityGate gate, + @Nullable Branch branch, @Nullable Long analysisDate, Map scannerProperties) { return new PostProjectAnalysisTask.ProjectAnalysis() { @Override public CeTask getCeTask() { @@ -213,7 +324,7 @@ public class WebhookPayloadFactoryImplTest { @Override public Optional getAnalysisDate() { - return Optional.of(new Date(1_500_000_000_000L)); + return Optional.ofNullable(analysisDate).map(Date::new); } @Override diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPayloadTest/failed.json b/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPayloadTest/failed.json deleted file mode 100644 index a8bce14cc4d..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPayloadTest/failed.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "serverUrl": "http://foo", - "taskId": "#1", - "status": "FAILED", - "project": { - "key": "P1", - "name": "Project One" - }, - "properties": { - } -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPayloadTest/gate_condition_without_value.json b/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPayloadTest/gate_condition_without_value.json deleted file mode 100644 index 6d54effb6c8..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPayloadTest/gate_condition_without_value.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "serverUrl": "http://foo", - "taskId": "#1", - "status": "SUCCESS", - "analysedAt": "2017-07-14T04:40:00+0200", - "project": { - "key": "P1", - "name": "Project One" - }, - "qualityGate": { - "name": "Gate One", - "status": "WARN", - "conditions": [ - { - "metric": "coverage", - "operator": "GREATER_THAN", - "status": "NO_VALUE", - "onLeakPeriod": false, - "errorThreshold": "70.0", - "warningThreshold": "75.0" - } - ] - } -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPayloadTest/success.json b/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPayloadTest/success.json deleted file mode 100644 index db37186442a..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPayloadTest/success.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "serverUrl": "http://foo", - "taskId": "#1", - "status": "SUCCESS", - "analysedAt": "2017-07-14T04:40:00+0200", - "project": { - "key": "P1", - "name": "Project One" - }, - "qualityGate": { - "name": "Gate One", - "status": "WARN", - "conditions": [ - { - "metric": "coverage", - "operator": "GREATER_THAN", - "value": "74.0", - "status": "WARN", - "onLeakPeriod": true, - "errorThreshold": "70.0", - "warningThreshold": "75.0" - } - ] - }, - "properties": { - } -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPayloadTest/with_analysis_properties.json b/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPayloadTest/with_analysis_properties.json deleted file mode 100644 index d518f229091..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPayloadTest/with_analysis_properties.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "serverUrl": "http://foo", - "taskId": "#1", - "status": "SUCCESS", - "analysedAt": "2017-07-14T04:40:00+0200", - "project": { - "key": "P1", - "name": "Project One" - }, - "qualityGate": { - "name": "Gate One", - "status": "WARN", - "conditions": [ - ] - }, - "properties": { - "sonar.analysis.revision": "ab45d24", - "sonar.analysis.buildNumber": "B123" - } -}