aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuillaume Jambet <guillaume.jambet@sonarsource.com>2018-02-14 15:41:26 +0100
committerGuillaume Jambet <guillaume.jambet@gmail.com>2018-03-01 15:21:05 +0100
commit3ae18356c3fcafeb7b5348c8916098156cd0a824 (patch)
treee0a8298543a9916ffefa39d6453a3cba381c7e61
parentbfb8b46ce0f4850775ccab4e2fa13ed83901c842 (diff)
downloadsonarqube-3ae18356c3fcafeb7b5348c8916098156cd0a824.tar.gz
sonarqube-3ae18356c3fcafeb7b5348c8916098156cd0a824.zip
SONAR-10347 Add search-by-webhook to webhook deliveries search ws.
-rw-r--r--server/sonar-db-core/src/main/resources/org/sonar/db/version/schema-h2.ddl1
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/webhook/WebhookDeliveryDao.java7
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/webhook/WebhookDeliveryLiteDto.java31
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/webhook/WebhookDeliveryMapper.java2
-rw-r--r--server/sonar-db-dao/src/main/resources/org/sonar/db/webhook/WebhookDeliveryMapper.xml10
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v71/AddWebhookKeyToWebhookDeliveriesTable.java46
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v71/DbVersion71.java1
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v71/AddWebhookKeyToWebhookDeliveriesTableTest.java55
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v71/DbVersion71Test.java2
-rw-r--r--server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v71/AddWebhookKeyToWebhookDeliveriesTableTest/webhook-deliveries.sql18
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/webhook/WebHooksImpl.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/webhook/Webhook.java8
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/webhook/WebhookDeliveryStorage.java1
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/webhook/ws/WebhookDeliveriesAction.java22
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookCallerImplTest.java18
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookDeliveryStorageTest.java3
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookTest.java10
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/webhook/ws/WebhookDeliveriesActionTest.java46
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();
+ }
}