diff options
author | Guillaume Jambet <guillaume.jambet@sonarsource.com> | 2018-02-14 15:41:26 +0100 |
---|---|---|
committer | Guillaume Jambet <guillaume.jambet@gmail.com> | 2018-03-01 15:21:05 +0100 |
commit | 3ae18356c3fcafeb7b5348c8916098156cd0a824 (patch) | |
tree | e0a8298543a9916ffefa39d6453a3cba381c7e61 /server/sonar-server | |
parent | bfb8b46ce0f4850775ccab4e2fa13ed83901c842 (diff) | |
download | sonarqube-3ae18356c3fcafeb7b5348c8916098156cd0a824.tar.gz sonarqube-3ae18356c3fcafeb7b5348c8916098156cd0a824.zip |
SONAR-10347 Add search-by-webhook to webhook deliveries search ws.
Diffstat (limited to 'server/sonar-server')
8 files changed, 88 insertions, 22 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/webhook/WebHooksImpl.java b/server/sonar-server/src/main/java/org/sonar/server/webhook/WebHooksImpl.java index 76851e8fd00..a5497710144 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/webhook/WebHooksImpl.java +++ b/server/sonar-server/src/main/java/org/sonar/server/webhook/WebHooksImpl.java @@ -73,7 +73,7 @@ public class WebHooksImpl implements WebHooks { @Override public void sendProjectAnalysisUpdate(Analysis analysis, Supplier<WebhookPayload> payloadSupplier) { List<Webhook> webhooks = readWebHooksFrom(analysis.getProjectUuid()) - .map(dto -> new Webhook(analysis.getProjectUuid(), analysis.getCeTaskUuid(), analysis.getAnalysisUuid(), dto.getName(), dto.getUrl())) + .map(dto -> new Webhook(dto.getUuid(), analysis.getProjectUuid(), analysis.getCeTaskUuid(), analysis.getAnalysisUuid(), dto.getName(), dto.getUrl())) .collect(MoreCollectors.toList()); if (webhooks.isEmpty()) { return; diff --git a/server/sonar-server/src/main/java/org/sonar/server/webhook/Webhook.java b/server/sonar-server/src/main/java/org/sonar/server/webhook/Webhook.java index 3a695549d62..8ac3b4c75a8 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/webhook/Webhook.java +++ b/server/sonar-server/src/main/java/org/sonar/server/webhook/Webhook.java @@ -29,13 +29,15 @@ import static java.util.Optional.ofNullable; @Immutable public class Webhook { + private final String uuid; private final String componentUuid; private final String ceTaskUuid; private final String analysisUuid; private final String name; private final String url; - public Webhook(String componentUuid, @Nullable String ceTaskUuid, @Nullable String analysisUuid, String name, String url) { + public Webhook(String uuid, String componentUuid, @Nullable String ceTaskUuid, @Nullable String analysisUuid, String name, String url) { + this.uuid = uuid; this.componentUuid = requireNonNull(componentUuid); this.ceTaskUuid = ceTaskUuid; this.analysisUuid = analysisUuid; @@ -59,6 +61,10 @@ public class Webhook { return url; } + public String getUuid() { + return uuid; + } + public Optional<String> getAnalysisUuid() { return ofNullable(analysisUuid); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/webhook/WebhookDeliveryStorage.java b/server/sonar-server/src/main/java/org/sonar/server/webhook/WebhookDeliveryStorage.java index 49062373b36..0ba9bb95c75 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/webhook/WebhookDeliveryStorage.java +++ b/server/sonar-server/src/main/java/org/sonar/server/webhook/WebhookDeliveryStorage.java @@ -65,6 +65,7 @@ public class WebhookDeliveryStorage { private WebhookDeliveryDto toDto(WebhookDelivery delivery) { WebhookDeliveryDto dto = new WebhookDeliveryDto(); dto.setUuid(uuidFactory.create()); + dto.setWebhookUuid(delivery.getWebhook().getUuid()); dto.setComponentUuid(delivery.getWebhook().getComponentUuid()); delivery.getWebhook().getCeTaskUuid().ifPresent(dto::setCeTaskUuid); delivery.getWebhook().getAnalysisUuid().ifPresent(dto::setAnalysisUuid); diff --git a/server/sonar-server/src/main/java/org/sonar/server/webhook/ws/WebhookDeliveriesAction.java b/server/sonar-server/src/main/java/org/sonar/server/webhook/ws/WebhookDeliveriesAction.java index 185bba7a271..685d384a9f9 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/webhook/ws/WebhookDeliveriesAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/webhook/ws/WebhookDeliveriesAction.java @@ -38,6 +38,8 @@ import org.sonarqube.ws.Webhooks; import static com.google.common.base.Preconditions.checkArgument; import static java.util.Objects.requireNonNull; +import static org.apache.commons.lang.StringUtils.isNotBlank; +import static org.sonar.core.util.Uuids.UUID_EXAMPLE_02; import static org.sonar.server.webhook.ws.WebhookWsSupport.copyDtoToProtobuf; import static org.sonar.server.ws.WsUtils.writeProtobuf; @@ -45,6 +47,7 @@ public class WebhookDeliveriesAction implements WebhooksWsAction { private static final String PARAM_COMPONENT = "componentKey"; private static final String PARAM_TASK = "ceTaskId"; + private static final String PARAM_WEBHOOK = "webhook"; private final DbClient dbClient; private final UserSession userSession; @@ -73,6 +76,12 @@ public class WebhookDeliveriesAction implements WebhooksWsAction { action.createParam(PARAM_TASK) .setDescription("Id of the Compute Engine task") .setExampleValue(Uuids.UUID_EXAMPLE_01); + + action.createParam(PARAM_WEBHOOK) + .setSince("7.1") + .setDescription("Key of the webhook that triggered those deliveries,"+ + "auto-generated value that can be obtained through api/webhooks/create or api/webhooks/list") + .setExampleValue(UUID_EXAMPLE_02); } @Override @@ -82,18 +91,23 @@ public class WebhookDeliveriesAction implements WebhooksWsAction { String ceTaskId = request.param(PARAM_TASK); String componentKey = request.param(PARAM_COMPONENT); - checkArgument(ceTaskId != null ^ componentKey != null, "Either '%s' or '%s' must be provided", PARAM_TASK, PARAM_COMPONENT); + String webhookUuid = request.param(PARAM_WEBHOOK); + + checkArgument(webhookUuid != null ^ (ceTaskId != null ^ componentKey != null), + "Either '%s' or '%s' or '%s' must be provided", PARAM_TASK, PARAM_COMPONENT, PARAM_WEBHOOK); - Data data = loadFromDatabase(ceTaskId, componentKey); + Data data = loadFromDatabase(webhookUuid, ceTaskId, componentKey); data.ensureAdminPermission(userSession); data.writeTo(request, response); } - private Data loadFromDatabase(@Nullable String ceTaskId, @Nullable String componentKey) { + private Data loadFromDatabase(@Nullable String webhookUuid, @Nullable String ceTaskId, @Nullable String componentKey) { ComponentDto component = null; List<WebhookDeliveryLiteDto> deliveries; try (DbSession dbSession = dbClient.openSession(false)) { - if (componentKey != null) { + if (isNotBlank(webhookUuid)) { + deliveries = dbClient.webhookDeliveryDao().selectByWebhookUuid(dbSession, webhookUuid); + } else if (componentKey != null) { component = componentFinder.getByKey(dbSession, componentKey); deliveries = dbClient.webhookDeliveryDao().selectOrderedByComponentUuid(dbSession, component.uuid()); } else { diff --git a/server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookCallerImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookCallerImplTest.java index 6a5e5270be4..1e174e6ba54 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookCallerImplTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookCallerImplTest.java @@ -45,6 +45,7 @@ public class WebhookCallerImplTest { private static final long NOW = 1_500_000_000_000L; private static final String PROJECT_UUID = "P_UUID1"; + private static final String WEBHOOK_UUID = "WH_UUID1"; private static final String CE_TASK_UUID = "CE_UUID1"; private static final String SOME_JSON = "{\"payload\": {}}"; private static final WebhookPayload PAYLOAD = new WebhookPayload("P1", SOME_JSON); @@ -59,12 +60,13 @@ public class WebhookCallerImplTest { @Test public void send_posts_payload_to_http_server() throws Exception { - Webhook webhook = new Webhook(PROJECT_UUID, CE_TASK_UUID, RandomStringUtils.randomAlphanumeric(40),"my-webhook", server.url("/ping").toString()); + Webhook webhook = new Webhook(WEBHOOK_UUID, PROJECT_UUID, CE_TASK_UUID, RandomStringUtils.randomAlphanumeric(40),"my-webhook", server.url("/ping").toString()); server.enqueue(new MockResponse().setBody("pong").setResponseCode(201)); WebhookDelivery delivery = newSender().call(webhook, PAYLOAD); assertThat(delivery.getHttpStatus()).hasValue(201); + assertThat(delivery.getWebhook().getUuid()).isEqualTo(WEBHOOK_UUID); assertThat(delivery.getDurationInMs().get()).isGreaterThanOrEqualTo(0); assertThat(delivery.getError()).isEmpty(); assertThat(delivery.getAt()).isEqualTo(NOW); @@ -82,7 +84,7 @@ public class WebhookCallerImplTest { @Test public void silently_catch_error_when_external_server_does_not_answer() throws Exception { - Webhook webhook = new Webhook(PROJECT_UUID, CE_TASK_UUID, RandomStringUtils.randomAlphanumeric(40),"my-webhook", server.url("/ping").toString()); + Webhook webhook = new Webhook(WEBHOOK_UUID, PROJECT_UUID, CE_TASK_UUID, RandomStringUtils.randomAlphanumeric(40),"my-webhook", server.url("/ping").toString()); server.shutdown(); WebhookDelivery delivery = newSender().call(webhook, PAYLOAD); @@ -98,7 +100,7 @@ public class WebhookCallerImplTest { @Test public void silently_catch_error_when_url_is_incorrect() { - Webhook webhook = new Webhook(PROJECT_UUID, CE_TASK_UUID, RandomStringUtils.randomAlphanumeric(40),"my-webhook", "this_is_not_an_url"); + Webhook webhook = new Webhook(WEBHOOK_UUID, PROJECT_UUID, CE_TASK_UUID, RandomStringUtils.randomAlphanumeric(40),"my-webhook", "this_is_not_an_url"); WebhookDelivery delivery = newSender().call(webhook, PAYLOAD); @@ -116,7 +118,7 @@ public class WebhookCallerImplTest { */ @Test public void redirects_should_be_followed_with_POST_method() throws Exception { - Webhook webhook = new Webhook(PROJECT_UUID, CE_TASK_UUID, RandomStringUtils.randomAlphanumeric(40),"my-webhook", server.url("/redirect").toString()); + Webhook webhook = new Webhook(WEBHOOK_UUID, PROJECT_UUID, CE_TASK_UUID, RandomStringUtils.randomAlphanumeric(40),"my-webhook", server.url("/redirect").toString()); // /redirect redirects to /target server.enqueue(new MockResponse().setResponseCode(307).setHeader("Location", server.url("target"))); @@ -138,7 +140,7 @@ public class WebhookCallerImplTest { @Test public void credentials_are_propagated_to_POST_redirects() throws Exception { HttpUrl url = server.url("/redirect").newBuilder().username("theLogin").password("thePassword").build(); - Webhook webhook = new Webhook(PROJECT_UUID, CE_TASK_UUID, RandomStringUtils.randomAlphanumeric(40),"my-webhook", url.toString()); + Webhook webhook = new Webhook(WEBHOOK_UUID, PROJECT_UUID, CE_TASK_UUID, RandomStringUtils.randomAlphanumeric(40),"my-webhook", url.toString()); // /redirect redirects to /target server.enqueue(new MockResponse().setResponseCode(307).setHeader("Location", server.url("target"))); @@ -158,7 +160,7 @@ public class WebhookCallerImplTest { @Test public void redirects_throws_ISE_if_header_Location_is_missing() { HttpUrl url = server.url("/redirect"); - Webhook webhook = new Webhook(PROJECT_UUID, CE_TASK_UUID, RandomStringUtils.randomAlphanumeric(40),"my-webhook", url.toString()); + Webhook webhook = new Webhook(WEBHOOK_UUID, PROJECT_UUID, CE_TASK_UUID, RandomStringUtils.randomAlphanumeric(40),"my-webhook", url.toString()); server.enqueue(new MockResponse().setResponseCode(307)); @@ -173,7 +175,7 @@ public class WebhookCallerImplTest { @Test public void redirects_throws_ISE_if_header_Location_does_not_relate_to_a_supported_protocol() { HttpUrl url = server.url("/redirect"); - Webhook webhook = new Webhook(PROJECT_UUID, CE_TASK_UUID, RandomStringUtils.randomAlphanumeric(40),"my-webhook", url.toString()); + Webhook webhook = new Webhook(WEBHOOK_UUID, PROJECT_UUID, CE_TASK_UUID, RandomStringUtils.randomAlphanumeric(40),"my-webhook", url.toString()); server.enqueue(new MockResponse().setResponseCode(307).setHeader("Location", "ftp://foo")); @@ -188,7 +190,7 @@ public class WebhookCallerImplTest { @Test public void send_basic_authentication_header_if_url_contains_credentials() throws Exception { HttpUrl url = server.url("/ping").newBuilder().username("theLogin").password("thePassword").build(); - Webhook webhook = new Webhook(PROJECT_UUID, CE_TASK_UUID, RandomStringUtils.randomAlphanumeric(40),"my-webhook", url.toString()); + Webhook webhook = new Webhook(WEBHOOK_UUID, PROJECT_UUID, CE_TASK_UUID, RandomStringUtils.randomAlphanumeric(40),"my-webhook", url.toString()); server.enqueue(new MockResponse().setBody("pong")); WebhookDelivery delivery = newSender().call(webhook, PAYLOAD); diff --git a/server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookDeliveryStorageTest.java b/server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookDeliveryStorageTest.java index 5f63dc54209..158fdd73002 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookDeliveryStorageTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookDeliveryStorageTest.java @@ -62,6 +62,7 @@ public class WebhookDeliveryStorageTest { WebhookDeliveryDto dto = dbClient.webhookDeliveryDao().selectByUuid(dbSession, DELIVERY_UUID).get(); assertThat(dto.getUuid()).isEqualTo(DELIVERY_UUID); + assertThat(dto.getWebhookUuid()).isEqualTo("WEBHOOK_UUID_1"); assertThat(dto.getComponentUuid()).isEqualTo(delivery.getWebhook().getComponentUuid()); assertThat(dto.getCeTaskUuid()).isEqualTo(delivery.getWebhook().getCeTaskUuid().get()); assertThat(dto.getName()).isEqualTo(delivery.getWebhook().getName()); @@ -102,7 +103,7 @@ public class WebhookDeliveryStorageTest { private static WebhookDelivery.Builder newBuilderTemplate() { return new WebhookDelivery.Builder() - .setWebhook(new Webhook("COMPONENT1", "TASK1", RandomStringUtils.randomAlphanumeric(40),"Jenkins", "http://jenkins")) + .setWebhook(new Webhook("WEBHOOK_UUID_1", "COMPONENT1", "TASK1", RandomStringUtils.randomAlphanumeric(40),"Jenkins", "http://jenkins")) .setPayload(new WebhookPayload("my-project", "{json}")) .setAt(1_000_000L) .setHttpStatus(200) diff --git a/server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookTest.java b/server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookTest.java index c73aee52cc9..64778c0dfa4 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookTest.java @@ -36,21 +36,21 @@ public class WebhookTest { public void constructor_with_null_componentUuid_should_throw_NPE() { expectedException.expect(NullPointerException.class); - new Webhook(null, null, null, randomAlphanumeric(10), randomAlphanumeric(10)); + new Webhook(randomAlphanumeric(40), null, null, null, randomAlphanumeric(10), randomAlphanumeric(10)); } @Test public void constructor_with_null_name_should_throw_NPE() { expectedException.expect(NullPointerException.class); - new Webhook(randomAlphanumeric(10), null, null, null, randomAlphanumeric(10)); + new Webhook(randomAlphanumeric(40), randomAlphanumeric(10), null, null, null, randomAlphanumeric(10)); } @Test public void constructor_with_null_url_should_throw_NPE() { expectedException.expect(NullPointerException.class); - new Webhook(randomAlphanumeric(10), null, null, randomAlphanumeric(10), null); + new Webhook(randomAlphanumeric(40), randomAlphanumeric(10), null, null, randomAlphanumeric(10), null); } @Test @@ -58,7 +58,7 @@ public class WebhookTest { String componentUuid = randomAlphanumeric(10); String name = randomAlphanumeric(10); String url = randomAlphanumeric(10); - Webhook underTest = new Webhook(componentUuid, null, null, name, url); + Webhook underTest = new Webhook(randomAlphanumeric(40), componentUuid, null, null, name, url); assertThat(underTest.getComponentUuid()).isEqualTo(componentUuid); assertThat(underTest.getName()).isEqualTo(name); @@ -68,7 +68,7 @@ public class WebhookTest { String ceTaskUuid = randomAlphanumeric(10); String analysisUuid = randomAlphanumeric(10); - underTest = new Webhook(componentUuid, ceTaskUuid, analysisUuid, name, url); + underTest = new Webhook(randomAlphanumeric(40), componentUuid, ceTaskUuid, analysisUuid, name, url); assertThat(underTest.getComponentUuid()).isEqualTo(componentUuid); assertThat(underTest.getName()).isEqualTo(name); assertThat(underTest.getUrl()).isEqualTo(url); diff --git a/server/sonar-server/src/test/java/org/sonar/server/webhook/ws/WebhookDeliveriesActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/webhook/ws/WebhookDeliveriesActionTest.java index 14d91c65782..e8b9c9c9ca8 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/webhook/ws/WebhookDeliveriesActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/webhook/ws/WebhookDeliveriesActionTest.java @@ -68,7 +68,7 @@ public class WebhookDeliveriesActionTest { @Test public void test_definition() { - assertThat(ws.getDef().params()).extracting(WebService.Param::key).containsOnly("componentKey", "ceTaskId"); + assertThat(ws.getDef().params()).extracting(WebService.Param::key).containsExactlyInAnyOrder("componentKey", "ceTaskId", "webhook"); assertThat(ws.getDef().isPost()).isFalse(); assertThat(ws.getDef().isInternal()).isFalse(); assertThat(ws.getDef().responseExampleAsString()).isNotEmpty(); @@ -104,6 +104,17 @@ public class WebhookDeliveriesActionTest { } @Test + public void search_by_webhook_and_return_no_records() { + userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + + Webhooks.DeliveriesWsResponse response = ws.newRequest() + .setParam("webhook", "t1") + .executeProtobuf(Webhooks.DeliveriesWsResponse.class); + + assertThat(response.getDeliveriesCount()).isEqualTo(0); + } + + @Test public void search_by_component_and_return_records_of_example() { WebhookDeliveryDto dto = newWebhookDeliveryDto() .setUuid("d1") @@ -146,6 +157,24 @@ public class WebhookDeliveriesActionTest { } @Test + public void search_by_webhook_and_return_records() { + WebhookDeliveryDto dto1 = newWebhookDeliveryDto().setComponentUuid(project.uuid()).setCeTaskUuid("t1").setWebhookUuid("wh-1-uuid"); + WebhookDeliveryDto dto2 = newWebhookDeliveryDto().setComponentUuid(project.uuid()).setCeTaskUuid("t1").setWebhookUuid("wh-1-uuid"); + WebhookDeliveryDto dto3 = newWebhookDeliveryDto().setComponentUuid(project.uuid()).setCeTaskUuid("t2").setWebhookUuid("wh-2-uuid"); + dbClient.webhookDeliveryDao().insert(db.getSession(), dto1); + dbClient.webhookDeliveryDao().insert(db.getSession(), dto2); + dbClient.webhookDeliveryDao().insert(db.getSession(), dto3); + db.commit(); + userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + + Webhooks.DeliveriesWsResponse response = ws.newRequest() + .setParam("ceTaskId", "t1") + .executeProtobuf(Webhooks.DeliveriesWsResponse.class); + assertThat(response.getDeliveriesCount()).isEqualTo(2); + assertThat(response.getDeliveriesList()).extracting(Webhooks.Delivery::getId).containsOnly(dto1.getUuid(), dto2.getUuid()); + } + + @Test public void search_by_component_and_throw_ForbiddenException_if_not_admin_of_project() { WebhookDeliveryDto dto = newWebhookDeliveryDto() .setComponentUuid(project.uuid()); @@ -182,11 +211,24 @@ public class WebhookDeliveriesActionTest { userSession.logIn(); expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Either 'ceTaskId' or 'componentKey' must be provided"); + expectedException.expectMessage("Either 'ceTaskId' or 'componentKey' or 'webhook' must be provided"); ws.newRequest() .setParam("componentKey", project.getDbKey()) .setParam("ceTaskId", "t1") .execute(); } + + @Test + public void throw_IAE_if_both_component_and_webhook_are_set() { + userSession.logIn(); + + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Either 'ceTaskId' or 'componentKey' or 'webhook' must be provided"); + + ws.newRequest() + .setParam("componentKey", project.getDbKey()) + .setParam("webhook", "wh-uuid") + .execute(); + } } |