]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-10347 Add search-by-webhook to webhook deliveries search ws.
authorGuillaume Jambet <guillaume.jambet@sonarsource.com>
Wed, 14 Feb 2018 14:41:26 +0000 (15:41 +0100)
committerGuillaume Jambet <guillaume.jambet@gmail.com>
Thu, 1 Mar 2018 14:21:05 +0000 (15:21 +0100)
18 files changed:
server/sonar-db-core/src/main/resources/org/sonar/db/version/schema-h2.ddl
server/sonar-db-dao/src/main/java/org/sonar/db/webhook/WebhookDeliveryDao.java
server/sonar-db-dao/src/main/java/org/sonar/db/webhook/WebhookDeliveryLiteDto.java
server/sonar-db-dao/src/main/java/org/sonar/db/webhook/WebhookDeliveryMapper.java
server/sonar-db-dao/src/main/resources/org/sonar/db/webhook/WebhookDeliveryMapper.xml
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v71/AddWebhookKeyToWebhookDeliveriesTable.java [new file with mode: 0644]
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v71/DbVersion71.java
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v71/AddWebhookKeyToWebhookDeliveriesTableTest.java [new file with mode: 0644]
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v71/DbVersion71Test.java
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v71/AddWebhookKeyToWebhookDeliveriesTableTest/webhook-deliveries.sql [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/webhook/WebHooksImpl.java
server/sonar-server/src/main/java/org/sonar/server/webhook/Webhook.java
server/sonar-server/src/main/java/org/sonar/server/webhook/WebhookDeliveryStorage.java
server/sonar-server/src/main/java/org/sonar/server/webhook/ws/WebhookDeliveriesAction.java
server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookCallerImplTest.java
server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookDeliveryStorageTest.java
server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookTest.java
server/sonar-server/src/test/java/org/sonar/server/webhook/ws/WebhookDeliveriesActionTest.java

index 3ab27f0b1eaa08c9f99cf55c80ad5c66a825da9e..aad6a316acdab41c1a8df7e24c8382915f3f3f07 100644 (file)
@@ -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),
index a67cd0390ab0bb3489f3ad42098ea89473e3fce5..2060cad60f7afb1a9a5aae860a3b68bbd97426e2 100644 (file)
@@ -30,6 +30,13 @@ public class WebhookDeliveryDao implements Dao {
     return Optional.ofNullable(mapper(dbSession).selectByUuid(uuid));
   }
 
+  /**
+   * 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.
    */
index 3f80bcb13314ad1284c398e85edeed87d16a430d..af130a3d4d91592150cac7f31b57cb6d41394ce4 100644 (file)
@@ -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
index 8fd5b42bef83b29e9e172ba368328f7063516f5a..f14eb163d1e89ab8c28358b807d763a46a911b87 100644 (file)
@@ -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);
index c13ead5a155f3664f5173f7f4db8e7f290c013ea..0612c9712939dcc269deea9e075926274b9a5e00 100644 (file)
@@ -7,6 +7,7 @@
   <sql id="sqlLiteColumns">
     uuid,
     component_uuid as componentUuid,
+    webhook_uuid as webhookUuid,
     ce_task_uuid as ceTaskUuid,
     name,
     url,
     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 (file)
index 0000000..ba6dd64
--- /dev/null
@@ -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());
+  }
+
+}
index abe4af30f23d4d5d76d01a40a4eba3fe3efd611f..9c406e6eb99c1b15d39df47c9a5c284e40e9f0ca 100644 (file)
@@ -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 (file)
index 0000000..937a09a
--- /dev/null
@@ -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();
+  }
+}
index 70a599f9f6e69a529688be8cc2354bbcb1d84faa..6b5041ef512bf9340524a70ad4392f106fd09297 100644 (file)
@@ -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 (file)
index 0000000..27263b0
--- /dev/null
@@ -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");
index 76851e8fd00a963e7c3e619b1a48991363f7b44e..a5497710144a3be461e37637999a406be96d4f62 100644 (file)
@@ -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;
index 3a695549d629981cc8a6379589e51113dbbd57ad..8ac3b4c75a814df897f79298e02c2ffed2159f27 100644 (file)
@@ -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);
   }
index 49062373b360e460fbcfebb124a018e84d40db65..0ba9bb95c75604acda08603d41ba4bf55b0e0ab3 100644 (file)
@@ -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);
index 185bba7a2712d4b1580be0a00a2015e1d6e41e42..685d384a9f9b6dbcfc160e99e41b698f945cf427 100644 (file)
@@ -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 {
index 6a5e5270be4baa95cf4aa6eb00182f24462a7ed8..1e174e6ba5415366f834e5d15f7f0867789ccac8 100644 (file)
@@ -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);
index 5f63dc54209b1be111f7f78a4e7c9af07cc785ec..158fdd730023ffcb67ad9e039180013080071c62 100644 (file)
@@ -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)
index c73aee52cc94c98f4467cffb7f90274e8b9d52c7..64778c0dfa4d140747d3bc363ae003174132838d 100644 (file)
@@ -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);
index 14d91c6578275610cb57cd0061ac1afae169948c..e8b9c9c9ca8d21c15989a509602f79f74d7d46d3 100644 (file)
@@ -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();
@@ -103,6 +103,17 @@ public class WebhookDeliveriesActionTest {
     assertThat(response.getDeliveriesCount()).isEqualTo(0);
   }
 
+  @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()
@@ -145,6 +156,24 @@ public class WebhookDeliveriesActionTest {
     assertThat(response.getDeliveriesList()).extracting(Webhooks.Delivery::getId).containsOnly(dto1.getUuid(), dto2.getUuid());
   }
 
+  @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()
@@ -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();
+  }
 }