diff options
Diffstat (limited to 'server/sonar-db-dao/src')
5 files changed, 139 insertions, 129 deletions
diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/ce/CeActivityDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/ce/CeActivityDaoIT.java index eb05863189f..5a45c0e42e1 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/ce/CeActivityDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/ce/CeActivityDaoIT.java @@ -50,6 +50,7 @@ import org.sonar.db.Pagination; import org.sonar.db.component.BranchDto; import org.sonar.db.project.ProjectDto; +import static java.util.Collections.emptyList; import static java.util.Collections.singleton; import static java.util.Collections.singletonList; import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic; @@ -115,35 +116,46 @@ public class CeActivityDaoIT { assertThat(dto.getErrorStacktrace()).isNull(); assertThat(dto.getErrorType()).isNull(); assertThat(dto.isHasScannerContext()).isFalse(); - assertThat(dto.getWarningCount()).isZero(); + assertThat(dto.getCeTaskMessageDtos()).isEmpty(); } @Test - public void selectByUuid_populates_warning_count() { + public void selectByUuid_populates_messages() { CeActivityDto[] tasks = { insert("TASK_1", REPORT, "PROJECT_1", SUCCESS), insert("TASK_2", REPORT, "PROJECT_1", SUCCESS), insert("TASK_3", REPORT, "PROJECT_1", SUCCESS) }; - int moreThan1 = 2 + new Random().nextInt(5); - insertWarnings(tasks[0], moreThan1); - insertWarnings(tasks[1], 0); - insertWarnings(tasks[2], 1); - - assertThat(underTest.selectByUuid(dbSession, tasks[0].getUuid()).get().getWarningCount()).isEqualTo(moreThan1); - assertThat(underTest.selectByUuid(dbSession, tasks[1].getUuid()).get().getWarningCount()).isZero(); - assertThat(underTest.selectByUuid(dbSession, tasks[2].getUuid()).get().getWarningCount()).isOne(); - } - - private void insertWarnings(CeActivityDto task, int warningCount) { - IntStream.range(0, warningCount).forEach(i -> db.getDbClient().ceTaskMessageDao().insert(dbSession, - new CeTaskMessageDto() - .setUuid(UuidFactoryFast.getInstance().create()) - .setTaskUuid(task.getUuid()) - .setMessage("message_" + task.getUuid() + "_" + i) - .setType(CeTaskMessageType.GENERIC) - .setCreatedAt(task.getUuid().hashCode() + i))); + List<CeTaskMessageDto> task1messages = insertCeTaskMessage(tasks[0], 4); + List<CeTaskMessageDto> task2messages = insertCeTaskMessage(tasks[1], 0); + List<CeTaskMessageDto> task3messages = insertCeTaskMessage(tasks[2], 1); + + getCeActivityAndAssertMessages(tasks[0].getUuid(), task1messages); + getCeActivityAndAssertMessages(tasks[1].getUuid(), task2messages); + getCeActivityAndAssertMessages(tasks[2].getUuid(), task3messages); + } + + private void getCeActivityAndAssertMessages(String taskUuid, List<CeTaskMessageDto> taskMessages) { + CeActivityDto ceActivityDto = underTest.selectByUuid(dbSession, taskUuid).orElseThrow(); + assertThat(ceActivityDto.getCeTaskMessageDtos()).usingRecursiveFieldByFieldElementComparator().hasSameElementsAs(taskMessages); + } + + private List<CeTaskMessageDto> insertCeTaskMessage(CeActivityDto task, int messagesCount) { + List<CeTaskMessageDto> ceTaskMessageDtos = IntStream.range(0, messagesCount) + .mapToObj(i -> createMessage(task, i)) + .toList(); + ceTaskMessageDtos.forEach(ceTaskMessageDto -> db.getDbClient().ceTaskMessageDao().insert(dbSession, ceTaskMessageDto)); db.commit(); + return ceTaskMessageDtos; + } + + private static CeTaskMessageDto createMessage(CeActivityDto task, int i) { + return new CeTaskMessageDto() + .setUuid(UuidFactoryFast.getInstance().create()) + .setTaskUuid(task.getUuid()) + .setMessage("message_" + task.getUuid() + "_" + i) + .setType(CeTaskMessageType.GENERIC) + .setCreatedAt(task.getUuid().hashCode() + i); } @Test @@ -518,7 +530,7 @@ public class CeActivityDaoIT { } @Test - public void selectByQuery_populates_warningCount() { + public void selectByQuery_populates_messages() { CeActivityDto[] tasks = { insert("TASK_1", REPORT, "PROJECT_1", SUCCESS), insert("TASK_2", REPORT, "PROJECT_1", FAILED), @@ -526,45 +538,57 @@ public class CeActivityDaoIT { insert("TASK_4", "views", null, SUCCESS) }; int moreThan1 = 2 + new Random().nextInt(5); - insertWarnings(tasks[0], moreThan1); - insertWarnings(tasks[1], 3); - insertWarnings(tasks[2], 1); - insertWarnings(tasks[3], 6); + insertCeTaskMessage(tasks[0], moreThan1); + insertCeTaskMessage(tasks[1], 30); + insertCeTaskMessage(tasks[2], 10); + insertCeTaskMessage(tasks[3], 60); // no filters - CeTaskQuery query = new CeTaskQuery().setStatuses(Collections.emptyList()); + CeTaskQuery query = new CeTaskQuery(); assertThat(underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(10))) - .extracting(CeActivityDto::getUuid, CeActivityDto::getWarningCount) - .containsExactly(tuple("TASK_4", 6), tuple("TASK_3", 1), tuple("TASK_2", 3), tuple("TASK_1", moreThan1)); + .extracting(CeActivityDto::getUuid, ceActivityDto -> ceActivityDto.getCeTaskMessageDtos().size()) + .containsExactly(tuple("TASK_4", 60), tuple("TASK_3", 10), tuple("TASK_2", 30), tuple("TASK_1", moreThan1)); // select by component uuid query = new CeTaskQuery().setMainComponentUuid("PROJECT_1"); assertThat(underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100))) - .extracting(CeActivityDto::getUuid, CeActivityDto::getWarningCount) - .containsExactly(tuple("TASK_2", 3), tuple("TASK_1", moreThan1)); + .extracting(CeActivityDto::getUuid, ceActivityDto -> ceActivityDto.getCeTaskMessageDtos().size()) + .containsExactly(tuple("TASK_2", 30), tuple("TASK_1", moreThan1)); // select by status query = new CeTaskQuery().setStatuses(singletonList(SUCCESS.name())); assertThat(underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100))) - .extracting(CeActivityDto::getUuid, CeActivityDto::getWarningCount) - .containsExactly(tuple("TASK_4", 6), tuple("TASK_3", 1), tuple("TASK_1", moreThan1)); + .extracting(CeActivityDto::getUuid, ceActivityDto -> ceActivityDto.getCeTaskMessageDtos().size()) + .containsExactly(tuple("TASK_4", 60), tuple("TASK_3", 10), tuple("TASK_1", moreThan1)); // select by type query = new CeTaskQuery().setType(REPORT); assertThat(underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100))) - .extracting(CeActivityDto::getUuid, CeActivityDto::getWarningCount) - .containsExactly(tuple("TASK_3", 1), tuple("TASK_2", 3), tuple("TASK_1", moreThan1)); + .extracting(CeActivityDto::getUuid, ceActivityDto -> ceActivityDto.getCeTaskMessageDtos().size()) + .containsExactly(tuple("TASK_3", 10), tuple("TASK_2", 30), tuple("TASK_1", moreThan1)); query = new CeTaskQuery().setType("views"); assertThat(underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100))) - .extracting(CeActivityDto::getUuid, CeActivityDto::getWarningCount) - .containsExactly(tuple("TASK_4", 6)); + .extracting(CeActivityDto::getUuid, ceActivityDto -> ceActivityDto.getCeTaskMessageDtos().size()) + .containsExactly(tuple("TASK_4", 60)); // select by multiple conditions query = new CeTaskQuery().setType(REPORT).setOnlyCurrents(true).setMainComponentUuid("PROJECT_1"); assertThat(underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100))) - .extracting(CeActivityDto::getUuid, CeActivityDto::getWarningCount) - .containsExactly(tuple("TASK_2", 3)); + .extracting(CeActivityDto::getUuid, ceActivityDto -> ceActivityDto.getCeTaskMessageDtos().size()) + .containsExactly(tuple("TASK_2", 30)); + + } + @Test + public void selectByQuery_whenNoMessage_returnsEmptyList() { + insert("TASK_1", REPORT, "PROJECT_1", SUCCESS); + + List<CeActivityDto> results = underTest.selectByQuery(db.getSession(), new CeTaskQuery(), Pagination.all()); + + assertThat(results) + .hasSize(1) + .extracting(CeActivityDto::getCeTaskMessageDtos) + .containsExactly(emptyList()); } @Test @@ -682,18 +706,18 @@ public class CeActivityDaoIT { } @Test - public void selectOlderThan_does_not_populate_warningCount() { + public void selectOlderThan_populatesCorrectly() { CeActivityDto activity1 = insert("TASK_1", REPORT, "PROJECT_1", FAILED); - insertWarnings(activity1, 10); + insertCeTaskMessage(activity1, 10); CeActivityDto activity2 = insert("TASK_2", REPORT, "PROJECT_1", SUCCESS); - insertWarnings(activity2, 1); + insertCeTaskMessage(activity2, 1); List<CeActivityDto> dtos = underTest.selectOlderThan(db.getSession(), system2.now() + 1_000_000L); assertThat(dtos) .hasSize(2) - .extracting(CeActivityDto::getWarningCount) - .containsOnly(0); + .extracting(ceActivityDto -> ceActivityDto.getCeTaskMessageDtos().size()) + .containsOnly(10, 1); } @Test @@ -804,7 +828,7 @@ public class CeActivityDaoIT { insert("TASK_6", CeTaskTypes.BRANCH_ISSUE_SYNC, projectBranch1.getUuid(), projectDto3.getUuid(), FAILED); BranchDto projectBranch2 = db.components() - .insertProjectBranch(projectDto3, branchDto -> branchDto.setNeedIssueSync(true)); + .insertProjectBranch(projectDto3, branchDto -> branchDto.setNeedIssueSync(true)); insert("TASK_7", CeTaskTypes.BRANCH_ISSUE_SYNC, projectBranch2.getUuid(), projectDto3.getUuid(), CANCELED); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeActivityDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeActivityDto.java index 407a093b368..1ae1fde50ed 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeActivityDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeActivityDto.java @@ -19,11 +19,12 @@ */ package org.sonar.db.ce; +import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Strings; +import java.util.List; import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.sonar.db.DbSession; -import org.sonar.db.component.ComponentDto; import static com.google.common.base.Preconditions.checkArgument; import static java.lang.String.format; @@ -99,13 +100,13 @@ public class CeActivityDto { * This property can not be populated when inserting but <strong>is populated when reading</strong>. */ private boolean hasScannerContext; + /** - * Count of warnings attached to the current activity. + * Messages attached to the current activity. * <p> - * This property can not be populated when inserting but <strong>is populated when retrieving the activity by UUID</strong>. + * This property can not be populated when inserting but <strong>is populated when retrieving the activity</strong>. */ - private int warningCount = 0; - + private List<CeTaskMessageDto> ceTaskMessageDtos; private String nodeName; CeActivityDto() { @@ -324,13 +325,13 @@ public class CeActivityDto { return this; } - public int getWarningCount() { - return warningCount; + public List<CeTaskMessageDto> getCeTaskMessageDtos() { + return ceTaskMessageDtos; } - protected CeActivityDto setWarningCount(int warningCount) { - checkArgument(warningCount >= 0); - this.warningCount = warningCount; + @VisibleForTesting + protected CeActivityDto setCeTaskMessageDtos(List<CeTaskMessageDto> ceTaskMessageDtos) { + this.ceTaskMessageDtos = ceTaskMessageDtos; return this; } @@ -369,7 +370,6 @@ public class CeActivityDto { ", errorMessage='" + errorMessage + '\'' + ", errorStacktrace='" + errorStacktrace + '\'' + ", hasScannerContext=" + hasScannerContext + - ", warningCount=" + warningCount + '}'; } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeTaskMessageType.java b/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeTaskMessageType.java index a7a7b343fbe..da7a1ddb2b2 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeTaskMessageType.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeTaskMessageType.java @@ -20,17 +20,23 @@ package org.sonar.db.ce; public enum CeTaskMessageType { - GENERIC(false), - SUGGEST_DEVELOPER_EDITION_UPGRADE(true), - INFO(false); + INFO(false, false), + GENERIC(false, true), + SUGGEST_DEVELOPER_EDITION_UPGRADE(true, true); private final boolean dismissible; + private final boolean isWarning; - CeTaskMessageType(boolean dismissible) { + CeTaskMessageType(boolean dismissible, boolean isWarning) { this.dismissible = dismissible; + this.isWarning = isWarning; } public boolean isDismissible() { return dismissible; } + + public boolean isWarning() { + return isWarning; + } } diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml index 0ad2f5d286b..07a3d8e4411 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml @@ -15,10 +15,6 @@ csc.task_uuid is not null as hasScannerContext </sql> - <sql id="countWarnings"> - (select count(1) from ce_task_message ctm where ctm.task_uuid = ca.uuid) as warningCount - </sql> - <sql id="ceActivityColumns"> ca.uuid, ca.node_name as nodeName, @@ -40,7 +36,12 @@ ca.main_is_last_key as mainIsLastKey, ca.execution_time_ms as executionTimeMs, ca.error_message as errorMessage, - ca.error_type as errorType + ca.error_type as errorType, + ctm.uuid as ctm_uuid, + ctm.task_uuid as ctm_taskUuid, + ctm.message as ctm_message, + ctm.message_type as ctm_type, + ctm.created_at as ctm_createdAt </sql> <sql id="columns"> @@ -48,57 +49,55 @@ <include refid="hasScannerContextColumn"/> </sql> - <select id="selectByUuid" parameterType="String" resultType="org.sonar.db.ce.CeActivityDto"> + <sql id="fromClauseWithJoins"> + from ce_activity ca + left outer join ce_task_message ctm on ca.uuid = ctm.task_uuid + left outer join ce_scanner_context csc on csc.task_uuid = ca.uuid + </sql> + + <resultMap id="ceActivityResultMap" type="org.sonar.db.ce.CeActivityDto" autoMapping="true"> + <id property="uuid" column="uuid"/> + <collection property="ceTaskMessageDtos" ofType="org.sonar.db.ce.CeTaskMessageDto" autoMapping="true" columnPrefix="ctm_"> + <id property="uuid" column="uuid"/> + <result property="key" column="kee"/> + </collection> + </resultMap> + + <select id="selectByUuid" parameterType="String" resultMap="ceActivityResultMap"> select <include refid="columns"/>, - ca.error_stacktrace as errorStacktrace, - <include refid="countWarnings"/> - from ce_activity ca - left outer join ce_scanner_context csc on - ca.uuid = csc.task_uuid + ca.error_stacktrace as errorStacktrace + <include refid="fromClauseWithJoins"/> where ca.uuid=#{uuid,jdbcType=VARCHAR} </select> - <select id="selectByQuery" parameterType="map" resultType="org.sonar.db.ce.CeActivityDto"> + <select id="selectByQuery" parameterType="map" resultMap="ceActivityResultMap"> select - <include refid="columns"/>, - <include refid="countWarnings"/> - <include refid="sqlSelectByQuery" /> - order by - ca.created_at desc, uuid desc - limit #{pagination.pageSize,jdbcType=INTEGER} offset #{pagination.offset,jdbcType=INTEGER} - </select> - - <select id="selectByQuery" parameterType="map" resultType="org.sonar.db.ce.CeActivityDto" databaseId="mssql"> - select * from ( - select row_number() over(order by ca.created_at desc, uuid desc) as number, - <include refid="columns"/>, - <include refid="countWarnings"/> + <include refid="columns"/> + <include refid="fromClauseWithJoins"/> + where ca.uuid in ( <include refid="sqlSelectByQuery" /> - ) as query - where - query.number between #{pagination.startRowNumber,jdbcType=INTEGER} and #{pagination.endRowNumber,jdbcType=INTEGER} - order by createdAt desc, uuid desc + ) + order by ca.created_at desc, ca.uuid desc </select> - <select id="selectByQuery" parameterType="map" resultType="org.sonar.db.ce.CeActivityDto" databaseId="oracle"> - select * from ( - select rownum as rn, t.* from ( - select - <include refid="columns"/>, - <include refid="countWarnings"/> - <include refid="sqlSelectByQuery" /> - order by ca.created_at desc, ca.uuid desc - ) t - ) t - where - t.rn between #{pagination.startRowNumber,jdbcType=INTEGER} and #{pagination.endRowNumber,jdbcType=INTEGER} + <sql id="sqlSelectByQuery"> + <include refid="sqlSelectByQueryWithoutPagination"/> + order by ca.created_at desc, uuid desc + offset (#{pagination.startRowNumber,jdbcType=INTEGER}-1) rows fetch next #{pagination.pageSize,jdbcType=INTEGER} rows only + </sql> + + <select id="countByQuery" parameterType="map" resultType="int"> + select + count(1) from ( + <include refid="sqlSelectByQueryWithoutPagination" /> + ) allTaskUuids </select> - <sql id="sqlSelectByQuery"> + <sql id="sqlSelectByQueryWithoutPagination"> + select ca.uuid from ce_activity ca - left outer join ce_scanner_context csc on csc.task_uuid = ca.uuid <where> <if test="query.onlyCurrents"> and ca.main_is_last=${_true} @@ -136,30 +135,22 @@ </where> </sql> - <select id="selectOlderThan" parameterType="long" resultType="org.sonar.db.ce.CeActivityDto"> + <select id="selectOlderThan" parameterType="long" resultMap="ceActivityResultMap"> select <include refid="columns"/> - from ce_activity ca - left outer join ce_scanner_context csc on csc.task_uuid = ca.uuid + <include refid="fromClauseWithJoins"/> where ca.created_at < #{beforeDate,jdbcType=BIGINT} </select> - <select id="selectNewerThan" parameterType="long" resultType="org.sonar.db.ce.CeActivityDto"> + <select id="selectNewerThan" parameterType="long" resultMap="ceActivityResultMap"> select <include refid="columns"/> - from ce_activity ca - left outer join ce_scanner_context csc on csc.task_uuid = ca.uuid + <include refid="fromClauseWithJoins"/> where ca.created_at > #{afterDate,jdbcType=BIGINT} </select> - <select id="countByQuery" parameterType="map" resultType="int"> - select - count(1) - <include refid="sqlSelectByQuery" /> - </select> - <select id="countLastByStatusAndMainComponentUuid" resultType="int"> select count(1) @@ -254,12 +245,10 @@ </foreach> </delete> - <select id="selectLastByComponentUuidAndTaskType" parameterType="map" resultType="org.sonar.db.ce.CeActivityDto"> + <select id="selectLastByComponentUuidAndTaskType" parameterType="map" resultMap="ceActivityResultMap"> select <include refid="columns"/> - from ce_activity ca - left outer join ce_scanner_context csc on - ca.uuid = csc.task_uuid + <include refid="fromClauseWithJoins"/> where ca.component_uuid = #{componentUuid,jdbcType=VARCHAR} and ca.task_type = #{taskType,jdbcType=VARCHAR} @@ -289,10 +278,10 @@ from dual </select> - <select id="selectByTaskType" parameterType="map" resultType="org.sonar.db.ce.CeActivityDto"> + <select id="selectByTaskType" parameterType="map" resultMap="ceActivityResultMap"> select <include refid="ceActivityColumns"/> - from ce_activity ca + <include refid="fromClauseWithJoins"/> where ca.task_type = #{taskType,jdbcType=VARCHAR} </select> diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeActivityDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeActivityDtoTest.java index 77d67fa80b8..702551ef98e 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeActivityDtoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeActivityDtoTest.java @@ -142,15 +142,6 @@ public class CeActivityDtoTest { assertThat(underTest.getErrorMessage()).isEqualTo(before + after); } - @Test - public void setWarningCount_throws_IAE_if_less_than_0() { - underTest.setWarningCount(0); - underTest.setWarningCount(1 + new Random().nextInt(10)); - - assertThatThrownBy(() -> underTest.setWarningCount(-1 - new Random().nextInt(10))) - .isInstanceOf(IllegalArgumentException.class); - } - @DataProvider public static Object[][] stringsWithChar0() { return new Object[][] { |