Browse Source

SONAR-8353 add WebhookDeliveryDao

tags/6.2-RC1
Simon Brandhof 7 years ago
parent
commit
ba7e66a7f6

+ 1
- 1
server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java View File

@@ -106,7 +106,7 @@ public class ComputeEngineContainerImplTest {
assertThat(picoContainer.getParent().getParent().getParent().getComponentAdapters()).hasSize(
COMPONENTS_IN_LEVEL_1_AT_CONSTRUCTION
+ 25 // level 1
+ 46 // content of DaoModule
+ 47 // content of DaoModule
+ 2 // content of EsSearchModule
+ 62 // content of CorePropertyDefinitions
+ 1 // content of CePropertyDefinitions

+ 3
- 1
sonar-db/src/main/java/org/sonar/db/DaoModule.java View File

@@ -66,6 +66,7 @@ import org.sonar.db.user.RoleDao;
import org.sonar.db.user.UserDao;
import org.sonar.db.user.UserGroupDao;
import org.sonar.db.user.UserTokenDao;
import org.sonar.db.webhook.WebhookDeliveryDao;

public class DaoModule extends Module {
private static final List<Class<? extends Dao>> classes = ImmutableList.<Class<? extends Dao>>builder().add(
@@ -112,7 +113,8 @@ public class DaoModule extends Module {
UserDao.class,
UserGroupDao.class,
UserPermissionDao.class,
UserTokenDao.class).build();
UserTokenDao.class,
WebhookDeliveryDao.class).build();

@Override
protected void configureModule() {

+ 7
- 0
sonar-db/src/main/java/org/sonar/db/DbClient.java View File

@@ -66,6 +66,7 @@ import org.sonar.db.user.RoleDao;
import org.sonar.db.user.UserDao;
import org.sonar.db.user.UserGroupDao;
import org.sonar.db.user.UserTokenDao;
import org.sonar.db.webhook.WebhookDeliveryDao;

public class DbClient {

@@ -115,6 +116,7 @@ public class DbClient {
private final ActiveRuleDao activeRuleDao;
private final QProfileChangeDao qProfileChangeDao;
private final UserPermissionDao userPermissionDao;
private final WebhookDeliveryDao webhookDeliveryDao;

public DbClient(Database database, MyBatis myBatis, Dao... daos) {
this.database = database;
@@ -168,6 +170,7 @@ public class DbClient {
activeRuleDao = getDao(map, ActiveRuleDao.class);
qProfileChangeDao = getDao(map, QProfileChangeDao.class);
userPermissionDao = getDao(map, UserPermissionDao.class);
webhookDeliveryDao = getDao(map, WebhookDeliveryDao.class);
}

public DbSession openSession(boolean batch) {
@@ -358,6 +361,10 @@ public class DbClient {
return userPermissionDao;
}

public WebhookDeliveryDao webhookDeliveryDao() {
return webhookDeliveryDao;
}

protected <K extends Dao> K getDao(Map<Class, Dao> map, Class<K> clazz) {
return (K) map.get(clazz);
}

+ 3
- 1
sonar-db/src/main/java/org/sonar/db/MyBatis.java View File

@@ -122,6 +122,7 @@ import org.sonar.db.version.SchemaMigrationMapper;
import org.sonar.db.version.v45.Migration45Mapper;
import org.sonar.db.version.v50.Migration50Mapper;
import org.sonar.db.version.v53.Migration53Mapper;
import org.sonar.db.webhook.WebhookDeliveryMapper;

public class MyBatis {

@@ -248,7 +249,8 @@ public class MyBatis {
UserGroupMapper.class,
UserMapper.class,
UserPermissionMapper.class,
UserTokenMapper.class
UserTokenMapper.class,
WebhookDeliveryMapper.class
};
confBuilder.loadMappers(mappers);


+ 42
- 0
sonar-db/src/main/java/org/sonar/db/webhook/WebhookDeliveryDao.java View File

@@ -0,0 +1,42 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact 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 java.util.Optional;
import org.sonar.db.Dao;
import org.sonar.db.DbSession;

public class WebhookDeliveryDao implements Dao {

public Optional<WebhookDeliveryDto> selectByUuid(DbSession dbSession, String uuid) {
return Optional.ofNullable(mapper(dbSession).selectByUuid(uuid));
}
public void insert(DbSession dbSession, WebhookDeliveryDto dto) {
mapper(dbSession).insert(dto);
}

public void deleteComponentBeforeDate(DbSession dbSession, String componentUuid, long beforeDate) {
mapper(dbSession).deleteComponentBeforeDate(componentUuid, beforeDate);
}

private static WebhookDeliveryMapper mapper(DbSession dbSession) {
return dbSession.getMapper(WebhookDeliveryMapper.class);
}
}

+ 66
- 0
sonar-db/src/main/java/org/sonar/db/webhook/WebhookDeliveryDto.java View File

@@ -0,0 +1,66 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact 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 javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.commons.lang.builder.ToStringBuilder;

public class WebhookDeliveryDto extends WebhookDeliveryLiteDto<WebhookDeliveryDto> {
/** Error message if HTTP request cannot be sent, else null */
private String errorStacktrace;
/** The payload that has been sent, cannot be null */
private String payload;

@CheckForNull
public String getErrorStacktrace() {
return errorStacktrace;
}

public WebhookDeliveryDto setErrorStacktrace(@Nullable String s) {
this.errorStacktrace = s;
return this;
}

@CheckForNull
public String getPayload() {
return payload;
}

public WebhookDeliveryDto setPayload(@Nullable String s) {
this.payload = s;
return this;
}

@Override
public String toString() {
return new ToStringBuilder(this)
.append("uuid", uuid)
.append("componentUuid", componentUuid)
.append("name", name)
.append("success", success)
.append("httpStatus", httpStatus)
.append("durationMs", durationMs)
.append("url", url)
.append("createdAt", createdAt)
.append("errorStacktrace", errorStacktrace)
.toString();
}
}

+ 142
- 0
sonar-db/src/main/java/org/sonar/db/webhook/WebhookDeliveryLiteDto.java View File

@@ -0,0 +1,142 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact 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 javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.commons.lang.builder.ToStringBuilder;

public class WebhookDeliveryLiteDto<T extends WebhookDeliveryLiteDto> {
/** Technical unique identifier, can't be null */
protected String uuid;
/** Component UUID, can't be null */
protected String componentUuid;
/** Compute Engine task UUID, can't be null */
protected String ceTaskUuid;
/** Name, can't be null */
protected String name;
protected boolean success;
/** HTTP response status. Null if HTTP request cannot be sent */
protected Integer httpStatus;
/** Duration in ms. Null if HTTP request cannot be sent */
protected Integer durationMs;
/** URL, cannot be null */
protected String url;
/** Time of delivery */
protected long createdAt;

public String getUuid() {
return uuid;
}

public T setUuid(String s) {
this.uuid = s;
return (T)this;
}

public String getComponentUuid() {
return componentUuid;
}

public T setComponentUuid(String s) {
this.componentUuid = s;
return (T)this;
}

public String getCeTaskUuid() {
return ceTaskUuid;
}

public T setCeTaskUuid(String s) {
this.ceTaskUuid = s;
return (T)this;
}

public String getName() {
return name;
}

public T setName(String s) {
this.name = s;
return (T)this;
}

public boolean isSuccess() {
return success;
}

public T setSuccess(boolean b) {
this.success = b;
return (T)this;
}

@CheckForNull
public Integer getHttpStatus() {
return httpStatus;
}

public T setHttpStatus(@Nullable Integer i) {
this.httpStatus = i;
return (T)this;
}

@CheckForNull
public Integer getDurationMs() {
return durationMs;
}

public T setDurationMs(@Nullable Integer i) {
this.durationMs = i;
return (T)this;
}

public String getUrl() {
return url;
}

public T setUrl(String s) {
this.url = s;
return (T)this;
}

public long getCreatedAt() {
return createdAt;
}

public T setCreatedAt(long l) {
this.createdAt = l;
return (T)this;
}

@Override
public String toString() {
return new ToStringBuilder(this)
.append("uuid", uuid)
.append("componentUuid", componentUuid)
.append("ceTaskUuid", ceTaskUuid)
.append("name", name)
.append("success", success)
.append("httpStatus", httpStatus)
.append("durationMs", durationMs)
.append("url", url)
.append("createdAt", createdAt)
.toString();
}
}

+ 33
- 0
sonar-db/src/main/java/org/sonar/db/webhook/WebhookDeliveryMapper.java View File

@@ -0,0 +1,33 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact 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 javax.annotation.CheckForNull;
import org.apache.ibatis.annotations.Param;

public interface WebhookDeliveryMapper {

@CheckForNull
WebhookDeliveryDto selectByUuid(@Param("uuid") String uuid);

void insert(WebhookDeliveryDto dto);

void deleteComponentBeforeDate(@Param("componentUuid") String componentUuid, @Param("beforeDate") long beforeDate);
}

+ 24
- 0
sonar-db/src/main/java/org/sonar/db/webhook/package-info.java View File

@@ -0,0 +1,24 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact 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.
*/
@ParametersAreNonnullByDefault
package org.sonar.db.webhook;

import javax.annotation.ParametersAreNonnullByDefault;


+ 58
- 0
sonar-db/src/main/resources/org/sonar/db/webhook/WebhookDeliveryMapper.xml View File

@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="org.sonar.db.webhook.WebhookDeliveryMapper">

<select id="selectByUuid" parameterType="String" resultType="org.sonar.db.webhook.WebhookDeliveryDto">
select
uuid,
component_uuid as componentUuid,
ce_task_uuid as ceTaskUuid,
name,
url,
success,
http_status as httpStatus,
duration_ms as durationMs,
payload,
error_stacktrace as errorStacktrace,
created_at as createdAt
from webhook_deliveries
where uuid = #{uuid,jdbcType=VARCHAR}
</select>

<insert id="insert" parameterType="org.sonar.db.webhook.WebhookDeliveryDto" useGeneratedKeys="false">
insert into webhook_deliveries (
uuid,
component_uuid,
ce_task_uuid,
name,
url,
success,
http_status,
duration_ms,
payload,
error_stacktrace,
created_at
) values (
#{uuid,jdbcType=VARCHAR},
#{componentUuid,jdbcType=VARCHAR},
#{ceTaskUuid,jdbcType=VARCHAR},
#{name,jdbcType=VARCHAR},
#{url,jdbcType=VARCHAR},
#{success,jdbcType=BOOLEAN},
#{httpStatus,jdbcType=INTEGER},
#{durationMs,jdbcType=INTEGER},
#{payload,jdbcType=VARCHAR},
#{errorStacktrace,jdbcType=VARCHAR},
#{createdAt,jdbcType=TIMESTAMP}
)
</insert>

<delete id="deleteComponentBeforeDate" parameterType="map">
delete from webhook_deliveries
where
component_uuid = #{componentUuid,jdbcType=VARCHAR} and
created_at &lt; #{beforeDate,jdbcType=BIGINT}
</delete>
</mapper>

+ 1
- 1
sonar-db/src/test/java/org/sonar/db/DaoModuleTest.java View File

@@ -29,6 +29,6 @@ public class DaoModuleTest {
public void verify_count_of_added_components() {
ComponentContainer container = new ComponentContainer();
new DaoModule().configure(container);
assertThat(container.size()).isEqualTo(2 + 44);
assertThat(container.size()).isEqualTo(2 + 45);
}
}

+ 131
- 0
sonar-db/src/test/java/org/sonar/db/webhook/WebhookDeliveryDaoTest.java View File

@@ -0,0 +1,131 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact 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 java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.utils.System2;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;

import static org.assertj.core.api.Assertions.assertThat;


public class WebhookDeliveryDaoTest {

private static final long DATE_1 = 1_999_000L;
@Rule
public final DbTester dbTester = DbTester.create(System2.INSTANCE).setDisableDefaultOrganization(true);

@Rule
public ExpectedException expectedException = ExpectedException.none();

private final DbClient dbClient = dbTester.getDbClient();
private final DbSession dbSession = dbTester.getSession();
private final WebhookDeliveryDao underTest = dbClient.webhookDeliveryDao();

@Test
public void insert_row_with_only_mandatory_columns() {
WebhookDeliveryDto dto = newDto("DELIVERY_1", "COMPONENT_1", "TASK_1");

underTest.insert(dbSession, dto);

WebhookDeliveryDto stored = selectByUuid(dto.getUuid());
verifyMandatoryFields(dto, stored);

// optional fields are null
assertThat(stored.getHttpStatus()).isNull();
assertThat(stored.getDurationMs()).isNull();
assertThat(stored.getErrorStacktrace()).isNull();
}

@Test
public void insert_row_with_all_columns() {
WebhookDeliveryDto dto = newDto("DELIVERY_1", "COMPONENT_1", "TASK_1")
.setDurationMs(10000)
.setHttpStatus(200)
.setErrorStacktrace("timeout")
.setPayload("{json}");

underTest.insert(dbSession, dto);

WebhookDeliveryDto stored = selectByUuid(dto.getUuid());
verifyMandatoryFields(dto, stored);
assertThat(stored.getHttpStatus()).isEqualTo(dto.getHttpStatus());
assertThat(stored.getDurationMs()).isEqualTo(dto.getDurationMs());
assertThat(stored.getErrorStacktrace()).isEqualTo(dto.getErrorStacktrace());
}

@Test
public void delete_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));

// should delete the old delivery on COMPONENT_1 and keep the one of COMPONENT_2
underTest.deleteComponentBeforeDate(dbSession, "COMPONENT_1", 1_500_000L);

List<Object> uuids = dbTester.select(dbSession, "select uuid as \"uuid\" from webhook_deliveries")
.stream()
.map(columns -> columns.get("uuid"))
.collect(Collectors.toList());
assertThat(uuids).containsOnly("DELIVERY_2", "DELIVERY_3");

}

private void verifyMandatoryFields(WebhookDeliveryDto expected, WebhookDeliveryDto actual) {
assertThat(actual.getUuid()).isEqualTo(expected.getUuid());
assertThat(actual.getComponentUuid()).isEqualTo(expected.getComponentUuid());
assertThat(actual.getCeTaskUuid()).isEqualTo(expected.getCeTaskUuid());
assertThat(actual.getName()).isEqualTo(expected.getName());
assertThat(actual.getUrl()).isEqualTo(expected.getUrl());
assertThat(actual.isSuccess()).isEqualTo(expected.isSuccess());
assertThat(actual.getPayload()).isEqualTo(expected.getPayload());
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 componentUuid, String ceTaskUuid) {
return new WebhookDeliveryDto()
.setUuid(uuid)
.setComponentUuid(componentUuid)
.setCeTaskUuid(ceTaskUuid)
.setName("Jenkins")
.setUrl("http://jenkins")
.setSuccess(true)
.setPayload("{json}")
.setCreatedAt(DATE_1);
}

private WebhookDeliveryDto selectByUuid(String uuid) {
Optional<WebhookDeliveryDto> dto = underTest.selectByUuid(dbSession, uuid);
assertThat(dto).isPresent();
return dto.get();
}
}

Loading…
Cancel
Save