@@ -21,6 +21,7 @@ package org.sonar.db.webhook; | |||
import java.util.List; | |||
import java.util.Optional; | |||
import org.apache.ibatis.session.RowBounds; | |||
import org.sonar.db.Dao; | |||
import org.sonar.db.DbSession; | |||
@@ -30,25 +31,37 @@ public class WebhookDeliveryDao implements Dao { | |||
return Optional.ofNullable(mapper(dbSession).selectByUuid(uuid)); | |||
} | |||
public int countDeliveriesByWebhookUuid(DbSession dbSession, String webhookUuid) { | |||
return mapper(dbSession).countByWebhookUuid(webhookUuid); | |||
} | |||
/** | |||
* 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); | |||
public List<WebhookDeliveryLiteDto> selectByWebhookUuid(DbSession dbSession, String webhookUuid, int offset, int limit) { | |||
return mapper(dbSession).selectByWebhookUuid(webhookUuid, new RowBounds(offset, limit)); | |||
} | |||
public int countDeliveriesByComponentUuid(DbSession dbSession, String componentUuid) { | |||
return mapper(dbSession).countByComponentUuid(componentUuid); | |||
} | |||
/** | |||
* All the deliveries for the specified component. Results are ordered by descending date. | |||
*/ | |||
public List<WebhookDeliveryLiteDto> selectOrderedByComponentUuid(DbSession dbSession, String componentUuid) { | |||
return mapper(dbSession).selectOrderedByComponentUuid(componentUuid); | |||
public List<WebhookDeliveryLiteDto> selectOrderedByComponentUuid(DbSession dbSession, String componentUuid, int offset, int limit) { | |||
return mapper(dbSession).selectOrderedByComponentUuid(componentUuid, new RowBounds(offset, limit)); | |||
} | |||
public int countDeliveriesByCeTaskUuid(DbSession dbSession, String ceTaskId) { | |||
return mapper(dbSession).countByCeTaskUuid(ceTaskId); | |||
} | |||
/** | |||
* All the deliveries for the specified CE task. Results are ordered by descending date. | |||
*/ | |||
public List<WebhookDeliveryLiteDto> selectOrderedByCeTaskUuid(DbSession dbSession, String ceTaskUuid) { | |||
return mapper(dbSession).selectOrderedByCeTaskUuid(ceTaskUuid); | |||
public List<WebhookDeliveryLiteDto> selectOrderedByCeTaskUuid(DbSession dbSession, String ceTaskUuid, int offset, int limit) { | |||
return mapper(dbSession).selectOrderedByCeTaskUuid(ceTaskUuid, new RowBounds(offset, limit)); | |||
} | |||
public void insert(DbSession dbSession, WebhookDeliveryDto dto) { |
@@ -22,17 +22,24 @@ package org.sonar.db.webhook; | |||
import java.util.List; | |||
import javax.annotation.CheckForNull; | |||
import org.apache.ibatis.annotations.Param; | |||
import org.apache.ibatis.session.RowBounds; | |||
public interface WebhookDeliveryMapper { | |||
@CheckForNull | |||
WebhookDeliveryDto selectByUuid(@Param("uuid") String uuid); | |||
List<WebhookDeliveryLiteDto> selectByWebhookUuid(@Param("webhookUuid") String webhookUuid); | |||
int countByWebhookUuid(@Param("webhookUuid") String webhookUuid); | |||
List<WebhookDeliveryLiteDto> selectOrderedByComponentUuid(@Param("componentUuid") String componentUuid); | |||
List<WebhookDeliveryLiteDto> selectByWebhookUuid(@Param("webhookUuid") String webhookUuid, RowBounds rowBounds); | |||
List<WebhookDeliveryLiteDto> selectOrderedByCeTaskUuid(@Param("ceTaskUuid") String ceTaskUuid); | |||
int countByComponentUuid(@Param("componentUuid") String componentUuid); | |||
List<WebhookDeliveryLiteDto> selectOrderedByComponentUuid(@Param("componentUuid") String componentUuid, RowBounds rowBounds); | |||
int countByCeTaskUuid(@Param("ceTaskUuid") String ceTaskId); | |||
List<WebhookDeliveryLiteDto> selectOrderedByCeTaskUuid(@Param("ceTaskUuid") String ceTaskUuid, RowBounds rowBounds); | |||
void insert(WebhookDeliveryDto dto); | |||
@@ -26,6 +26,13 @@ | |||
where uuid = #{uuid,jdbcType=VARCHAR} | |||
</select> | |||
<select id="countByWebhookUuid" parameterType="String" resultType="int"> | |||
select | |||
count(1) | |||
from webhook_deliveries | |||
where webhook_uuid = #{webhookUuid,jdbcType=VARCHAR} | |||
</select> | |||
<select id="selectByWebhookUuid" parameterType="String" resultType="org.sonar.db.webhook.WebhookDeliveryLiteDto"> | |||
select <include refid="sqlLiteColumns" /> | |||
from webhook_deliveries | |||
@@ -33,6 +40,13 @@ | |||
order by created_at desc | |||
</select> | |||
<select id="countByComponentUuid" parameterType="String" resultType="int"> | |||
select | |||
count(1) | |||
from webhook_deliveries | |||
where component_uuid = #{componentUuid,jdbcType=VARCHAR} | |||
</select> | |||
<select id="selectOrderedByComponentUuid" parameterType="String" resultType="org.sonar.db.webhook.WebhookDeliveryLiteDto"> | |||
select <include refid="sqlLiteColumns" /> | |||
from webhook_deliveries | |||
@@ -47,6 +61,13 @@ | |||
order by created_at desc | |||
</select> | |||
<select id="countByCeTaskUuid" parameterType="String" resultType="int"> | |||
select | |||
count(1) | |||
from webhook_deliveries | |||
where ce_task_uuid = #{ceTaskUuid,jdbcType=VARCHAR} | |||
</select> | |||
<insert id="insert" parameterType="org.sonar.db.webhook.WebhookDeliveryDto" useGeneratedKeys="false"> | |||
insert into webhook_deliveries ( | |||
uuid, |
@@ -46,6 +46,8 @@ public class WebhookDeliveryDaoTest { | |||
private final DbClient dbClient = dbTester.getDbClient(); | |||
private final DbSession dbSession = dbTester.getSession(); | |||
private final WebhookDbTester dbWebhooks = dbTester.webhooks(); | |||
private final WebhookDeliveryDao underTest = dbClient.webhookDeliveryDao(); | |||
@Test | |||
@@ -55,53 +57,97 @@ public class WebhookDeliveryDaoTest { | |||
@Test | |||
public void selectOrderedByComponentUuid_returns_empty_if_no_records() { | |||
underTest.insert(dbSession, newDto("D1", "COMPONENT_1", "TASK_1")); | |||
underTest.insert(dbSession, newDto("D1", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_1")); | |||
List<WebhookDeliveryLiteDto> deliveries = underTest.selectOrderedByComponentUuid(dbSession, "ANOTHER_COMPONENT"); | |||
List<WebhookDeliveryLiteDto> deliveries = underTest.selectOrderedByComponentUuid(dbSession, "ANOTHER_COMPONENT", 0, 10); | |||
assertThat(deliveries).isEmpty(); | |||
} | |||
@Test | |||
public void selectOrderedByComponentUuid_returns_records_ordered_by_date() { | |||
WebhookDeliveryDto dto1 = newDto("D1", "COMPONENT_1", "TASK_1").setCreatedAt(BEFORE); | |||
WebhookDeliveryDto dto2 = newDto("D2", "COMPONENT_1", "TASK_1").setCreatedAt(NOW); | |||
WebhookDeliveryDto dto3 = newDto("D3", "COMPONENT_2", "TASK_1").setCreatedAt(NOW); | |||
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); | |||
underTest.insert(dbSession, dto3); | |||
underTest.insert(dbSession, dto2); | |||
underTest.insert(dbSession, dto1); | |||
List<WebhookDeliveryLiteDto> deliveries = underTest.selectOrderedByComponentUuid(dbSession, "COMPONENT_1"); | |||
List<WebhookDeliveryLiteDto> deliveries = underTest.selectOrderedByComponentUuid(dbSession, "COMPONENT_1", 0, 10); | |||
assertThat(deliveries).extracting(WebhookDeliveryLiteDto::getUuid).containsExactly("D2", "D1"); | |||
} | |||
@Test | |||
public void selectOrderedByCeTaskUuid_returns_empty_if_no_records() { | |||
underTest.insert(dbSession, newDto("D1", "COMPONENT_1", "TASK_1")); | |||
underTest.insert(dbSession, newDto("D1", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_1")); | |||
List<WebhookDeliveryLiteDto> deliveries = underTest.selectOrderedByCeTaskUuid(dbSession, "ANOTHER_TASK"); | |||
List<WebhookDeliveryLiteDto> deliveries = underTest.selectOrderedByCeTaskUuid(dbSession, "ANOTHER_TASK", 0, 10); | |||
assertThat(deliveries).isEmpty(); | |||
} | |||
@Test | |||
public void selectOrderedByCeTaskUuid_returns_records_ordered_by_date() { | |||
WebhookDeliveryDto dto1 = newDto("D1", "COMPONENT_1", "TASK_1").setCreatedAt(BEFORE); | |||
WebhookDeliveryDto dto2 = newDto("D2", "COMPONENT_1", "TASK_1").setCreatedAt(NOW); | |||
WebhookDeliveryDto dto3 = newDto("D3", "COMPONENT_2", "TASK_2").setCreatedAt(NOW); | |||
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); | |||
underTest.insert(dbSession, dto3); | |||
underTest.insert(dbSession, dto2); | |||
underTest.insert(dbSession, dto1); | |||
List<WebhookDeliveryLiteDto> deliveries = underTest.selectOrderedByCeTaskUuid(dbSession, "TASK_1", 0, 10); | |||
assertThat(deliveries).extracting(WebhookDeliveryLiteDto::getUuid).containsExactly("D2", "D1"); | |||
} | |||
@Test | |||
public void selectByWebhookUuid_returns_empty_if_no_records() { | |||
underTest.insert(dbSession, newDto("D1", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_1")); | |||
List<WebhookDeliveryLiteDto> deliveries = underTest.selectByWebhookUuid(dbSession, "a-webhook-uuid", 0, 10); | |||
assertThat(deliveries).isEmpty(); | |||
} | |||
@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); | |||
underTest.insert(dbSession, dto3); | |||
underTest.insert(dbSession, dto2); | |||
underTest.insert(dbSession, dto1); | |||
List<WebhookDeliveryLiteDto> deliveries = underTest.selectOrderedByCeTaskUuid(dbSession, "TASK_1"); | |||
List<WebhookDeliveryLiteDto> deliveries = underTest.selectByWebhookUuid(dbSession, webhookDto.getUuid(), 0, 10); | |||
assertThat(deliveries).extracting(WebhookDeliveryLiteDto::getUuid).containsExactly("D2", "D1"); | |||
} | |||
@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)); | |||
List<WebhookDeliveryLiteDto> deliveries = underTest.selectByWebhookUuid(dbSession, webhookDto.getUuid(), 1, 3); | |||
assertThat(deliveries).extracting(WebhookDeliveryLiteDto::getUuid).containsExactlyInAnyOrder("D3", "D4", "D5"); | |||
} | |||
@Test | |||
public void insert_row_with_only_mandatory_columns() { | |||
WebhookDeliveryDto dto = newDto("DELIVERY_1", "COMPONENT_1", "TASK_1") | |||
WebhookDeliveryDto dto = newDto("DELIVERY_1", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_1") | |||
.setHttpStatus(null) | |||
.setDurationMs(null) | |||
.setErrorStacktrace(null); | |||
@@ -119,12 +165,13 @@ public class WebhookDeliveryDaoTest { | |||
@Test | |||
public void insert_row_with_all_columns() { | |||
WebhookDeliveryDto dto = newDto("DELIVERY_1", "COMPONENT_1", "TASK_1"); | |||
WebhookDeliveryDto dto = newDto("DELIVERY_1", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_1"); | |||
underTest.insert(dbSession, dto); | |||
WebhookDeliveryDto stored = selectByUuid(dto.getUuid()); | |||
verifyMandatoryFields(dto, stored); | |||
assertThat(stored.getWebhookUuid()).isEqualTo(dto.getWebhookUuid()); | |||
assertThat(stored.getHttpStatus()).isEqualTo(dto.getHttpStatus()); | |||
assertThat(stored.getDurationMs()).isEqualTo(dto.getDurationMs()); | |||
assertThat(stored.getErrorStacktrace()).isEqualTo(dto.getErrorStacktrace()); | |||
@@ -132,9 +179,9 @@ public class WebhookDeliveryDaoTest { | |||
@Test | |||
public void deleteComponentBeforeDate_deletes_rows_before_date() { | |||
underTest.insert(dbSession, newDto("DELIVERY_1", "COMPONENT_1", "TASK_1").setCreatedAt(1_000_000L)); | |||
underTest.insert(dbSession, newDto("DELIVERY_2", "COMPONENT_1", "TASK_2").setCreatedAt(2_000_000L)); | |||
underTest.insert(dbSession, newDto("DELIVERY_3", "COMPONENT_2", "TASK_3").setCreatedAt(1_000_000L)); | |||
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)); | |||
// should delete the old delivery on COMPONENT_1 and keep the one of COMPONENT_2 | |||
underTest.deleteComponentBeforeDate(dbSession, "COMPONENT_1", 1_500_000L); | |||
@@ -152,7 +199,7 @@ public class WebhookDeliveryDaoTest { | |||
@Test | |||
public void deleteComponentBeforeDate_does_nothing_on_invalid_uuid() { | |||
underTest.insert(dbSession, newDto("DELIVERY_1", "COMPONENT_1", "TASK_1").setCreatedAt(1_000_000L)); | |||
underTest.insert(dbSession, newDto("DELIVERY_1", "WEBHOOK_UUID_1", "COMPONENT_1", "TASK_1").setCreatedAt(1_000_000L)); | |||
underTest.deleteComponentBeforeDate(dbSession, "COMPONENT_2", 1_500_000L); | |||
@@ -174,9 +221,10 @@ public class WebhookDeliveryDaoTest { | |||
* Build a {@link WebhookDeliveryDto} with all mandatory fields. | |||
* Optional fields are kept null. | |||
*/ | |||
private static WebhookDeliveryDto newDto(String uuid, String componentUuid, String ceTaskUuid) { | |||
private static WebhookDeliveryDto newDto(String uuid, String webhookUuid, String componentUuid, String ceTaskUuid) { | |||
return newWebhookDeliveryDto() | |||
.setUuid(uuid) | |||
.setWebhookUuid(webhookUuid) | |||
.setComponentUuid(componentUuid) | |||
.setCeTaskUuid(ceTaskUuid); | |||
} |
@@ -36,6 +36,11 @@ public class WebhookTesting { | |||
.setProjectUuid(project.uuid()); | |||
} | |||
public static WebhookDto newProjectWebhook(String projectUuid) { | |||
return getWebhookDto() | |||
.setProjectUuid(projectUuid); | |||
} | |||
public static WebhookDto newWebhook(OrganizationDto organizationDto) { | |||
return getWebhookDto() | |||
.setOrganizationUuid(organizationDto.getUuid()); |
@@ -34,12 +34,16 @@ import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.webhook.WebhookDeliveryLiteDto; | |||
import org.sonar.server.component.ComponentFinder; | |||
import org.sonar.server.user.UserSession; | |||
import org.sonarqube.ws.Common; | |||
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.api.server.ws.WebService.Param.PAGE; | |||
import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE; | |||
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; | |||
import static org.sonar.server.ws.WsUtils.writeProtobuf; | |||
@@ -79,9 +83,11 @@ public class WebhookDeliveriesAction implements WebhooksWsAction { | |||
action.createParam(PARAM_WEBHOOK) | |||
.setSince("7.1") | |||
.setDescription("Key of the webhook that triggered those deliveries,"+ | |||
.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); | |||
action.addPagingParamsSince(10, MAX_LIMIT, "7.1"); | |||
} | |||
@Override | |||
@@ -92,42 +98,60 @@ public class WebhookDeliveriesAction implements WebhooksWsAction { | |||
String ceTaskId = request.param(PARAM_TASK); | |||
String componentKey = request.param(PARAM_COMPONENT); | |||
String webhookUuid = request.param(PARAM_WEBHOOK); | |||
int page = request.mandatoryParamAsInt(PAGE); | |||
int pageSize = request.mandatoryParamAsInt(PAGE_SIZE); | |||
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(webhookUuid, ceTaskId, componentKey); | |||
Data data = loadFromDatabase(webhookUuid, ceTaskId, componentKey, page, pageSize); | |||
data.ensureAdminPermission(userSession); | |||
data.writeTo(request, response); | |||
} | |||
private Data loadFromDatabase(@Nullable String webhookUuid, @Nullable String ceTaskId, @Nullable String componentKey) { | |||
ComponentDto component = null; | |||
private Data loadFromDatabase(@Nullable String webhookUuid, @Nullable String ceTaskId, @Nullable String componentKey, int page, int pageSize) { | |||
ComponentDto component; | |||
List<WebhookDeliveryLiteDto> deliveries; | |||
int totalElements; | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
if (isNotBlank(webhookUuid)) { | |||
deliveries = dbClient.webhookDeliveryDao().selectByWebhookUuid(dbSession, webhookUuid); | |||
deliveries = dbClient.webhookDeliveryDao().selectByWebhookUuid(dbSession, webhookUuid, page - 1, pageSize); | |||
component = getComponentDto(dbSession, deliveries); | |||
totalElements = dbClient.webhookDeliveryDao().countDeliveriesByWebhookUuid(dbSession, webhookUuid); | |||
} else if (componentKey != null) { | |||
component = componentFinder.getByKey(dbSession, componentKey); | |||
deliveries = dbClient.webhookDeliveryDao().selectOrderedByComponentUuid(dbSession, component.uuid()); | |||
deliveries = dbClient.webhookDeliveryDao().selectOrderedByComponentUuid(dbSession, component.uuid(), page - 1, pageSize); | |||
totalElements = dbClient.webhookDeliveryDao().countDeliveriesByComponentUuid(dbSession, component.uuid()); | |||
} else { | |||
deliveries = dbClient.webhookDeliveryDao().selectOrderedByCeTaskUuid(dbSession, ceTaskId); | |||
Optional<String> deliveredComponentUuid = deliveries | |||
.stream() | |||
.map(WebhookDeliveryLiteDto::getComponentUuid) | |||
.findFirst(); | |||
if (deliveredComponentUuid.isPresent()) { | |||
component = componentFinder.getByUuid(dbSession, deliveredComponentUuid.get()); | |||
} | |||
deliveries = dbClient.webhookDeliveryDao().selectOrderedByCeTaskUuid(dbSession, ceTaskId, page - 1, pageSize); | |||
component = getComponentDto(dbSession, deliveries); | |||
totalElements = dbClient.webhookDeliveryDao().countDeliveriesByCeTaskUuid(dbSession, ceTaskId); | |||
} | |||
} | |||
return new Data(component, deliveries); | |||
return new Data(component, deliveries).withPagingInfo(page, pageSize, totalElements); | |||
} | |||
private ComponentDto getComponentDto(DbSession dbSession, List<WebhookDeliveryLiteDto> deliveries) { | |||
Optional<String> deliveredComponentUuid = deliveries | |||
.stream() | |||
.map(WebhookDeliveryLiteDto::getComponentUuid) | |||
.findFirst(); | |||
if (deliveredComponentUuid.isPresent()) { | |||
return componentFinder.getByUuid(dbSession, deliveredComponentUuid.get()); | |||
} else { | |||
return null; | |||
} | |||
} | |||
private static class Data { | |||
private final ComponentDto component; | |||
private final List<WebhookDeliveryLiteDto> deliveryDtos; | |||
private int pageIndex; | |||
private int pageSize; | |||
private int totalElements; | |||
Data(@Nullable ComponentDto component, List<WebhookDeliveryLiteDto> deliveries) { | |||
this.deliveryDtos = deliveries; | |||
if (deliveries.isEmpty()) { | |||
@@ -150,7 +174,24 @@ public class WebhookDeliveriesAction implements WebhooksWsAction { | |||
copyDtoToProtobuf(component, dto, deliveryBuilder); | |||
responseBuilder.addDeliveries(deliveryBuilder); | |||
} | |||
responseBuilder.setPaging(buildPaging(pageIndex, pageSize, totalElements)); | |||
writeProtobuf(responseBuilder.build(), request, response); | |||
} | |||
static Common.Paging buildPaging(int pageIndex, int pageSize, int totalElements) { | |||
return Common.Paging.newBuilder() | |||
.setPageIndex(pageIndex) | |||
.setPageSize(pageSize) | |||
.setTotal(totalElements) | |||
.build(); | |||
} | |||
public Data withPagingInfo(int pageIndex, int pageSize, int totalElements) { | |||
this.pageIndex = pageIndex; | |||
this.pageSize = pageSize; | |||
this.totalElements = totalElements; | |||
return this; | |||
} | |||
} | |||
} |
@@ -1,14 +1,20 @@ | |||
{ | |||
"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\"}" | |||
} | |||
} | |||
"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 | |||
} | |||
] | |||
} |
@@ -68,7 +68,7 @@ public class WebhookDeliveriesActionTest { | |||
@Test | |||
public void test_definition() { | |||
assertThat(ws.getDef().params()).extracting(WebService.Param::key).containsExactlyInAnyOrder("componentKey", "ceTaskId", "webhook"); | |||
assertThat(ws.getDef().params()).extracting(WebService.Param::key).containsExactlyInAnyOrder("componentKey", "ceTaskId", "webhook", "p", "ps"); | |||
assertThat(ws.getDef().isPost()).isFalse(); | |||
assertThat(ws.getDef().isInternal()).isFalse(); | |||
assertThat(ws.getDef().responseExampleAsString()).isNotEmpty(); |
@@ -393,6 +393,25 @@ public interface WebService extends Definable<WebService.Context> { | |||
.setExampleValue("20"); | |||
} | |||
/** | |||
* 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. | |||
*/ | |||
public NewAction addPagingParamsSince(int defaultPageSize, int maxPageSize, String version) { | |||
createParam(Param.PAGE) | |||
.setDescription("1-based page number") | |||
.setExampleValue("42") | |||
.setDefaultValue("1") | |||
.setSince(version); | |||
createParam(Param.PAGE_SIZE) | |||
.setDescription("Page size. Must be greater than 0 and less than " + maxPageSize) | |||
.setDefaultValue(String.valueOf(defaultPageSize)) | |||
.setMaximumValue(maxPageSize) | |||
.setExampleValue("20") | |||
.setSince(version); | |||
return this; | |||
} | |||
/** | |||
* Creates the parameter {@link org.sonar.api.server.ws.WebService.Param#FIELDS}, which is | |||
* used to restrict the number of fields returned in JSON response. |
@@ -20,6 +20,8 @@ syntax = "proto2"; | |||
package sonarqube.ws.webhooks; | |||
import "ws-commons.proto"; | |||
option java_package = "org.sonarqube.ws"; | |||
option java_outer_classname = "Webhooks"; | |||
option optimize_for = SPEED; | |||
@@ -57,7 +59,10 @@ message CreateWsResponse { | |||
// WS api/webhooks/deliveries | |||
message DeliveriesWsResponse { | |||
repeated Delivery deliveries = 1; | |||
optional sonarqube.ws.commons.Paging paging = 1; | |||
repeated Delivery deliveries = 2; | |||
} | |||
// WS api/webhooks/delivery |