@@ -20,11 +20,15 @@ | |||
package org.sonar.db.webhook; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.Optional; | |||
import org.apache.ibatis.session.RowBounds; | |||
import org.sonar.db.Dao; | |||
import org.sonar.db.DbSession; | |||
import static java.util.function.Function.identity; | |||
import static java.util.stream.Collectors.toMap; | |||
public class WebhookDeliveryDao implements Dao { | |||
public Optional<WebhookDeliveryDto> selectByUuid(DbSession dbSession, String uuid) { | |||
@@ -72,6 +76,12 @@ public class WebhookDeliveryDao implements Dao { | |||
mapper(dbSession).deleteComponentBeforeDate(componentUuid, beforeDate); | |||
} | |||
public Map<String, WebhookDeliveryLiteDto> selectLatestDeliveries(DbSession dbSession, List<WebhookDto> webhooks) { | |||
return webhooks.stream() | |||
.flatMap(webhook -> selectByWebhookUuid(dbSession, webhook.getUuid(),0,1).stream()) | |||
.collect(toMap(WebhookDeliveryLiteDto::getWebhookUuid, identity())); | |||
} | |||
private static WebhookDeliveryMapper mapper(DbSession dbSession) { | |||
return dbSession.getMapper(WebhookDeliveryMapper.class); | |||
} |
@@ -49,6 +49,7 @@ import org.sonar.db.source.FileSourceTester; | |||
import org.sonar.db.user.RootFlagAssertions; | |||
import org.sonar.db.user.UserDbTester; | |||
import org.sonar.db.webhook.WebhookDbTester; | |||
import org.sonar.db.webhook.WebhookDeliveryDbTester; | |||
import static com.google.common.base.Preconditions.checkState; | |||
import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; | |||
@@ -85,6 +86,7 @@ public class DbTester extends AbstractDbTester<TestDb> { | |||
private final FileSourceTester fileSourceTester; | |||
private final PluginDbTester pluginDbTester; | |||
private final WebhookDbTester webhookDbTester; | |||
private final WebhookDeliveryDbTester webhookDeliveryDbTester; | |||
public DbTester(System2 system2, @Nullable String schemaPath) { | |||
super(TestDb.create(schemaPath)); | |||
@@ -109,6 +111,7 @@ public class DbTester extends AbstractDbTester<TestDb> { | |||
this.fileSourceTester = new FileSourceTester(this); | |||
this.pluginDbTester = new PluginDbTester(this); | |||
this.webhookDbTester = new WebhookDbTester(this); | |||
this.webhookDeliveryDbTester = new WebhookDeliveryDbTester(this); | |||
} | |||
public static DbTester create() { | |||
@@ -255,6 +258,10 @@ public class DbTester extends AbstractDbTester<TestDb> { | |||
return webhookDbTester; | |||
} | |||
public WebhookDeliveryDbTester webhookDelivery() { | |||
return webhookDeliveryDbTester; | |||
} | |||
@Override | |||
protected void after() { | |||
if (session != null) { |
@@ -73,7 +73,7 @@ import static org.sonar.db.component.ComponentTesting.newDirectory; | |||
import static org.sonar.db.component.ComponentTesting.newFileDto; | |||
import static org.sonar.db.component.ComponentTesting.newModuleDto; | |||
import static org.sonar.db.component.ComponentTesting.newProjectCopy; | |||
import static org.sonar.db.webhook.WebhookDbTesting.newWebhookDeliveryDto; | |||
import static org.sonar.db.webhook.WebhookDbTesting.newDto; | |||
import static org.sonar.db.webhook.WebhookDbTesting.selectAllDeliveryUuids; | |||
public class PurgeDaoTest { | |||
@@ -524,8 +524,8 @@ public class PurgeDaoTest { | |||
@Test | |||
public void deleteProject_deletes_webhook_deliveries() { | |||
ComponentDto project = dbTester.components().insertPublicProject(); | |||
dbClient.webhookDeliveryDao().insert(dbSession, newWebhookDeliveryDto().setComponentUuid(project.uuid()).setUuid("D1")); | |||
dbClient.webhookDeliveryDao().insert(dbSession, newWebhookDeliveryDto().setComponentUuid("P2").setUuid("D2")); | |||
dbClient.webhookDeliveryDao().insert(dbSession, newDto().setComponentUuid(project.uuid()).setUuid("D1")); | |||
dbClient.webhookDeliveryDao().insert(dbSession, newDto().setComponentUuid("P2").setUuid("D2")); | |||
underTest.deleteProject(dbSession, project.uuid()); | |||
@@ -35,7 +35,19 @@ public class WebhookDbTesting { | |||
// only statics | |||
} | |||
public static WebhookDeliveryDto newWebhookDeliveryDto() { | |||
/** | |||
* Build a {@link WebhookDeliveryDto} with all mandatory fields. | |||
* Optional fields are kept null. | |||
*/ | |||
public static WebhookDeliveryDto newDto(String uuid, String webhookUuid, String componentUuid, String ceTaskUuid) { | |||
return newDto() | |||
.setUuid(uuid) | |||
.setWebhookUuid(webhookUuid) | |||
.setComponentUuid(componentUuid) | |||
.setCeTaskUuid(ceTaskUuid); | |||
} | |||
public static WebhookDeliveryDto newDto() { | |||
return new WebhookDeliveryDto() | |||
.setUuid(randomAlphanumeric(40)) | |||
.setComponentUuid(randomAlphanumeric(40)) |
@@ -30,8 +30,9 @@ import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.DbTester; | |||
import static com.google.common.collect.ImmutableList.of; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.sonar.db.webhook.WebhookDbTesting.newWebhookDeliveryDto; | |||
import static org.sonar.db.webhook.WebhookTesting.newProjectWebhook; | |||
public class WebhookDeliveryDaoTest { | |||
@@ -57,7 +58,7 @@ public class WebhookDeliveryDaoTest { | |||
@Test | |||
public void selectOrderedByComponentUuid_returns_empty_if_no_records() { | |||
underTest.insert(dbSession, newDto("D1", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_1")); | |||
underTest.insert(dbSession, WebhookDbTesting.newDto("D1", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_1")); | |||
List<WebhookDeliveryLiteDto> deliveries = underTest.selectOrderedByComponentUuid(dbSession, "ANOTHER_COMPONENT", 0, 10); | |||
@@ -66,9 +67,9 @@ public class WebhookDeliveryDaoTest { | |||
@Test | |||
public void selectOrderedByComponentUuid_returns_records_ordered_by_date() { | |||
WebhookDeliveryDto dto1 = newDto("D1", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_1").setCreatedAt(BEFORE); | |||
WebhookDeliveryDto dto2 = newDto("D2", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_1").setCreatedAt(NOW); | |||
WebhookDeliveryDto dto3 = newDto("D3", "WEBHOOK_UUID_1", "COMPONENT_2", "TASK_1").setCreatedAt(NOW); | |||
WebhookDeliveryDto dto1 = WebhookDbTesting.newDto("D1", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_1").setCreatedAt(BEFORE); | |||
WebhookDeliveryDto dto2 = WebhookDbTesting.newDto("D2", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_1").setCreatedAt(NOW); | |||
WebhookDeliveryDto dto3 = WebhookDbTesting.newDto("D3", "WEBHOOK_UUID_1", "COMPONENT_2", "TASK_1").setCreatedAt(NOW); | |||
underTest.insert(dbSession, dto3); | |||
underTest.insert(dbSession, dto2); | |||
underTest.insert(dbSession, dto1); | |||
@@ -80,7 +81,7 @@ public class WebhookDeliveryDaoTest { | |||
@Test | |||
public void selectOrderedByCeTaskUuid_returns_empty_if_no_records() { | |||
underTest.insert(dbSession, newDto("D1", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_1")); | |||
underTest.insert(dbSession, WebhookDbTesting.newDto("D1", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_1")); | |||
List<WebhookDeliveryLiteDto> deliveries = underTest.selectOrderedByCeTaskUuid(dbSession, "ANOTHER_TASK", 0, 10); | |||
@@ -89,9 +90,9 @@ public class WebhookDeliveryDaoTest { | |||
@Test | |||
public void selectOrderedByCeTaskUuid_returns_records_ordered_by_date() { | |||
WebhookDeliveryDto dto1 = newDto("D1", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_1").setCreatedAt(BEFORE); | |||
WebhookDeliveryDto dto2 = newDto("D2", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_1").setCreatedAt(NOW); | |||
WebhookDeliveryDto dto3 = newDto("D3", "WEBHOOK_UUID_1", "COMPONENT_2", "TASK_2").setCreatedAt(NOW); | |||
WebhookDeliveryDto dto1 = WebhookDbTesting.newDto("D1", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_1").setCreatedAt(BEFORE); | |||
WebhookDeliveryDto dto2 = WebhookDbTesting.newDto("D2", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_1").setCreatedAt(NOW); | |||
WebhookDeliveryDto dto3 = WebhookDbTesting.newDto("D3", "WEBHOOK_UUID_1", "COMPONENT_2", "TASK_2").setCreatedAt(NOW); | |||
underTest.insert(dbSession, dto3); | |||
underTest.insert(dbSession, dto2); | |||
underTest.insert(dbSession, dto1); | |||
@@ -104,7 +105,7 @@ public class WebhookDeliveryDaoTest { | |||
@Test | |||
public void selectByWebhookUuid_returns_empty_if_no_records() { | |||
underTest.insert(dbSession, newDto("D1", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_1")); | |||
underTest.insert(dbSession, WebhookDbTesting.newDto("D1", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_1")); | |||
List<WebhookDeliveryLiteDto> deliveries = underTest.selectByWebhookUuid(dbSession, "a-webhook-uuid", 0, 10); | |||
@@ -114,9 +115,9 @@ public class WebhookDeliveryDaoTest { | |||
@Test | |||
public void selectByWebhookUuid_returns_records_ordered_by_date() { | |||
WebhookDto webhookDto = dbWebhooks.insert(WebhookTesting.newProjectWebhook("COMPONENT_1")); | |||
WebhookDeliveryDto dto1 = newDto("D1", webhookDto.getUuid(), "COMPONENT_1", "TASK_1").setCreatedAt(BEFORE); | |||
WebhookDeliveryDto dto2 = newDto("D2", webhookDto.getUuid(), "COMPONENT_1", "TASK_2").setCreatedAt(NOW); | |||
WebhookDeliveryDto dto3 = newDto("D3", "fake-webhook-uuid", "COMPONENT_2", "TASK_1").setCreatedAt(NOW); | |||
WebhookDeliveryDto dto1 = WebhookDbTesting.newDto("D1", webhookDto.getUuid(), "COMPONENT_1", "TASK_1").setCreatedAt(BEFORE); | |||
WebhookDeliveryDto dto2 = WebhookDbTesting.newDto("D2", webhookDto.getUuid(), "COMPONENT_1", "TASK_2").setCreatedAt(NOW); | |||
WebhookDeliveryDto dto3 = WebhookDbTesting.newDto("D3", "fake-webhook-uuid", "COMPONENT_2", "TASK_1").setCreatedAt(NOW); | |||
underTest.insert(dbSession, dto3); | |||
underTest.insert(dbSession, dto2); | |||
underTest.insert(dbSession, dto1); | |||
@@ -129,25 +130,40 @@ public class WebhookDeliveryDaoTest { | |||
@Test | |||
public void selectByWebhookUuid_returns_records_according_to_pagination() { | |||
WebhookDto webhookDto = dbWebhooks.insert(WebhookTesting.newProjectWebhook("COMPONENT_1")); | |||
WebhookDeliveryDto dto1 = newDto("D1", webhookDto.getUuid(), "COMPONENT_1", "TASK_1").setCreatedAt(BEFORE); | |||
underTest.insert(dbSession, dto1); | |||
WebhookDeliveryDto dto2 = newDto("D2", webhookDto.getUuid(), "COMPONENT_1", "TASK_2").setCreatedAt(NOW); | |||
underTest.insert(dbSession, dto2); | |||
underTest.insert(dbSession, newDto("D3", webhookDto.getUuid(), "COMPONENT_1", "TASK_2").setCreatedAt(NOW)); | |||
underTest.insert(dbSession, newDto("D4", webhookDto.getUuid(), "COMPONENT_1", "TASK_2").setCreatedAt(NOW)); | |||
underTest.insert(dbSession, newDto("D5", webhookDto.getUuid(), "COMPONENT_1", "TASK_2").setCreatedAt(NOW)); | |||
underTest.insert(dbSession, newDto("D6", webhookDto.getUuid(), "COMPONENT_1", "TASK_2").setCreatedAt(NOW)); | |||
underTest.insert(dbSession, WebhookDbTesting.newDto("D1", webhookDto.getUuid(), "COMPONENT_1", "TASK_2").setCreatedAt(NOW - 5_000L)); | |||
underTest.insert(dbSession, WebhookDbTesting.newDto("D2", webhookDto.getUuid(), "COMPONENT_1", "TASK_2").setCreatedAt(NOW - 4_000L)); | |||
underTest.insert(dbSession, WebhookDbTesting.newDto("D3", webhookDto.getUuid(), "COMPONENT_1", "TASK_2").setCreatedAt(NOW - 3_000L)); | |||
underTest.insert(dbSession, WebhookDbTesting.newDto("D4", webhookDto.getUuid(), "COMPONENT_1", "TASK_2").setCreatedAt(NOW - 2_000L)); | |||
underTest.insert(dbSession, WebhookDbTesting.newDto("D5", webhookDto.getUuid(), "COMPONENT_1", "TASK_2").setCreatedAt(NOW - 1_000L)); | |||
underTest.insert(dbSession, WebhookDbTesting.newDto("D6", webhookDto.getUuid(), "COMPONENT_1", "TASK_2").setCreatedAt(NOW)); | |||
List<WebhookDeliveryLiteDto> deliveries = underTest.selectByWebhookUuid(dbSession, webhookDto.getUuid(), 1, 3); | |||
List<WebhookDeliveryLiteDto> deliveries = underTest.selectByWebhookUuid(dbSession, webhookDto.getUuid(), 2, 2); | |||
assertThat(deliveries).extracting(WebhookDeliveryLiteDto::getUuid).containsExactlyInAnyOrder("D3", "D4", "D5"); | |||
assertThat(deliveries).extracting(WebhookDeliveryLiteDto::getUuid).containsExactly("D4", "D3"); | |||
} | |||
@Test | |||
public void selectLatestDelivery_of_a_webhook() { | |||
WebhookDto webhook1 = dbWebhooks.insert(newProjectWebhook("COMPONENT_1")); | |||
underTest.insert(dbSession, WebhookDbTesting.newDto("WH1-DELIVERY-1-UUID", webhook1.getUuid(), "COMPONENT_1", "TASK_1").setCreatedAt(BEFORE)); | |||
underTest.insert(dbSession, WebhookDbTesting.newDto("WH1-DELIVERY-2-UUID", webhook1.getUuid(), "COMPONENT_1", "TASK_2").setCreatedAt(NOW)); | |||
WebhookDto webhook2 = dbWebhooks.insert(newProjectWebhook("COMPONENT_1")); | |||
underTest.insert(dbSession, WebhookDbTesting.newDto("WH2-DELIVERY-1-UUID", webhook2.getUuid(), "COMPONENT_1", "TASK_1").setCreatedAt(BEFORE)); | |||
underTest.insert(dbSession, WebhookDbTesting.newDto("WH2-DELIVERY-2-UUID", webhook2.getUuid(), "COMPONENT_1", "TASK_2").setCreatedAt(NOW)); | |||
Map<String, WebhookDeliveryLiteDto> map = underTest.selectLatestDeliveries(dbSession, of(webhook1, webhook2)); | |||
assertThat(map).containsKeys(webhook1.getUuid()); | |||
assertThat(map.get(webhook1.getUuid())).extracting(WebhookDeliveryLiteDto::getUuid).contains("WH1-DELIVERY-2-UUID"); | |||
assertThat(map).containsKeys(webhook2.getUuid()); | |||
assertThat(map.get(webhook2.getUuid())).extracting(WebhookDeliveryLiteDto::getUuid).contains("WH2-DELIVERY-2-UUID"); | |||
} | |||
@Test | |||
public void insert_row_with_only_mandatory_columns() { | |||
WebhookDeliveryDto dto = newDto("DELIVERY_1", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_1") | |||
WebhookDeliveryDto dto = WebhookDbTesting.newDto("DELIVERY_1", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_1") | |||
.setHttpStatus(null) | |||
.setDurationMs(null) | |||
.setErrorStacktrace(null); | |||
@@ -165,7 +181,7 @@ public class WebhookDeliveryDaoTest { | |||
@Test | |||
public void insert_row_with_all_columns() { | |||
WebhookDeliveryDto dto = newDto("DELIVERY_1", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_1"); | |||
WebhookDeliveryDto dto = WebhookDbTesting.newDto("DELIVERY_1", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_1"); | |||
underTest.insert(dbSession, dto); | |||
@@ -179,9 +195,9 @@ public class WebhookDeliveryDaoTest { | |||
@Test | |||
public void deleteComponentBeforeDate_deletes_rows_before_date() { | |||
underTest.insert(dbSession, newDto("DELIVERY_1", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_1").setCreatedAt(1_000_000L)); | |||
underTest.insert(dbSession, newDto("DELIVERY_2", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_2").setCreatedAt(2_000_000L)); | |||
underTest.insert(dbSession, newDto("DELIVERY_3", "WEBHOOK_UUID_1", "COMPONENT_2", "TASK_3").setCreatedAt(1_000_000L)); | |||
underTest.insert(dbSession, WebhookDbTesting.newDto("DELIVERY_1", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_1").setCreatedAt(1_000_000L)); | |||
underTest.insert(dbSession, WebhookDbTesting.newDto("DELIVERY_2", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_2").setCreatedAt(2_000_000L)); | |||
underTest.insert(dbSession, WebhookDbTesting.newDto("DELIVERY_3", "WEBHOOK_UUID_1", "COMPONENT_2", "TASK_3").setCreatedAt(1_000_000L)); | |||
// should delete the old delivery on COMPONENT_1 and keep the one of COMPONENT_2 | |||
underTest.deleteComponentBeforeDate(dbSession, "COMPONENT_1", 1_500_000L); | |||
@@ -199,7 +215,7 @@ public class WebhookDeliveryDaoTest { | |||
@Test | |||
public void deleteComponentBeforeDate_does_nothing_on_invalid_uuid() { | |||
underTest.insert(dbSession, newDto("DELIVERY_1", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_1").setCreatedAt(1_000_000L)); | |||
underTest.insert(dbSession, WebhookDbTesting.newDto("DELIVERY_1", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_1").setCreatedAt(1_000_000L)); | |||
underTest.deleteComponentBeforeDate(dbSession, "COMPONENT_2", 1_500_000L); | |||
@@ -217,18 +233,6 @@ public class WebhookDeliveryDaoTest { | |||
assertThat(actual.getCreatedAt()).isEqualTo(expected.getCreatedAt()); | |||
} | |||
/** | |||
* Build a {@link WebhookDeliveryDto} with all mandatory fields. | |||
* Optional fields are kept null. | |||
*/ | |||
private static WebhookDeliveryDto newDto(String uuid, String webhookUuid, String componentUuid, String ceTaskUuid) { | |||
return newWebhookDeliveryDto() | |||
.setUuid(uuid) | |||
.setWebhookUuid(webhookUuid) | |||
.setComponentUuid(componentUuid) | |||
.setCeTaskUuid(ceTaskUuid); | |||
} | |||
private WebhookDeliveryDto selectByUuid(String uuid) { | |||
Optional<WebhookDeliveryDto> dto = underTest.selectByUuid(dbSession, uuid); | |||
assertThat(dto).isPresent(); |
@@ -0,0 +1,40 @@ | |||
/* | |||
* 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.db.webhook; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.DbTester; | |||
public class WebhookDeliveryDbTester { | |||
private final DbTester dbTester; | |||
public WebhookDeliveryDbTester(DbTester dbTester) { | |||
this.dbTester = dbTester; | |||
} | |||
public WebhookDeliveryLiteDto insert(WebhookDeliveryDto dto) { | |||
DbSession dbSession = dbTester.getSession(); | |||
dbTester.getDbClient().webhookDeliveryDao().insert(dbSession, dto); | |||
dbSession.commit(); | |||
return dto; | |||
} | |||
} |
@@ -19,10 +19,11 @@ | |||
*/ | |||
package org.sonar.db.webhook; | |||
import java.util.Calendar; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.organization.OrganizationDto; | |||
import java.util.Calendar; | |||
import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; | |||
public class WebhookTesting { | |||
@@ -46,6 +47,12 @@ public class WebhookTesting { | |||
.setOrganizationUuid(organizationDto.getUuid()); | |||
} | |||
public static WebhookDto newOrganizationWebhook(String name, String organizationUuid) { | |||
return getWebhookDto() | |||
.setName(name) | |||
.setOrganizationUuid(organizationUuid); | |||
} | |||
private static WebhookDto getWebhookDto() { | |||
return new WebhookDto() | |||
.setUuid(randomAlphanumeric(40)) |
@@ -25,6 +25,7 @@ import java.util.Arrays; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.function.Function; | |||
import javax.annotation.CheckForNull; | |||
import javax.annotation.Nullable; | |||
import org.sonar.api.utils.log.Logger; | |||
import org.sonar.api.utils.log.Loggers; | |||
@@ -33,6 +34,7 @@ import org.sonar.db.Database; | |||
import org.sonar.server.platform.db.migration.step.DataChange; | |||
import org.sonar.server.platform.db.migration.version.v63.DefaultOrganizationUuidProvider; | |||
import static com.google.common.base.Preconditions.checkNotNull; | |||
import static java.util.stream.Collectors.toList; | |||
import static java.util.stream.Collectors.toMap; | |||
@@ -124,11 +126,13 @@ public class MigrateWebhooksToWebhooksTable extends DataChange { | |||
for (String value : values) { | |||
PropertyRow name = properties.get("sonar.webhooks.project." + value + ".name"); | |||
PropertyRow url = properties.get("sonar.webhooks.project." + value + ".url"); | |||
webhooks.add(new Webhook(name, url, null, projectUuidOf(context, name))); | |||
String projectUuid = checkNotNull(projectUuidOf(context, name), "Project was not found for property : sonar.webhooks.project.%s", value); | |||
webhooks.add(new Webhook(name, url, null, projectUuid)); | |||
} | |||
return webhooks; | |||
} | |||
@CheckForNull | |||
private static String projectUuidOf(Context context, PropertyRow row) throws SQLException { | |||
return context | |||
.prepareSelect("select uuid from projects where id = ?") |
@@ -65,12 +65,14 @@ public class WebhookCallerImpl implements WebhookCaller { | |||
Request request = buildHttpRequest(webhook, payload); | |||
try (Response response = execute(request)) { | |||
builder.setHttpStatus(response.code()); | |||
builder.setDurationInMs((int) (system.now() - startedAt)); | |||
} | |||
} catch (Exception e) { | |||
builder.setError(e); | |||
} | |||
return builder.build(); | |||
return builder | |||
.setDurationInMs((int) (system.now() - startedAt)) | |||
.build(); | |||
} | |||
private static Request buildHttpRequest(Webhook webhook, WebhookPayload payload) { |
@@ -21,6 +21,7 @@ package org.sonar.server.webhook.ws; | |||
import com.google.common.io.Resources; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.Optional; | |||
import javax.annotation.Nullable; | |||
import org.sonar.api.server.ws.Request; | |||
@@ -30,13 +31,17 @@ import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.organization.OrganizationDto; | |||
import org.sonar.db.webhook.WebhookDeliveryLiteDto; | |||
import org.sonar.db.webhook.WebhookDto; | |||
import org.sonar.server.organization.DefaultOrganizationProvider; | |||
import org.sonar.server.user.UserSession; | |||
import org.sonarqube.ws.Webhooks.ListWsResponse.Builder; | |||
import org.sonarqube.ws.Webhooks; | |||
import org.sonarqube.ws.Webhooks.ListResponse; | |||
import org.sonarqube.ws.Webhooks.ListResponseElement; | |||
import static java.util.Optional.ofNullable; | |||
import static org.apache.commons.lang.StringUtils.isNotBlank; | |||
import static org.sonar.api.utils.DateUtils.formatDateTime; | |||
import static org.sonar.server.webhook.ws.WebhooksWsParameters.LIST_ACTION; | |||
import static org.sonar.server.webhook.ws.WebhooksWsParameters.ORGANIZATION_KEY_PARAM; | |||
import static org.sonar.server.webhook.ws.WebhooksWsParameters.PROJECT_KEY_PARAM; | |||
@@ -45,7 +50,6 @@ import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001; | |||
import static org.sonar.server.ws.WsUtils.checkFoundWithOptional; | |||
import static org.sonar.server.ws.WsUtils.checkStateWithOptional; | |||
import static org.sonar.server.ws.WsUtils.writeProtobuf; | |||
import static org.sonarqube.ws.Webhooks.ListWsResponse.newBuilder; | |||
public class ListAction implements WebhooksWsAction { | |||
@@ -92,55 +96,77 @@ public class ListAction implements WebhooksWsAction { | |||
userSession.checkLoggedIn(); | |||
writeResponse(request, response, doHandle(organizationKey, projectKey)); | |||
try (DbSession dbSession = dbClient.openSession(true)) { | |||
List<WebhookDto> webhookDtos = doHandle(dbSession, organizationKey, projectKey); | |||
Map<String, WebhookDeliveryLiteDto> lastDeliveries = loadLastDeliveriesOf(dbSession, webhookDtos); | |||
writeResponse(request, response, webhookDtos, lastDeliveries); | |||
} | |||
} | |||
private List<WebhookDto> doHandle(@Nullable String organizationKey, @Nullable String projectKey) { | |||
try (DbSession dbSession = dbClient.openSession(true)) { | |||
private Map<String, WebhookDeliveryLiteDto> loadLastDeliveriesOf(DbSession dbSession, List<WebhookDto> webhookDtos) { | |||
return dbClient.webhookDeliveryDao().selectLatestDeliveries(dbSession, webhookDtos); | |||
} | |||
OrganizationDto organizationDto; | |||
if (isNotBlank(organizationKey)) { | |||
Optional<OrganizationDto> dtoOptional = dbClient.organizationDao().selectByKey(dbSession, organizationKey); | |||
organizationDto = checkFoundWithOptional(dtoOptional, "No organization with key '%s'", organizationKey); | |||
} else { | |||
organizationDto = defaultOrganizationDto(dbSession); | |||
} | |||
private List<WebhookDto> doHandle(DbSession dbSession, @Nullable String organizationKey, @Nullable String projectKey) { | |||
if (isNotBlank(projectKey)) { | |||
OrganizationDto organizationDto; | |||
if (isNotBlank(organizationKey)) { | |||
Optional<OrganizationDto> dtoOptional = dbClient.organizationDao().selectByKey(dbSession, organizationKey); | |||
organizationDto = checkFoundWithOptional(dtoOptional, "No organization with key '%s'", organizationKey); | |||
} else { | |||
organizationDto = defaultOrganizationDto(dbSession); | |||
} | |||
Optional<ComponentDto> optional = ofNullable(dbClient.componentDao().selectByKey(dbSession, projectKey).orNull()); | |||
ComponentDto componentDto = checkFoundWithOptional(optional, "project %s does not exist", projectKey); | |||
webhookSupport.checkPermission(componentDto); | |||
webhookSupport.checkThatProjectBelongsToOrganization(componentDto, organizationDto, "Project '%s' does not belong to organisation '%s'", projectKey, organizationKey); | |||
webhookSupport.checkPermission(componentDto); | |||
return dbClient.webhookDao().selectByProject(dbSession, componentDto); | |||
if (isNotBlank(projectKey)) { | |||
} else { | |||
Optional<ComponentDto> optional = ofNullable(dbClient.componentDao().selectByKey(dbSession, projectKey).orNull()); | |||
ComponentDto componentDto = checkFoundWithOptional(optional, "project %s does not exist", projectKey); | |||
webhookSupport.checkPermission(componentDto); | |||
webhookSupport.checkThatProjectBelongsToOrganization(componentDto, organizationDto, "Project '%s' does not belong to organisation '%s'", projectKey, organizationKey); | |||
webhookSupport.checkPermission(componentDto); | |||
return dbClient.webhookDao().selectByProject(dbSession, componentDto); | |||
webhookSupport.checkPermission(organizationDto); | |||
return dbClient.webhookDao().selectByOrganization(dbSession, organizationDto); | |||
} else { | |||
} | |||
webhookSupport.checkPermission(organizationDto); | |||
return dbClient.webhookDao().selectByOrganization(dbSession, organizationDto); | |||
} | |||
} | |||
private static void writeResponse(Request request, Response response, List<WebhookDto> webhookDtos) { | |||
Builder responseBuilder = newBuilder(); | |||
} | |||
private static void writeResponse(Request request, Response response, List<WebhookDto> webhookDtos, Map<String, WebhookDeliveryLiteDto> lastDeliveries) { | |||
ListResponse.Builder responseBuilder = ListResponse.newBuilder(); | |||
webhookDtos | |||
.stream() | |||
.forEach(webhook -> responseBuilder.addWebhooksBuilder() | |||
.setKey(webhook.getUuid()) | |||
.setName(webhook.getName()) | |||
.setUrl(webhook.getUrl())); | |||
.forEach(webhook -> { | |||
ListResponseElement.Builder responseElementBuilder = responseBuilder.addWebhooksBuilder(); | |||
responseElementBuilder | |||
.setKey(webhook.getUuid()) | |||
.setName(webhook.getName()) | |||
.setUrl(webhook.getUrl()); | |||
addLastDelivery(responseElementBuilder, webhook, lastDeliveries); | |||
}); | |||
writeProtobuf(responseBuilder.build(), request, response); | |||
} | |||
private static void addLastDelivery(ListResponseElement.Builder responseElementBuilder, WebhookDto webhook, Map<String, WebhookDeliveryLiteDto> lastDeliveries) { | |||
if (lastDeliveries.containsKey(webhook.getUuid())) { | |||
WebhookDeliveryLiteDto delivery = lastDeliveries.get(webhook.getUuid()); | |||
Webhooks.LatestDelivery.Builder builder = responseElementBuilder.getLatestDeliveryBuilder() | |||
.setId(delivery.getUuid()) | |||
.setAt(formatDateTime(delivery.getCreatedAt())) | |||
.setSuccess(delivery.isSuccess()); | |||
if (delivery.getHttpStatus() != null) { | |||
builder.setHttpStatus(delivery.getHttpStatus()); | |||
} | |||
if (delivery.getDurationMs() != null) { | |||
builder.setDurationMs(delivery.getDurationMs()); | |||
} | |||
builder.build(); | |||
} | |||
} | |||
private OrganizationDto defaultOrganizationDto(DbSession dbSession) { | |||
String uuid = defaultOrganizationProvider.get().getUuid(); | |||
Optional<OrganizationDto> organizationDto = dbClient.organizationDao().selectByUuid(dbSession, uuid); |
@@ -42,6 +42,7 @@ import static java.util.Objects.requireNonNull; | |||
import static org.apache.commons.lang.StringUtils.isNotBlank; | |||
import static org.sonar.api.server.ws.WebService.Param.PAGE; | |||
import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE; | |||
import static org.sonar.api.utils.Paging.offset; | |||
import static org.sonar.core.util.Uuids.UUID_EXAMPLE_02; | |||
import static org.sonar.server.es.SearchOptions.MAX_LIMIT; | |||
import static org.sonar.server.webhook.ws.WebhookWsSupport.copyDtoToProtobuf; | |||
@@ -115,17 +116,17 @@ public class WebhookDeliveriesAction implements WebhooksWsAction { | |||
int totalElements; | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
if (isNotBlank(webhookUuid)) { | |||
deliveries = dbClient.webhookDeliveryDao().selectByWebhookUuid(dbSession, webhookUuid, page - 1, pageSize); | |||
component = getComponentDto(dbSession, deliveries); | |||
totalElements = dbClient.webhookDeliveryDao().countDeliveriesByWebhookUuid(dbSession, webhookUuid); | |||
deliveries = dbClient.webhookDeliveryDao().selectByWebhookUuid(dbSession, webhookUuid, offset(page, pageSize), pageSize); | |||
component = getComponentDto(dbSession, deliveries); | |||
} else if (componentKey != null) { | |||
component = componentFinder.getByKey(dbSession, componentKey); | |||
deliveries = dbClient.webhookDeliveryDao().selectOrderedByComponentUuid(dbSession, component.uuid(), page - 1, pageSize); | |||
totalElements = dbClient.webhookDeliveryDao().countDeliveriesByComponentUuid(dbSession, component.uuid()); | |||
deliveries = dbClient.webhookDeliveryDao().selectOrderedByComponentUuid(dbSession, component.uuid(), offset(page, pageSize), pageSize); | |||
} else { | |||
deliveries = dbClient.webhookDeliveryDao().selectOrderedByCeTaskUuid(dbSession, ceTaskId, page - 1, pageSize); | |||
component = getComponentDto(dbSession, deliveries); | |||
totalElements = dbClient.webhookDeliveryDao().countDeliveriesByCeTaskUuid(dbSession, ceTaskId); | |||
deliveries = dbClient.webhookDeliveryDao().selectOrderedByCeTaskUuid(dbSession, ceTaskId, offset(page, pageSize), pageSize); | |||
component = getComponentDto(dbSession, deliveries); | |||
} | |||
} | |||
return new Data(component, deliveries).withPagingInfo(page, pageSize, totalElements); |
@@ -1,4 +1,9 @@ | |||
{ | |||
"paging": { | |||
"pageIndex": 1, | |||
"pageSize": 10, | |||
"total": 1 | |||
}, | |||
"deliveries": [ | |||
{ | |||
"id": "d1", | |||
@@ -12,4 +17,4 @@ | |||
"durationMs": 10 | |||
} | |||
] | |||
} | |||
} |
@@ -1,20 +1,14 @@ | |||
{ | |||
"paging": { | |||
"pageIndex": 1, | |||
"pageSize": 10, | |||
"total": 1 | |||
}, | |||
"deliveries": [ | |||
{ | |||
"id": "d1", | |||
"componentKey": "my-project", | |||
"ceTaskId": "task-1", | |||
"name": "Jenkins", | |||
"url": "http://jenkins", | |||
"at": "2017-07-14T04:40:00+0200", | |||
"success": true, | |||
"httpStatus": 200, | |||
"durationMs": 10 | |||
} | |||
] | |||
} | |||
"delivery": { | |||
"id": "d1", | |||
"componentKey": "my-project", | |||
"ceTaskId": "task-1", | |||
"name": "Jenkins", | |||
"url": "http://jenkins", | |||
"at": "2017-07-14T04:40:00+0200", | |||
"success": true, | |||
"httpStatus": 200, | |||
"durationMs": 10, | |||
"payload": "{\"status\"=\"SUCCESS\"}" | |||
} | |||
} |
@@ -90,7 +90,7 @@ public class WebhookCallerImplTest { | |||
WebhookDelivery delivery = newSender().call(webhook, PAYLOAD); | |||
assertThat(delivery.getHttpStatus()).isEmpty(); | |||
assertThat(delivery.getDurationInMs()).isEmpty(); | |||
assertThat(delivery.getDurationInMs().get()).isGreaterThanOrEqualTo(0); | |||
// message can be "Connection refused" or "connect timed out" | |||
assertThat(delivery.getErrorMessage().get()).matches("(.*Connection refused.*)|(.*connect timed out.*)"); | |||
assertThat(delivery.getAt()).isEqualTo(NOW); | |||
@@ -105,7 +105,7 @@ public class WebhookCallerImplTest { | |||
WebhookDelivery delivery = newSender().call(webhook, PAYLOAD); | |||
assertThat(delivery.getHttpStatus()).isEmpty(); | |||
assertThat(delivery.getDurationInMs()).isEmpty(); | |||
assertThat(delivery.getDurationInMs().get()).isGreaterThanOrEqualTo(0); | |||
assertThat(delivery.getError().get()).isInstanceOf(IllegalArgumentException.class); | |||
assertThat(delivery.getErrorMessage().get()).isEqualTo("Webhook URL is not valid: this_is_not_an_url"); | |||
assertThat(delivery.getAt()).isEqualTo(NOW); |
@@ -28,12 +28,13 @@ import org.sonar.core.util.UuidFactory; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.webhook.WebhookDbTesting; | |||
import org.sonar.db.webhook.WebhookDeliveryDto; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
import static org.sonar.db.webhook.WebhookDbTesting.newWebhookDeliveryDto; | |||
import static org.sonar.db.webhook.WebhookDbTesting.newDto; | |||
import static org.sonar.db.webhook.WebhookDbTesting.selectAllDeliveryUuids; | |||
public class WebhookDeliveryStorageTest { | |||
@@ -111,7 +112,7 @@ public class WebhookDeliveryStorageTest { | |||
} | |||
private static WebhookDeliveryDto newDto(String uuid, String componentUuid, long at) { | |||
return newWebhookDeliveryDto() | |||
return WebhookDbTesting.newDto() | |||
.setUuid(uuid) | |||
.setComponentUuid(componentUuid) | |||
.setCreatedAt(at); |
@@ -19,6 +19,7 @@ | |||
*/ | |||
package org.sonar.server.webhook.ws; | |||
import java.util.List; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
@@ -31,6 +32,7 @@ import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.organization.OrganizationDbTester; | |||
import org.sonar.db.organization.OrganizationDto; | |||
import org.sonar.db.webhook.WebhookDbTester; | |||
import org.sonar.db.webhook.WebhookDeliveryDbTester; | |||
import org.sonar.db.webhook.WebhookDto; | |||
import org.sonar.server.exceptions.ForbiddenException; | |||
import org.sonar.server.exceptions.NotFoundException; | |||
@@ -38,8 +40,8 @@ import org.sonar.server.exceptions.UnauthorizedException; | |||
import org.sonar.server.organization.DefaultOrganizationProvider; | |||
import org.sonar.server.tester.UserSessionRule; | |||
import org.sonar.server.ws.WsActionTester; | |||
import org.sonarqube.ws.Webhooks.ListWsResponse; | |||
import org.sonarqube.ws.Webhooks.ListWsResponse.List; | |||
import org.sonarqube.ws.Webhooks; | |||
import org.sonarqube.ws.Webhooks.ListResponse; | |||
import static java.lang.String.format; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
@@ -48,6 +50,8 @@ import static org.junit.rules.ExpectedException.none; | |||
import static org.sonar.api.web.UserRole.ADMIN; | |||
import static org.sonar.db.DbTester.create; | |||
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER; | |||
import static org.sonar.db.webhook.WebhookDbTesting.newDto; | |||
import static org.sonar.db.webhook.WebhookTesting.newOrganizationWebhook; | |||
import static org.sonar.server.organization.TestDefaultOrganizationProvider.from; | |||
import static org.sonar.server.tester.UserSessionRule.standalone; | |||
import static org.sonar.server.webhook.ws.WebhooksWsParameters.ORGANIZATION_KEY_PARAM; | |||
@@ -55,199 +59,252 @@ import static org.sonar.server.webhook.ws.WebhooksWsParameters.PROJECT_KEY_PARAM | |||
public class ListActionTest { | |||
@Rule | |||
public ExpectedException expectedException = none(); | |||
private static final long NOW = 1_500_000_000L; | |||
private static final long BEFORE = NOW - 1_000L; | |||
@Rule | |||
public UserSessionRule userSession = standalone(); | |||
@Rule | |||
public ExpectedException expectedException = none(); | |||
@Rule | |||
public DbTester db = create(); | |||
@Rule | |||
public UserSessionRule userSession = standalone(); | |||
private DbClient dbClient = db.getDbClient(); | |||
private DefaultOrganizationProvider defaultOrganizationProvider = from(db); | |||
private WebhookSupport webhookSupport = new WebhookSupport(userSession); | |||
private ListAction underTest = new ListAction(dbClient, userSession, defaultOrganizationProvider, webhookSupport); | |||
@Rule | |||
public DbTester db = create(); | |||
private ComponentDbTester componentDbTester = db.components(); | |||
private WebhookDbTester webhookDbTester = db.webhooks(); | |||
private OrganizationDbTester organizationDbTester = db.organizations(); | |||
private WsActionTester wsActionTester = new WsActionTester(underTest); | |||
private DbClient dbClient = db.getDbClient(); | |||
private DefaultOrganizationProvider defaultOrganizationProvider = from(db); | |||
private WebhookSupport webhookSupport = new WebhookSupport(userSession); | |||
private ListAction underTest = new ListAction(dbClient, userSession, defaultOrganizationProvider, webhookSupport); | |||
@Test | |||
public void definition() { | |||
private ComponentDbTester componentDbTester = db.components(); | |||
private WebhookDbTester webhookDbTester = db.webhooks(); | |||
private WebhookDeliveryDbTester webhookDeliveryDbTester = db.webhookDelivery(); | |||
private OrganizationDbTester organizationDbTester = db.organizations(); | |||
private WsActionTester wsActionTester = new WsActionTester(underTest); | |||
WebService.Action action = wsActionTester.getDef(); | |||
@Test | |||
public void definition() { | |||
assertThat(action).isNotNull(); | |||
assertThat(action.isInternal()).isFalse(); | |||
assertThat(action.isPost()).isFalse(); | |||
assertThat(action.responseExampleAsString()).isNotEmpty(); | |||
assertThat(action.params()) | |||
.extracting(Param::key, Param::isRequired) | |||
.containsExactlyInAnyOrder( | |||
tuple("organization", false), | |||
tuple("project", false)); | |||
WebService.Action action = wsActionTester.getDef(); | |||
} | |||
assertThat(action).isNotNull(); | |||
assertThat(action.isInternal()).isFalse(); | |||
assertThat(action.isPost()).isFalse(); | |||
assertThat(action.responseExampleAsString()).isNotEmpty(); | |||
assertThat(action.params()) | |||
.extracting(Param::key, Param::isRequired) | |||
.containsExactlyInAnyOrder( | |||
tuple("organization", false), | |||
tuple("project", false)); | |||
@Test | |||
public void List_global_webhooks() { | |||
} | |||
WebhookDto dto1 = webhookDbTester.insertWebhook(db.getDefaultOrganization()); | |||
WebhookDto dto2 = webhookDbTester.insertWebhook(db.getDefaultOrganization()); | |||
userSession.logIn().addPermission(ADMINISTER, db.getDefaultOrganization().getUuid()); | |||
@Test | |||
public void list_webhooks_and_their_latest_delivery() { | |||
WebhookDto webhook1 = webhookDbTester.insert(newOrganizationWebhook("aaa", defaultOrganizationProvider.get().getUuid())); | |||
webhookDeliveryDbTester.insert(newDto("WH1-DELIVERY-1-UUID", webhook1.getUuid(), "COMPONENT_1", "TASK_1").setCreatedAt(BEFORE)); | |||
webhookDeliveryDbTester.insert(newDto("WH1-DELIVERY-2-UUID", webhook1.getUuid(), "COMPONENT_1", "TASK_2").setCreatedAt(NOW)); | |||
ListWsResponse response = wsActionTester.newRequest() | |||
.executeProtobuf(ListWsResponse.class); | |||
WebhookDto webhook2 = webhookDbTester.insert(newOrganizationWebhook("bbb", defaultOrganizationProvider.get().getUuid())); | |||
webhookDeliveryDbTester.insert(newDto("WH2-DELIVERY-1-UUID", webhook2.getUuid(), "COMPONENT_1", "TASK_1").setCreatedAt(BEFORE)); | |||
webhookDeliveryDbTester.insert(newDto("WH2-DELIVERY-2-UUID", webhook2.getUuid(), "COMPONENT_1", "TASK_2").setCreatedAt(NOW)); | |||
assertThat(response.getWebhooksList()) | |||
.extracting(List::getName, List::getUrl) | |||
.contains(tuple(dto1.getName(), dto1.getUrl()), | |||
tuple(dto2.getName(), dto2.getUrl())); | |||
userSession.logIn().addPermission(ADMINISTER, db.getDefaultOrganization().getUuid()); | |||
} | |||
ListResponse response = wsActionTester.newRequest().executeProtobuf(ListResponse.class); | |||
@Test | |||
public void List_project_webhooks_when_no_organization_is_provided() { | |||
List<Webhooks.ListResponseElement> elements = response.getWebhooksList(); | |||
assertThat(elements.size()).isEqualTo(2); | |||
ComponentDto project1 = componentDbTester.insertPrivateProject(); | |||
userSession.logIn().addProjectPermission(ADMIN, project1); | |||
assertThat(elements.get(0)).extracting(Webhooks.ListResponseElement::getKey).containsExactly(webhook1.getUuid()); | |||
assertThat(elements.get(0)).extracting(Webhooks.ListResponseElement::getName).containsExactly("aaa"); | |||
assertThat(elements.get(0).getLatestDelivery()).isNotNull(); | |||
assertThat(elements.get(0).getLatestDelivery()).extracting(Webhooks.LatestDelivery::getId).containsExactly("WH1-DELIVERY-2-UUID"); | |||
WebhookDto dto1 = webhookDbTester.insertWebhook(project1); | |||
WebhookDto dto2 = webhookDbTester.insertWebhook(project1); | |||
assertThat(elements.get(1)).extracting(Webhooks.ListResponseElement::getKey).containsExactly(webhook2.getUuid()); | |||
assertThat(elements.get(1)).extracting(Webhooks.ListResponseElement::getName).containsExactly("bbb"); | |||
assertThat(elements.get(1).getLatestDelivery()).isNotNull(); | |||
assertThat(elements.get(1).getLatestDelivery()).extracting(Webhooks.LatestDelivery::getId).containsExactly("WH2-DELIVERY-2-UUID"); | |||
} | |||
ListWsResponse response = wsActionTester.newRequest() | |||
.setParam(PROJECT_KEY_PARAM, project1.getKey()) | |||
.executeProtobuf(ListWsResponse.class); | |||
@Test | |||
public void list_webhooks_when_no_delivery() { | |||
WebhookDto webhook1 = webhookDbTester.insert(newOrganizationWebhook("aaa", defaultOrganizationProvider.get().getUuid())); | |||
WebhookDto webhook2 = webhookDbTester.insert(newOrganizationWebhook("bbb", defaultOrganizationProvider.get().getUuid())); | |||
assertThat(response.getWebhooksList()) | |||
.extracting(List::getName, List::getUrl) | |||
.contains(tuple(dto1.getName(), dto1.getUrl()), | |||
tuple(dto2.getName(), dto2.getUrl())); | |||
userSession.logIn().addPermission(ADMINISTER, db.getDefaultOrganization().getUuid()); | |||
} | |||
ListResponse response = wsActionTester.newRequest().executeProtobuf(ListResponse.class); | |||
@Test | |||
public void List_organization_webhooks() { | |||
List<Webhooks.ListResponseElement> elements = response.getWebhooksList(); | |||
assertThat(elements.size()).isEqualTo(2); | |||
OrganizationDto organizationDto = organizationDbTester.insert(); | |||
WebhookDto dto1 = webhookDbTester.insertWebhook(organizationDto); | |||
WebhookDto dto2 = webhookDbTester.insertWebhook(organizationDto); | |||
userSession.logIn().addPermission(ADMINISTER, organizationDto.getUuid()); | |||
assertThat(elements.get(0)).extracting(Webhooks.ListResponseElement::getKey).containsExactly(webhook1.getUuid()); | |||
assertThat(elements.get(0)).extracting(Webhooks.ListResponseElement::getName).containsExactly("aaa"); | |||
assertThat(elements.get(0).hasLatestDelivery()).isFalse(); | |||
ListWsResponse response = wsActionTester.newRequest() | |||
.setParam(ORGANIZATION_KEY_PARAM, organizationDto.getKey()) | |||
.executeProtobuf(ListWsResponse.class); | |||
assertThat(elements.get(1)).extracting(Webhooks.ListResponseElement::getKey).containsExactly(webhook2.getUuid()); | |||
assertThat(elements.get(1)).extracting(Webhooks.ListResponseElement::getName).containsExactly("bbb"); | |||
assertThat(elements.get(1).hasLatestDelivery()).isFalse(); | |||
} | |||
assertThat(response.getWebhooksList()) | |||
.extracting(List::getName, List::getUrl) | |||
.contains(tuple(dto1.getName(), dto1.getUrl()), | |||
tuple(dto2.getName(), dto2.getUrl())); | |||
@Test | |||
public void list_global_webhooks() { | |||
} | |||
WebhookDto dto1 = webhookDbTester.insertWebhook(db.getDefaultOrganization()); | |||
WebhookDto dto2 = webhookDbTester.insertWebhook(db.getDefaultOrganization()); | |||
userSession.logIn().addPermission(ADMINISTER, db.getDefaultOrganization().getUuid()); | |||
@Test | |||
public void List_project_webhooks_when_organization_is_provided() { | |||
ListResponse response = wsActionTester.newRequest() | |||
.executeProtobuf(ListResponse.class); | |||
OrganizationDto organization = organizationDbTester.insert(); | |||
ComponentDto project = componentDbTester.insertPrivateProject(organization); | |||
userSession.logIn().addProjectPermission(ADMIN, project); | |||
assertThat(response.getWebhooksList()) | |||
.extracting(Webhooks.ListResponseElement::getName, Webhooks.ListResponseElement::getUrl) | |||
.contains(tuple(dto1.getName(), dto1.getUrl()), | |||
tuple(dto2.getName(), dto2.getUrl())); | |||
WebhookDto dto1 = webhookDbTester.insertWebhook(project); | |||
WebhookDto dto2 = webhookDbTester.insertWebhook(project); | |||
} | |||
ListWsResponse response = wsActionTester.newRequest() | |||
.setParam(ORGANIZATION_KEY_PARAM, organization.getKey()) | |||
.setParam(PROJECT_KEY_PARAM, project.getKey()) | |||
.executeProtobuf(ListWsResponse.class); | |||
@Test | |||
public void list_project_webhooks_when_no_organization_is_provided() { | |||
assertThat(response.getWebhooksList()) | |||
.extracting(List::getName, List::getUrl) | |||
.contains(tuple(dto1.getName(), dto1.getUrl()), | |||
tuple(dto2.getName(), dto2.getUrl())); | |||
ComponentDto project1 = componentDbTester.insertPrivateProject(); | |||
userSession.logIn().addProjectPermission(ADMIN, project1); | |||
} | |||
WebhookDto dto1 = webhookDbTester.insertWebhook(project1); | |||
WebhookDto dto2 = webhookDbTester.insertWebhook(project1); | |||
@Test | |||
public void return_NotFoundException_if_requested_project_is_not_found() throws Exception { | |||
ListResponse response = wsActionTester.newRequest() | |||
.setParam(PROJECT_KEY_PARAM, project1.getKey()) | |||
.executeProtobuf(ListResponse.class); | |||
userSession.logIn().setSystemAdministrator(); | |||
expectedException.expect(NotFoundException.class); | |||
assertThat(response.getWebhooksList()) | |||
.extracting(Webhooks.ListResponseElement::getName, Webhooks.ListResponseElement::getUrl) | |||
.contains(tuple(dto1.getName(), dto1.getUrl()), | |||
tuple(dto2.getName(), dto2.getUrl())); | |||
wsActionTester.newRequest() | |||
.setParam(PROJECT_KEY_PARAM, "pipo") | |||
.executeProtobuf(ListWsResponse.class); | |||
} | |||
} | |||
@Test | |||
public void list_organization_webhooks() { | |||
@Test | |||
public void return_NotFoundException_if_requested_organization_is_not_found() throws Exception { | |||
OrganizationDto organizationDto = organizationDbTester.insert(); | |||
WebhookDto dto1 = webhookDbTester.insertWebhook(organizationDto); | |||
WebhookDto dto2 = webhookDbTester.insertWebhook(organizationDto); | |||
userSession.logIn().addPermission(ADMINISTER, organizationDto.getUuid()); | |||
userSession.logIn().setSystemAdministrator(); | |||
expectedException.expect(NotFoundException.class); | |||
ListResponse response = wsActionTester.newRequest() | |||
.setParam(ORGANIZATION_KEY_PARAM, organizationDto.getKey()) | |||
.executeProtobuf(ListResponse.class); | |||
wsActionTester.newRequest() | |||
.setParam(ORGANIZATION_KEY_PARAM, "pipo") | |||
.executeProtobuf(ListWsResponse.class); | |||
assertThat(response.getWebhooksList()) | |||
.extracting(Webhooks.ListResponseElement::getName, Webhooks.ListResponseElement::getUrl) | |||
.contains(tuple(dto1.getName(), dto1.getUrl()), | |||
tuple(dto2.getName(), dto2.getUrl())); | |||
} | |||
} | |||
@Test | |||
public void fail_if_project_exists_but_does_not_belong_to_requested_organization() { | |||
@Test | |||
public void list_project_webhooks_when_organization_is_provided() { | |||
OrganizationDto organization = organizationDbTester.insert(); | |||
ComponentDto project = componentDbTester.insertPrivateProject(); | |||
OrganizationDto organization = organizationDbTester.insert(); | |||
ComponentDto project = componentDbTester.insertPrivateProject(organization); | |||
userSession.logIn().addProjectPermission(ADMIN, project); | |||
expectedException.expect(NotFoundException.class); | |||
expectedException.expectMessage(format("Project '%s' does not belong to organisation '%s'", project.getKey(), organization.getKey())); | |||
WebhookDto dto1 = webhookDbTester.insertWebhook(project); | |||
WebhookDto dto2 = webhookDbTester.insertWebhook(project); | |||
userSession.logIn().addProjectPermission(ADMIN, project); | |||
ListResponse response = wsActionTester.newRequest() | |||
.setParam(ORGANIZATION_KEY_PARAM, organization.getKey()) | |||
.setParam(PROJECT_KEY_PARAM, project.getKey()) | |||
.executeProtobuf(ListResponse.class); | |||
wsActionTester.newRequest() | |||
.setParam(ORGANIZATION_KEY_PARAM, organization.getKey()) | |||
.setParam(PROJECT_KEY_PARAM, project.getKey()) | |||
.execute(); | |||
assertThat(response.getWebhooksList()) | |||
.extracting(Webhooks.ListResponseElement::getName, Webhooks.ListResponseElement::getUrl) | |||
.contains(tuple(dto1.getName(), dto1.getUrl()), | |||
tuple(dto2.getName(), dto2.getUrl())); | |||
} | |||
} | |||
@Test | |||
public void return_UnauthorizedException_if_not_logged_in() throws Exception { | |||
@Test | |||
public void return_NotFoundException_if_requested_project_is_not_found() throws Exception { | |||
userSession.anonymous(); | |||
expectedException.expect(UnauthorizedException.class); | |||
userSession.logIn().setSystemAdministrator(); | |||
expectedException.expect(NotFoundException.class); | |||
wsActionTester.newRequest() | |||
.executeProtobuf(ListWsResponse.class); | |||
wsActionTester.newRequest() | |||
.setParam(PROJECT_KEY_PARAM, "pipo") | |||
.executeProtobuf(ListResponse.class); | |||
} | |||
} | |||
@Test | |||
public void throw_ForbiddenException_if_not_organization_administrator() { | |||
@Test | |||
public void return_NotFoundException_if_requested_organization_is_not_found() throws Exception { | |||
userSession.logIn(); | |||
userSession.logIn().setSystemAdministrator(); | |||
expectedException.expect(NotFoundException.class); | |||
expectedException.expect(ForbiddenException.class); | |||
expectedException.expectMessage("Insufficient privileges"); | |||
wsActionTester.newRequest() | |||
.setParam(ORGANIZATION_KEY_PARAM, "pipo") | |||
.executeProtobuf(ListResponse.class); | |||
wsActionTester.newRequest() | |||
.executeProtobuf(ListWsResponse.class); | |||
} | |||
} | |||
@Test | |||
public void throw_ForbiddenException_if_not_project_administrator() { | |||
@Test | |||
public void fail_if_project_exists_but_does_not_belong_to_requested_organization() { | |||
ComponentDto project = componentDbTester.insertPrivateProject(); | |||
OrganizationDto organization = organizationDbTester.insert(); | |||
ComponentDto project = componentDbTester.insertPrivateProject(); | |||
userSession.logIn(); | |||
expectedException.expect(NotFoundException.class); | |||
expectedException.expectMessage(format("Project '%s' does not belong to organisation '%s'", project.getKey(), organization.getKey())); | |||
expectedException.expect(ForbiddenException.class); | |||
expectedException.expectMessage("Insufficient privileges"); | |||
userSession.logIn().addProjectPermission(ADMIN, project); | |||
wsActionTester.newRequest() | |||
.setParam(PROJECT_KEY_PARAM, project.getKey()) | |||
.executeProtobuf(ListWsResponse.class); | |||
wsActionTester.newRequest() | |||
.setParam(ORGANIZATION_KEY_PARAM, organization.getKey()) | |||
.setParam(PROJECT_KEY_PARAM, project.getKey()) | |||
.execute(); | |||
} | |||
} | |||
@Test | |||
public void return_UnauthorizedException_if_not_logged_in() throws Exception { | |||
userSession.anonymous(); | |||
expectedException.expect(UnauthorizedException.class); | |||
wsActionTester.newRequest() | |||
.executeProtobuf(ListResponse.class); | |||
} | |||
@Test | |||
public void throw_ForbiddenException_if_not_organization_administrator() { | |||
userSession.logIn(); | |||
expectedException.expect(ForbiddenException.class); | |||
expectedException.expectMessage("Insufficient privileges"); | |||
wsActionTester.newRequest() | |||
.executeProtobuf(ListResponse.class); | |||
} | |||
@Test | |||
public void throw_ForbiddenException_if_not_project_administrator() { | |||
ComponentDto project = componentDbTester.insertPrivateProject(); | |||
userSession.logIn(); | |||
expectedException.expect(ForbiddenException.class); | |||
expectedException.expectMessage("Insufficient privileges"); | |||
wsActionTester.newRequest() | |||
.setParam(PROJECT_KEY_PARAM, project.getKey()) | |||
.executeProtobuf(ListResponse.class); | |||
} | |||
} |
@@ -29,7 +29,7 @@ import org.sonar.api.web.UserRole; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.component.ComponentTesting; | |||
import org.sonar.db.webhook.WebhookDeliveryDbTester; | |||
import org.sonar.db.webhook.WebhookDeliveryDto; | |||
import org.sonar.server.component.ComponentFinder; | |||
import org.sonar.server.component.TestComponentFinder; | |||
@@ -40,7 +40,8 @@ import org.sonar.server.ws.WsActionTester; | |||
import org.sonarqube.ws.Webhooks; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.sonar.db.webhook.WebhookDbTesting.newWebhookDeliveryDto; | |||
import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto; | |||
import static org.sonar.db.webhook.WebhookDbTesting.newDto; | |||
import static org.sonar.test.JsonAssert.assertJson; | |||
public class WebhookDeliveriesActionTest { | |||
@@ -55,6 +56,8 @@ public class WebhookDeliveriesActionTest { | |||
public DbTester db = DbTester.create(System2.INSTANCE); | |||
private DbClient dbClient = db.getDbClient(); | |||
private WebhookDeliveryDbTester webhookDeliveryDbTester = db.webhookDelivery(); | |||
private WsActionTester ws; | |||
private ComponentDto project; | |||
@@ -63,7 +66,7 @@ public class WebhookDeliveriesActionTest { | |||
ComponentFinder componentFinder = TestComponentFinder.from(db); | |||
WebhookDeliveriesAction underTest = new WebhookDeliveriesAction(dbClient, userSession, componentFinder); | |||
ws = new WsActionTester(underTest); | |||
project = db.components().insertComponent(ComponentTesting.newPrivateProjectDto(db.organizations().insert()).setDbKey("my-project")); | |||
project = db.components().insertComponent(newPrivateProjectDto(db.organizations().insert()).setDbKey("my-project")); | |||
} | |||
@Test | |||
@@ -116,7 +119,7 @@ public class WebhookDeliveriesActionTest { | |||
@Test | |||
public void search_by_component_and_return_records_of_example() { | |||
WebhookDeliveryDto dto = newWebhookDeliveryDto() | |||
WebhookDeliveryDto dto = newDto() | |||
.setUuid("d1") | |||
.setComponentUuid(project.uuid()) | |||
.setCeTaskUuid("task-1") | |||
@@ -140,9 +143,9 @@ public class WebhookDeliveriesActionTest { | |||
@Test | |||
public void search_by_task_and_return_records() { | |||
WebhookDeliveryDto dto1 = newWebhookDeliveryDto().setComponentUuid(project.uuid()).setCeTaskUuid("t1"); | |||
WebhookDeliveryDto dto2 = newWebhookDeliveryDto().setComponentUuid(project.uuid()).setCeTaskUuid("t1"); | |||
WebhookDeliveryDto dto3 = newWebhookDeliveryDto().setComponentUuid(project.uuid()).setCeTaskUuid("t2"); | |||
WebhookDeliveryDto dto1 = newDto().setComponentUuid(project.uuid()).setCeTaskUuid("t1"); | |||
WebhookDeliveryDto dto2 = newDto().setComponentUuid(project.uuid()).setCeTaskUuid("t1"); | |||
WebhookDeliveryDto dto3 = newDto().setComponentUuid(project.uuid()).setCeTaskUuid("t2"); | |||
dbClient.webhookDeliveryDao().insert(db.getSession(), dto1); | |||
dbClient.webhookDeliveryDao().insert(db.getSession(), dto2); | |||
dbClient.webhookDeliveryDao().insert(db.getSession(), dto3); | |||
@@ -158,9 +161,9 @@ 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"); | |||
WebhookDeliveryDto dto1 = newDto().setComponentUuid(project.uuid()).setCeTaskUuid("t1").setWebhookUuid("wh-1-uuid"); | |||
WebhookDeliveryDto dto2 = newDto().setComponentUuid(project.uuid()).setCeTaskUuid("t1").setWebhookUuid("wh-1-uuid"); | |||
WebhookDeliveryDto dto3 = newDto().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); | |||
@@ -168,15 +171,72 @@ public class WebhookDeliveriesActionTest { | |||
userSession.logIn().addProjectPermission(UserRole.ADMIN, project); | |||
Webhooks.DeliveriesWsResponse response = ws.newRequest() | |||
.setParam("ceTaskId", "t1") | |||
.setParam("webhook", "wh-1-uuid") | |||
.executeProtobuf(Webhooks.DeliveriesWsResponse.class); | |||
assertThat(response.getDeliveriesCount()).isEqualTo(2); | |||
assertThat(response.getDeliveriesList()).extracting(Webhooks.Delivery::getId).containsOnly(dto1.getUuid(), dto2.getUuid()); | |||
} | |||
@Test | |||
public void validate_default_pagination() { | |||
for (int i = 0; i < 15; i++) { | |||
webhookDeliveryDbTester.insert(newDto().setComponentUuid(project.uuid()).setCeTaskUuid("t1").setWebhookUuid("wh-1-uuid")); | |||
} | |||
userSession.logIn().addProjectPermission(UserRole.ADMIN, project); | |||
Webhooks.DeliveriesWsResponse response = ws.newRequest() | |||
.setParam("webhook", "wh-1-uuid") | |||
.executeProtobuf(Webhooks.DeliveriesWsResponse.class); | |||
assertThat(response.getDeliveriesCount()).isEqualTo(10); | |||
} | |||
@Test | |||
public void validate_pagination_first_page() { | |||
for (int i = 0; i < 12; i++) { | |||
webhookDeliveryDbTester.insert(newDto().setComponentUuid(project.uuid()).setCeTaskUuid("t1").setWebhookUuid("wh-1-uuid")); | |||
} | |||
userSession.logIn().addProjectPermission(UserRole.ADMIN, project); | |||
Webhooks.DeliveriesWsResponse response = ws.newRequest() | |||
.setParam("webhook", "wh-1-uuid") | |||
.setParam("p", "1") | |||
.setParam("ps", "10") | |||
.executeProtobuf(Webhooks.DeliveriesWsResponse.class); | |||
assertThat(response.getDeliveriesCount()).isEqualTo(10); | |||
assertThat(response.getPaging().getTotal()).isEqualTo(12); | |||
assertThat(response.getPaging().getPageIndex()).isEqualTo(1); | |||
} | |||
@Test | |||
public void validate_pagination_last_page() { | |||
for (int i = 0; i < 12; i++) { | |||
webhookDeliveryDbTester.insert(newDto().setComponentUuid(project.uuid()).setCeTaskUuid("t1").setWebhookUuid("wh-1-uuid")); | |||
} | |||
userSession.logIn().addProjectPermission(UserRole.ADMIN, project); | |||
Webhooks.DeliveriesWsResponse response = ws.newRequest() | |||
.setParam("webhook", "wh-1-uuid") | |||
.setParam("p", "2") | |||
.setParam("ps", "10") | |||
.executeProtobuf(Webhooks.DeliveriesWsResponse.class); | |||
assertThat(response.getDeliveriesCount()).isEqualTo(2); | |||
assertThat(response.getPaging().getTotal()).isEqualTo(12); | |||
assertThat(response.getPaging().getPageIndex()).isEqualTo(2); | |||
} | |||
@Test | |||
public void search_by_component_and_throw_ForbiddenException_if_not_admin_of_project() { | |||
WebhookDeliveryDto dto = newWebhookDeliveryDto() | |||
WebhookDeliveryDto dto = newDto() | |||
.setComponentUuid(project.uuid()); | |||
dbClient.webhookDeliveryDao().insert(db.getSession(), dto); | |||
db.commit(); | |||
@@ -192,7 +252,7 @@ public class WebhookDeliveriesActionTest { | |||
@Test | |||
public void search_by_task_and_throw_ForbiddenException_if_not_admin_of_project() { | |||
WebhookDeliveryDto dto = newWebhookDeliveryDto() | |||
WebhookDeliveryDto dto = newDto() | |||
.setComponentUuid(project.uuid()); | |||
dbClient.webhookDeliveryDao().insert(db.getSession(), dto); | |||
db.commit(); |
@@ -42,7 +42,7 @@ import org.sonarqube.ws.MediaTypes; | |||
import org.sonarqube.ws.Webhooks; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.sonar.db.webhook.WebhookDbTesting.newWebhookDeliveryDto; | |||
import static org.sonar.db.webhook.WebhookDbTesting.newDto; | |||
import static org.sonar.test.JsonAssert.assertJson; | |||
public class WebhookDeliveryActionTest { | |||
@@ -100,7 +100,7 @@ public class WebhookDeliveryActionTest { | |||
@Test | |||
public void load_the_delivery_of_example() { | |||
WebhookDeliveryDto dto = newWebhookDeliveryDto() | |||
WebhookDeliveryDto dto = newDto() | |||
.setUuid("d1") | |||
.setComponentUuid(project.uuid()) | |||
.setCeTaskUuid("task-1") | |||
@@ -125,7 +125,7 @@ public class WebhookDeliveryActionTest { | |||
@Test | |||
public void return_delivery_that_failed_to_be_sent() { | |||
WebhookDeliveryDto dto = newWebhookDeliveryDto() | |||
WebhookDeliveryDto dto = newDto() | |||
.setComponentUuid(project.uuid()) | |||
.setSuccess(false) | |||
.setHttpStatus(null) | |||
@@ -147,7 +147,7 @@ public class WebhookDeliveryActionTest { | |||
@Test | |||
public void return_delivery_with_none_of_optional_fields() { | |||
WebhookDeliveryDto dto = newWebhookDeliveryDto() | |||
WebhookDeliveryDto dto = newDto() | |||
.setComponentUuid(project.uuid()) | |||
.setCeTaskUuid(null) | |||
.setHttpStatus(null) | |||
@@ -171,7 +171,7 @@ public class WebhookDeliveryActionTest { | |||
@Test | |||
public void throw_ForbiddenException_if_not_admin_of_project() { | |||
WebhookDeliveryDto dto = newWebhookDeliveryDto() | |||
WebhookDeliveryDto dto = newDto() | |||
.setComponentUuid(project.uuid()); | |||
dbClient.webhookDeliveryDao().insert(db.getSession(), dto); | |||
db.commit(); |
@@ -2824,7 +2824,7 @@ webhooks.delivery.duration_x=Duration: {0} | |||
webhooks.delivery.payload=Payload: | |||
webhooks.delivery.response_x=Response: {0} | |||
webhooks.documentation_link=Webhooks documentation | |||
webhooks.last_execution=Last execution | |||
webhooks.last_execution=Last delivery | |||
webhooks.last_execution.none=Never | |||
webhooks.maximum_reached=You reached your maximum number of {0} webhooks. You can still update or delete an existing one. | |||
webhooks.name=Name |
@@ -244,6 +244,7 @@ public interface WebService extends Definable<WebService.Context> { | |||
class NewAction { | |||
private final String key; | |||
private static final String PAGE_PARAM_DESCRIPTION = "1-based page number"; | |||
private String deprecatedKey; | |||
private String description; | |||
private String since; | |||
@@ -353,7 +354,7 @@ public interface WebService extends Definable<WebService.Context> { | |||
*/ | |||
public NewAction addPagingParams(int defaultPageSize) { | |||
createParam(Param.PAGE) | |||
.setDescription("1-based page number") | |||
.setDescription(PAGE_PARAM_DESCRIPTION) | |||
.setExampleValue("42") | |||
.setDeprecatedKey("pageIndex", "5.2") | |||
.setDefaultValue("1"); | |||
@@ -378,7 +379,7 @@ public interface WebService extends Definable<WebService.Context> { | |||
public NewParam createPageParam() { | |||
return createParam(Param.PAGE) | |||
.setDescription("1-based page number") | |||
.setDescription(PAGE_PARAM_DESCRIPTION) | |||
.setExampleValue("42") | |||
.setDeprecatedKey("pageIndex", "5.2") | |||
.setDefaultValue("1"); | |||
@@ -395,11 +396,11 @@ public interface WebService extends Definable<WebService.Context> { | |||
/** | |||
* Add predefined parameters related to pagination of results with a maximum page size. | |||
* Note the maximum is a documentation only feature. It does not check anything. | |||
* @since 7.1 | |||
*/ | |||
public NewAction addPagingParamsSince(int defaultPageSize, int maxPageSize, String version) { | |||
createParam(Param.PAGE) | |||
.setDescription("1-based page number") | |||
.setDescription(PAGE_PARAM_DESCRIPTION) | |||
.setExampleValue("42") | |||
.setDefaultValue("1") | |||
.setSince(version); |
@@ -19,7 +19,6 @@ | |||
*/ | |||
package org.sonarqube.ws.client.webhooks; | |||
import java.util.List; | |||
import javax.annotation.Generated; | |||
/** | |||
@@ -33,6 +32,9 @@ public class DeliveriesRequest { | |||
private String ceTaskId; | |||
private String componentKey; | |||
private String p; | |||
private String ps; | |||
private String webhook; | |||
/** | |||
* Example value: "AU-Tpxb--iU5OvuD2FLy" | |||
@@ -57,4 +59,40 @@ public class DeliveriesRequest { | |||
public String getComponentKey() { | |||
return componentKey; | |||
} | |||
/** | |||
* Example value: "42" | |||
*/ | |||
public DeliveriesRequest setP(String p) { | |||
this.p = p; | |||
return this; | |||
} | |||
public String getP() { | |||
return p; | |||
} | |||
/** | |||
* Example value: "20" | |||
*/ | |||
public DeliveriesRequest setPs(String ps) { | |||
this.ps = ps; | |||
return this; | |||
} | |||
public String getPs() { | |||
return ps; | |||
} | |||
/** | |||
* Example value: "AU-TpxcA-iU5OvuD2FLz" | |||
*/ | |||
public DeliveriesRequest setWebhook(String webhook) { | |||
this.webhook = webhook; | |||
return this; | |||
} | |||
public String getWebhook() { | |||
return webhook; | |||
} | |||
} |
@@ -19,17 +19,16 @@ | |||
*/ | |||
package org.sonarqube.ws.client.webhooks; | |||
import java.util.stream.Collectors; | |||
import javax.annotation.Generated; | |||
import org.sonarqube.ws.MediaTypes; | |||
import org.sonarqube.ws.Webhooks.CreateWsResponse; | |||
import org.sonarqube.ws.Webhooks.DeliveriesWsResponse; | |||
import org.sonarqube.ws.Webhooks.DeliveryWsResponse; | |||
import org.sonarqube.ws.Webhooks.ListResponse; | |||
import org.sonarqube.ws.client.BaseService; | |||
import org.sonarqube.ws.client.GetRequest; | |||
import org.sonarqube.ws.client.PostRequest; | |||
import org.sonarqube.ws.client.WsConnector; | |||
import org.sonarqube.ws.Webhooks.CreateWsResponse; | |||
import org.sonarqube.ws.Webhooks.DeliveriesWsResponse; | |||
import org.sonarqube.ws.Webhooks.DeliveryWsResponse; | |||
import org.sonarqube.ws.Webhooks.ListWsResponse; | |||
/** | |||
* @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/webhooks">Further information about this web service online</a> | |||
@@ -84,7 +83,10 @@ public class WebhooksService extends BaseService { | |||
return call( | |||
new GetRequest(path("deliveries")) | |||
.setParam("ceTaskId", request.getCeTaskId()) | |||
.setParam("componentKey", request.getComponentKey()), | |||
.setParam("componentKey", request.getComponentKey()) | |||
.setParam("p", request.getP()) | |||
.setParam("ps", request.getPs()) | |||
.setParam("webhook", request.getWebhook()), | |||
DeliveriesWsResponse.parser()); | |||
} | |||
@@ -109,12 +111,12 @@ public class WebhooksService extends BaseService { | |||
* @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/webhooks/list">Further information about this action online (including a response example)</a> | |||
* @since 7.1 | |||
*/ | |||
public ListWsResponse list(ListRequest request) { | |||
public ListResponse list(ListRequest request) { | |||
return call( | |||
new GetRequest(path("list")) | |||
.setParam("organization", request.getOrganization()) | |||
.setParam("project", request.getProject()), | |||
ListWsResponse.parser()); | |||
ListResponse.parser()); | |||
} | |||
/** |
@@ -26,24 +26,24 @@ option java_package = "org.sonarqube.ws"; | |||
option java_outer_classname = "Webhooks"; | |||
option optimize_for = SPEED; | |||
// GET api/webhooks/list | |||
message ListWsResponse { | |||
repeated List webhooks = 1; | |||
message LatestDelivery { | |||
optional string id = 1; | |||
optional string at = 2; | |||
optional bool success = 3; | |||
optional int32 httpStatus = 4; | |||
optional int32 durationMs = 5; | |||
} | |||
message List { | |||
optional string key = 1; | |||
optional string name = 2; | |||
optional string url = 3; | |||
optional LatestDelivery latestDelivery = 4; | |||
message ListResponseElement { | |||
optional string key = 1; | |||
optional string name = 2; | |||
optional string url = 3; | |||
optional LatestDelivery latestDelivery = 4; | |||
} | |||
message LatestDelivery { | |||
optional string id = 1; | |||
optional string at = 2; | |||
optional string success = 3; | |||
optional string httpStatus = 4; | |||
optional string durationMs = 5; | |||
} | |||
} | |||
// GET api/webhooks/list | |||
message ListResponse { | |||
repeated ListResponseElement webhooks = 1; | |||
} | |||
// POST api/webhooks/create |
@@ -151,7 +151,7 @@ public class WebhooksTest { | |||
assertThat(detail.getSuccess()).isFalse(); | |||
assertThat(detail.hasHttpStatus()).isFalse(); | |||
assertThat(detail.hasDurationMs()).isFalse(); | |||
assertThat(detail.hasDurationMs()).isTrue(); | |||
assertThat(detail.getPayload()).isNotEmpty(); | |||
assertThat(detail.getErrorStacktrace()) | |||
.contains("java.net.UnknownHostException") |