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 | |
parent | bfb8b46ce0f4850775ccab4e2fa13ed83901c842 (diff) | |
download | sonarqube-3ae18356c3fcafeb7b5348c8916098156cd0a824.tar.gz sonarqube-3ae18356c3fcafeb7b5348c8916098156cd0a824.zip |
SONAR-10347 Add search-by-webhook to webhook deliveries search ws.
18 files changed, 250 insertions, 33 deletions
diff --git a/server/sonar-db-core/src/main/resources/org/sonar/db/version/schema-h2.ddl b/server/sonar-db-core/src/main/resources/org/sonar/db/version/schema-h2.ddl index 3ab27f0b1ea..aad6a316acd 100644 --- a/server/sonar-db-core/src/main/resources/org/sonar/db/version/schema-h2.ddl +++ b/server/sonar-db-core/src/main/resources/org/sonar/db/version/schema-h2.ddl @@ -769,6 +769,7 @@ CREATE INDEX "PROJECT_WEBHOOK" ON "WEBHOOKS" ("PROJECT_UUID"); CREATE TABLE "WEBHOOK_DELIVERIES" ( "UUID" VARCHAR(40) NOT NULL PRIMARY KEY, + "WEBHOOK_UUID" VARCHAR(40), "COMPONENT_UUID" VARCHAR(40) NOT NULL, "ANALYSIS_UUID" VARCHAR(40), "CE_TASK_UUID" VARCHAR(40), diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/webhook/WebhookDeliveryDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/webhook/WebhookDeliveryDao.java index a67cd0390ab..2060cad60f7 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/webhook/WebhookDeliveryDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/webhook/WebhookDeliveryDao.java @@ -31,6 +31,13 @@ public class WebhookDeliveryDao implements Dao { } /** + * All the deliveries for the specified webhook. Results are ordered by descending date. + */ + public List<WebhookDeliveryLiteDto> selectByWebhookUuid(DbSession dbSession, String webhookUuid) { + return mapper(dbSession).selectByWebhookUuid(webhookUuid); + } + + /** * All the deliveries for the specified component. Results are ordered by descending date. */ public List<WebhookDeliveryLiteDto> selectOrderedByComponentUuid(DbSession dbSession, String componentUuid) { diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/webhook/WebhookDeliveryLiteDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/webhook/WebhookDeliveryLiteDto.java index 3f80bcb1331..af130a3d4d9 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/webhook/WebhookDeliveryLiteDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/webhook/WebhookDeliveryLiteDto.java @@ -26,6 +26,8 @@ import org.apache.commons.lang.builder.ToStringBuilder; public class WebhookDeliveryLiteDto<T extends WebhookDeliveryLiteDto> { /** Technical unique identifier, can't be null */ protected String uuid; + /** Technical unique identifier, can be null for migration */ + protected String webhookUuid; /** Component UUID, can't be null */ protected String componentUuid; /** Compute Engine task UUID, can be null */ @@ -50,7 +52,16 @@ public class WebhookDeliveryLiteDto<T extends WebhookDeliveryLiteDto> { public T setUuid(String s) { this.uuid = s; - return (T)this; + return (T) this; + } + + public String getWebhookUuid() { + return webhookUuid; + } + + public T setWebhookUuid(String webhookUuid) { + this.webhookUuid = webhookUuid; + return (T) this; } public String getComponentUuid() { @@ -59,7 +70,7 @@ public class WebhookDeliveryLiteDto<T extends WebhookDeliveryLiteDto> { public T setComponentUuid(String s) { this.componentUuid = s; - return (T)this; + return (T) this; } @CheckForNull @@ -69,7 +80,7 @@ public class WebhookDeliveryLiteDto<T extends WebhookDeliveryLiteDto> { public T setCeTaskUuid(@Nullable String s) { this.ceTaskUuid = s; - return (T)this; + return (T) this; } @CheckForNull @@ -79,7 +90,7 @@ public class WebhookDeliveryLiteDto<T extends WebhookDeliveryLiteDto> { public T setAnalysisUuid(@Nullable String s) { this.analysisUuid = s; - return (T)this; + return (T) this; } public String getName() { @@ -88,7 +99,7 @@ public class WebhookDeliveryLiteDto<T extends WebhookDeliveryLiteDto> { public T setName(String s) { this.name = s; - return (T)this; + return (T) this; } public boolean isSuccess() { @@ -97,7 +108,7 @@ public class WebhookDeliveryLiteDto<T extends WebhookDeliveryLiteDto> { public T setSuccess(boolean b) { this.success = b; - return (T)this; + return (T) this; } @CheckForNull @@ -107,7 +118,7 @@ public class WebhookDeliveryLiteDto<T extends WebhookDeliveryLiteDto> { public T setHttpStatus(@Nullable Integer i) { this.httpStatus = i; - return (T)this; + return (T) this; } @CheckForNull @@ -117,7 +128,7 @@ public class WebhookDeliveryLiteDto<T extends WebhookDeliveryLiteDto> { public T setDurationMs(@Nullable Integer i) { this.durationMs = i; - return (T)this; + return (T) this; } public String getUrl() { @@ -126,7 +137,7 @@ public class WebhookDeliveryLiteDto<T extends WebhookDeliveryLiteDto> { public T setUrl(String s) { this.url = s; - return (T)this; + return (T) this; } public long getCreatedAt() { @@ -135,7 +146,7 @@ public class WebhookDeliveryLiteDto<T extends WebhookDeliveryLiteDto> { public T setCreatedAt(long l) { this.createdAt = l; - return (T)this; + return (T) this; } @Override diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/webhook/WebhookDeliveryMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/webhook/WebhookDeliveryMapper.java index 8fd5b42bef8..f14eb163d1e 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/webhook/WebhookDeliveryMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/webhook/WebhookDeliveryMapper.java @@ -28,6 +28,8 @@ public interface WebhookDeliveryMapper { @CheckForNull WebhookDeliveryDto selectByUuid(@Param("uuid") String uuid); + List<WebhookDeliveryLiteDto> selectByWebhookUuid(@Param("webhookUuid") String webhookUuid); + List<WebhookDeliveryLiteDto> selectOrderedByComponentUuid(@Param("componentUuid") String componentUuid); List<WebhookDeliveryLiteDto> selectOrderedByCeTaskUuid(@Param("ceTaskUuid") String ceTaskUuid); diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/webhook/WebhookDeliveryMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/webhook/WebhookDeliveryMapper.xml index c13ead5a155..0612c971293 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/webhook/WebhookDeliveryMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/webhook/WebhookDeliveryMapper.xml @@ -7,6 +7,7 @@ <sql id="sqlLiteColumns"> uuid, component_uuid as componentUuid, + webhook_uuid as webhookUuid, ce_task_uuid as ceTaskUuid, name, url, @@ -25,6 +26,13 @@ where uuid = #{uuid,jdbcType=VARCHAR} </select> + <select id="selectByWebhookUuid" parameterType="String" resultType="org.sonar.db.webhook.WebhookDeliveryLiteDto"> + select <include refid="sqlLiteColumns" /> + from webhook_deliveries + where webhook_uuid = #{webhookUuid,jdbcType=VARCHAR} + order by created_at desc + </select> + <select id="selectOrderedByComponentUuid" parameterType="String" resultType="org.sonar.db.webhook.WebhookDeliveryLiteDto"> select <include refid="sqlLiteColumns" /> from webhook_deliveries @@ -42,6 +50,7 @@ <insert id="insert" parameterType="org.sonar.db.webhook.WebhookDeliveryDto" useGeneratedKeys="false"> insert into webhook_deliveries ( uuid, + webhook_uuid, component_uuid, ce_task_uuid, analysis_uuid, @@ -55,6 +64,7 @@ created_at ) values ( #{uuid,jdbcType=VARCHAR}, + #{webhookUuid,jdbcType=VARCHAR}, #{componentUuid,jdbcType=VARCHAR}, #{ceTaskUuid,jdbcType=VARCHAR}, #{analysisUuid,jdbcType=VARCHAR}, diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v71/AddWebhookKeyToWebhookDeliveriesTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v71/AddWebhookKeyToWebhookDeliveriesTable.java new file mode 100644 index 00000000000..ba6dd64e46b --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v71/AddWebhookKeyToWebhookDeliveriesTable.java @@ -0,0 +1,46 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.platform.db.migration.version.v71; + +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder; +import org.sonar.server.platform.db.migration.step.DdlChange; + +import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; + +public class AddWebhookKeyToWebhookDeliveriesTable extends DdlChange { + + public AddWebhookKeyToWebhookDeliveriesTable(Database db) { + super(db); + } + + @Override + public void execute(Context context) throws SQLException { + context.execute(new AddColumnsBuilder(getDialect(), "webhook_deliveries") + .addColumn(newVarcharColumnDefBuilder() + .setColumnName("webhook_uuid") + .setIsNullable(true) + .setLimit(40) + .build()) + .build()); + } + +} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v71/DbVersion71.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v71/DbVersion71.java index abe4af30f23..9c406e6eb99 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v71/DbVersion71.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v71/DbVersion71.java @@ -42,6 +42,7 @@ public class DbVersion71 implements DbVersion { .add(2012, "Rename table PROJECT_LINKS2 to PROJECT_LINKS", RenameTableProjectLinks2ToProjectLinks.class) .add(2013, "Create WEBHOOKS Table", CreateWebhooksTable.class) .add(2014, "Migrate webhooks from SETTINGS table to WEBHOOKS table", MigrateWebhooksToWebhooksTable.class) + .add(2015, "Add webhook key to WEBHOOK_DELIVERIES table", AddWebhookKeyToWebhookDeliveriesTable.class) ; } } diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v71/AddWebhookKeyToWebhookDeliveriesTableTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v71/AddWebhookKeyToWebhookDeliveriesTableTest.java new file mode 100644 index 00000000000..937a09a6066 --- /dev/null +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v71/AddWebhookKeyToWebhookDeliveriesTableTest.java @@ -0,0 +1,55 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.platform.db.migration.version.v71; + +import java.sql.SQLException; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.db.CoreDbTester; + +import static java.sql.Types.VARCHAR; +import static org.sonar.db.CoreDbTester.createForSchema; + +public class AddWebhookKeyToWebhookDeliveriesTableTest { + @Rule + public final CoreDbTester dbTester = createForSchema(AddWebhookKeyToWebhookDeliveriesTableTest.class, "webhook-deliveries.sql"); + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + private AddWebhookKeyToWebhookDeliveriesTable underTest = new AddWebhookKeyToWebhookDeliveriesTable(dbTester.database()); + + @Test + public void column_is_added_to_table() throws SQLException { + underTest.execute(); + + dbTester.assertColumnDefinition("webhook_deliveries", "webhook_uuid", VARCHAR, 40, true); + } + + @Test + public void migration_is_not_reentrant() throws SQLException { + underTest.execute(); + + expectedException.expect(IllegalStateException.class); + + underTest.execute(); + } +} diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v71/DbVersion71Test.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v71/DbVersion71Test.java index 70a599f9f6e..6b5041ef512 100644 --- a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v71/DbVersion71Test.java +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v71/DbVersion71Test.java @@ -36,7 +36,7 @@ public class DbVersion71Test { @Test public void verify_migration_count() { - verifyMigrationCount(underTest, 15); + verifyMigrationCount(underTest, 16); } } diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v71/AddWebhookKeyToWebhookDeliveriesTableTest/webhook-deliveries.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v71/AddWebhookKeyToWebhookDeliveriesTableTest/webhook-deliveries.sql new file mode 100644 index 00000000000..27263b0804b --- /dev/null +++ b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v71/AddWebhookKeyToWebhookDeliveriesTableTest/webhook-deliveries.sql @@ -0,0 +1,18 @@ +CREATE TABLE "WEBHOOK_DELIVERIES" ( + "UUID" VARCHAR(40) NOT NULL PRIMARY KEY, + "COMPONENT_UUID" VARCHAR(40) NOT NULL, + "ANALYSIS_UUID" VARCHAR(40), + "CE_TASK_UUID" VARCHAR(40), + "NAME" VARCHAR(100) NOT NULL, + "URL" VARCHAR(2000) NOT NULL, + "SUCCESS" BOOLEAN NOT NULL, + "HTTP_STATUS" INT, + "DURATION_MS" INT, + "PAYLOAD" CLOB NOT NULL, + "ERROR_STACKTRACE" CLOB, + "CREATED_AT" BIGINT NOT NULL +); +CREATE UNIQUE INDEX "PK_WEBHOOK_DELIVERIES" ON "WEBHOOK_DELIVERIES" ("UUID"); +CREATE INDEX "COMPONENT_UUID" ON "WEBHOOK_DELIVERIES" ("COMPONENT_UUID"); +CREATE INDEX "CE_TASK_UUID" ON "WEBHOOK_DELIVERIES" ("CE_TASK_UUID"); +CREATE INDEX "ANALYSIS_UUID" ON "WEBHOOK_DELIVERIES" ("ANALYSIS_UUID"); 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(); + } } |