aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAurelien Poscia <aurelien.poscia@sonarsource.com>2023-05-23 09:56:47 +0200
committersonartech <sonartech@sonarsource.com>2023-05-26 20:03:08 +0000
commitd6364ee9a0dcd7ada6ee8b192f1738d260baadee (patch)
treedc8ad22535ccf9296deb7d4a208fd7652580cb40
parent36d7ca7391eed1ca47784cf4715e875c90145b50 (diff)
downloadsonarqube-d6364ee9a0dcd7ada6ee8b192f1738d260baadee.tar.gz
sonarqube-d6364ee9a0dcd7ada6ee8b192f1738d260baadee.zip
SONAR-19346 Publish GitHub sync provisioning summary
-rw-r--r--server/sonar-db-dao/src/it/java/org/sonar/db/ce/CeActivityDaoIT.java112
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeActivityDto.java22
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeTaskMessageType.java14
-rw-r--r--server/sonar-db-dao/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml111
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeActivityDtoTest.java9
-rw-r--r--server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ActivityActionIT.java20
-rw-r--r--server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ComponentActionIT.java24
-rw-r--r--server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/TaskActionIT.java47
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ActivityAction.java9
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ComponentAction.java3
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/TaskAction.java20
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/TaskFormatter.java56
-rw-r--r--server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/ws/TaskFormatterTest.java76
13 files changed, 285 insertions, 238 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 &lt; #{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 &gt; #{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[][] {
diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ActivityActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ActivityActionIT.java
index 893f5ede974..1a993ffed32 100644
--- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ActivityActionIT.java
+++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ActivityActionIT.java
@@ -241,15 +241,15 @@ public class ActivityActionIT {
}
@Test
- public void return_warnings_count_on_queue_and_activity_but_no_warnings_list() {
+ public void return_warnings_count_on_queue_and_activity_and_warnings_list() {
logInAsSystemAdministrator();
ComponentDto project1 = db.components().insertPrivateProject().getMainBranchComponent();
ComponentDto project2 = db.components().insertPrivateProject().getMainBranchComponent();
insertActivity("T1", project1, SUCCESS);
insertActivity("T2", project2, FAILED);
insertQueue("T3", project1, IN_PROGRESS);
- insertMessages("T1", 2);
- insertMessages("T2", 0);
+ List<String> messagesT1 = insertMessages("T1", 2);
+ List<String> messagesT2 = insertMessages("T2", 1);
insertMessages("T3", 5);
ActivityResponse activityResponse = call(ws.newRequest()
@@ -257,18 +257,22 @@ public class ActivityActionIT {
.setParam(PARAM_STATUS, "SUCCESS,FAILED,CANCELED,IN_PROGRESS,PENDING"));
assertThat(activityResponse.getTasksList())
.extracting(Task::getId, Task::getWarningCount, Task::getWarningsList)
- .containsOnly(tuple("T1", 2, emptyList()), tuple("T2", 0, emptyList()), tuple("T3", 0, emptyList()));
+ .containsOnly(tuple("T1", messagesT1.size(), messagesT1), tuple("T2", messagesT2.size(), messagesT2), tuple("T3", 0, emptyList()));
}
- private void insertMessages(String taskUuid, int messageCount) {
- IntStream.range(0, messageCount)
- .forEach(i -> db.getDbClient().ceTaskMessageDao().insert(db.getSession(), new CeTaskMessageDto()
+ private List<String> insertMessages(String taskUuid, int messageCount) {
+ List<CeTaskMessageDto> ceTaskMessageDtos = IntStream.range(0, messageCount)
+ .mapToObj(i -> new CeTaskMessageDto()
.setUuid("uuid_" + taskUuid + "_" + i)
.setTaskUuid(taskUuid)
.setMessage("m_" + taskUuid + "_" + i)
.setType(CeTaskMessageType.GENERIC)
- .setCreatedAt(taskUuid.hashCode() + i)));
+ .setCreatedAt(taskUuid.hashCode() + i))
+ .toList();
+
+ ceTaskMessageDtos.forEach(ceTaskMessageDto -> db.getDbClient().ceTaskMessageDao().insert(db.getSession(), ceTaskMessageDto));
db.commit();
+ return ceTaskMessageDtos.stream().map(CeTaskMessageDto::getMessage).toList();
}
@Test
diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ComponentActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ComponentActionIT.java
index 4c9111b7182..8884dfa1965 100644
--- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ComponentActionIT.java
+++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ComponentActionIT.java
@@ -20,7 +20,7 @@
package org.sonar.server.ce.ws;
import java.util.Collections;
-import java.util.Random;
+import java.util.List;
import java.util.stream.IntStream;
import javax.annotation.Nullable;
import org.junit.Rule;
@@ -243,18 +243,22 @@ public class ComponentActionIT {
}
@Test
- public void populates_warning_count_of_activities_but_not_warnings() {
+ public void populates_warning_count_and_warnings_of_activities() {
ComponentDto privateProject = db.components().insertPrivateProject().getMainBranchComponent();
userSession.addProjectPermission(UserRole.USER, privateProject);
SnapshotDto analysis = db.components().insertSnapshot(privateProject);
CeActivityDto activity = insertActivity("Branch", privateProject, SUCCESS, analysis);
- int messageCount = 1 + new Random().nextInt(10);
- IntStream.range(0, messageCount).forEach(i -> db.getDbClient().ceTaskMessageDao().insert(db.getSession(), new CeTaskMessageDto()
- .setUuid("uuid_" + i)
- .setTaskUuid(activity.getUuid())
- .setMessage("m_" + i)
- .setType(CeTaskMessageType.GENERIC)
- .setCreatedAt(i)));
+ int messageCount = 5;
+ List<CeTaskMessageDto> ceTaskMessageDtos = IntStream.range(0, messageCount)
+ .mapToObj(i -> new CeTaskMessageDto()
+ .setUuid("uuid_" + i)
+ .setTaskUuid(activity.getUuid())
+ .setMessage("m_" + i)
+ .setType(CeTaskMessageType.GENERIC)
+ .setCreatedAt(i))
+ .toList();
+
+ ceTaskMessageDtos.forEach(ceTaskMessageDto -> db.getDbClient().ceTaskMessageDao().insert(db.getSession(), ceTaskMessageDto));
db.commit();
Ce.ComponentResponse response = ws.newRequest()
@@ -263,7 +267,7 @@ public class ComponentActionIT {
assertThat(response.hasCurrent()).isTrue();
assertThat(response.getCurrent())
.extracting(Ce.Task::getWarningCount, Ce.Task::getWarningsList)
- .containsOnly(messageCount, emptyList());
+ .containsOnly(messageCount, ceTaskMessageDtos.stream().map(CeTaskMessageDto::getMessage).toList());
}
@Test
diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/TaskActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/TaskActionIT.java
index bad7f04b69e..42a6b28c5f4 100644
--- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/TaskActionIT.java
+++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/TaskActionIT.java
@@ -20,7 +20,7 @@
package org.sonar.server.ce.ws;
import java.util.Collections;
-import java.util.Random;
+import java.util.List;
import java.util.stream.IntStream;
import javax.annotation.Nullable;
import org.junit.Before;
@@ -115,7 +115,7 @@ public class TaskActionIT {
UserDto user = db.users().insertUser();
userSession.logIn(user).setSystemAdministrator();
CeQueueDto queueDto = createAndPersistQueueTask(null, user);
- IntStream.range(0, 1 + new Random().nextInt(5))
+ IntStream.range(0, 6)
.forEach(i -> db.getDbClient().ceTaskMessageDao().insert(db.getSession(),
new CeTaskMessageDto()
.setUuid("u_" + i)
@@ -181,7 +181,7 @@ public class TaskActionIT {
public void branch_in_queue_analysis() {
UserDto user = db.users().insertUser();
userSession.logIn(user).setSystemAdministrator();
- ;
+
String branch = "my_branch";
CeQueueDto queueDto = createAndPersistQueueTask(null, user);
insertCharacteristic(queueDto, BRANCH_KEY, branch);
@@ -433,7 +433,7 @@ public class TaskActionIT {
public void get_warnings_on_global_archived_task_requires_to_be_system_administrator() {
logInAsSystemAdministrator();
- getWarningsImpl(createAndPersistArchivedTask(null));
+ insertWarningsCallEndpointAndAssertWarnings(createAndPersistArchivedTask(null));
}
@Test
@@ -441,7 +441,7 @@ public class TaskActionIT {
userSession.logIn().registerComponents(publicProject);
CeActivityDto persistArchivedTask = createAndPersistArchivedTask(publicProject);
- assertThatThrownBy(() -> getWarningsImpl(persistArchivedTask))
+ assertThatThrownBy(() -> insertWarningsCallEndpointAndAssertWarnings(persistArchivedTask))
.isInstanceOf(ForbiddenException.class);
}
@@ -450,7 +450,7 @@ public class TaskActionIT {
userSession.logIn().addProjectPermission(UserRole.USER, privateProject);
CeActivityDto persistArchivedTask = createAndPersistArchivedTask(privateProject);
- assertThatThrownBy(() -> getWarningsImpl(persistArchivedTask))
+ assertThatThrownBy(() -> insertWarningsCallEndpointAndAssertWarnings(persistArchivedTask))
.isInstanceOf(ForbiddenException.class);
}
@@ -458,33 +458,50 @@ public class TaskActionIT {
public void get_warnings_on_private_project_archived_task_if_scan() {
userSession.logIn().addProjectPermission(GlobalPermission.SCAN.getKey(), privateProject);
- getWarningsImpl(createAndPersistArchivedTask(privateProject));
+ insertWarningsCallEndpointAndAssertWarnings(createAndPersistArchivedTask(privateProject));
}
@Test
public void get_warnings_on_private_project_archived_task_if_global_scan_permission() {
userSession.logIn().addPermission(GlobalPermission.SCAN);
- getWarningsImpl(createAndPersistArchivedTask(privateProject));
+ insertWarningsCallEndpointAndAssertWarnings(createAndPersistArchivedTask(privateProject));
+ }
+
+ @Test
+ public void get_warnings_on_global_archived_task_requires_to_be_system_administrator2() {
+ logInAsSystemAdministrator();
+
+ CeActivityDto activityDto = persist(createActivityDto("uuid1"));
+ insertMessage(activityDto, 1, CeTaskMessageType.INFO);
+ CeTaskMessageDto warning = insertMessage(activityDto, 2, CeTaskMessageType.GENERIC);
+
+ callEndpointAndAssertWarnings(activityDto, List.of(warning));
}
- private void getWarningsImpl(CeActivityDto task) {
- String[] warnings = IntStream.range(0, 1 + new Random().nextInt(10))
+ private void insertWarningsCallEndpointAndAssertWarnings(CeActivityDto task) {
+ List<CeTaskMessageDto> warnings = IntStream.range(0, 6)
.mapToObj(i -> insertWarning(task, i))
- .map(CeTaskMessageDto::getMessage)
- .toArray(String[]::new);
+ .toList();
+ callEndpointAndAssertWarnings(task, warnings);
+ }
+ private void callEndpointAndAssertWarnings(CeActivityDto task, List<CeTaskMessageDto> warnings) {
Ce.Task taskWithWarnings = callWithWarnings(task.getUuid());
- assertThat(taskWithWarnings.getWarningCount()).isEqualTo(warnings.length);
- assertThat(taskWithWarnings.getWarningsList()).containsExactly(warnings);
+ assertThat(taskWithWarnings.getWarningCount()).isEqualTo(warnings.size());
+ assertThat(taskWithWarnings.getWarningsList()).isEqualTo(warnings.stream().map(CeTaskMessageDto::getMessage).toList());
}
private CeTaskMessageDto insertWarning(CeActivityDto task, int i) {
+ return insertMessage(task, i, CeTaskMessageType.GENERIC);
+ }
+
+ private CeTaskMessageDto insertMessage(CeActivityDto task, int i, CeTaskMessageType ceTaskMessageType) {
CeTaskMessageDto res = new CeTaskMessageDto()
.setUuid(UuidFactoryFast.getInstance().create())
.setTaskUuid(task.getUuid())
.setMessage("msg_" + task.getUuid() + "_" + i)
- .setType(CeTaskMessageType.GENERIC)
+ .setType(ceTaskMessageType)
.setCreatedAt(task.getUuid().hashCode() + i);
db.getDbClient().ceTaskMessageDao().insert(db.getSession(), res);
db.getSession().commit();
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ActivityAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ActivityAction.java
index 5eb7b96b74c..f30975adf1d 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ActivityAction.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ActivityAction.java
@@ -58,7 +58,6 @@ import static java.lang.Integer.max;
import static java.lang.Integer.parseInt;
import static java.lang.String.format;
import static java.util.Arrays.asList;
-import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static java.util.stream.Collectors.toSet;
import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY;
@@ -78,7 +77,7 @@ import static org.sonar.server.ws.WsUtils.writeProtobuf;
public class ActivityAction implements CeWsAction {
private static final int MAX_PAGE_SIZE = 1000;
- private static final String[] POSSIBLE_QUALIFIERS = new String[]{Qualifiers.PROJECT, Qualifiers.APP, Qualifiers.VIEW};
+ private static final String[] POSSIBLE_QUALIFIERS = new String[] {Qualifiers.PROJECT, Qualifiers.APP, Qualifiers.VIEW};
private static final String INVALID_QUERY_PARAM_ERROR_MESSAGE = "%s and %s must not be set at the same time";
private final UserSession userSession;
@@ -113,7 +112,9 @@ public class ActivityAction implements CeWsAction {
new Change("7.6", format("The use of module keys in parameters '%s' is deprecated", TEXT_QUERY)),
new Change("8.8", "field \"logs\" is dropped"),
new Change("10.0", "Remove deprecated field 'componentId'"),
- new Change("10.1", String.format("The use of module keys in parameter '%s' is removed", PARAM_COMPONENT)))
+ new Change("10.1", String.format("The use of module keys in parameter '%s' is removed", PARAM_COMPONENT)),
+ new Change("10.1", "Warnings field will be now be filled (it was always empty in the past).")
+ )
.setSince("5.2");
action.createParam(PARAM_COMPONENT)
@@ -264,7 +265,7 @@ public class ActivityAction implements CeWsAction {
}
Optional<CeActivityDto> activity = dbClient.ceActivityDao().selectByUuid(dbSession, textQuery);
- return activity.map(ceActivityDto -> formatter.formatActivity(dbSession, ceActivityDto, null, emptyList()));
+ return activity.map(ceActivityDto -> formatter.formatActivity(dbSession, ceActivityDto, null));
}
private CeTaskQuery buildQuery(DbSession dbSession, Request request, @Nullable ComponentDto component) {
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ComponentAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ComponentAction.java
index 6273a27cbe7..b9178c473ba 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ComponentAction.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ComponentAction.java
@@ -38,7 +38,6 @@ import org.sonarqube.ws.Ce;
import org.sonarqube.ws.Ce.ComponentResponse;
import static java.lang.String.format;
-import static java.util.Collections.emptyList;
import static org.sonar.db.Pagination.forPage;
import static org.sonar.server.ce.ws.CeWsParameters.PARAM_COMPONENT;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
@@ -92,7 +91,7 @@ public class ComponentAction implements CeWsAction {
Ce.ComponentResponse.Builder wsResponseBuilder = ComponentResponse.newBuilder();
wsResponseBuilder.addAllQueue(formatter.formatQueue(dbSession, queueDtos));
if (activityDtos.size() == 1) {
- wsResponseBuilder.setCurrent(formatter.formatActivity(dbSession, activityDtos.get(0), null, emptyList()));
+ wsResponseBuilder.setCurrent(formatter.formatActivity(dbSession, activityDtos.get(0), null));
}
writeProtobuf(wsResponseBuilder.build(), wsRequest, wsResponse);
}
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/TaskAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/TaskAction.java
index cc52bb9251b..2f15f9272a1 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/TaskAction.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/TaskAction.java
@@ -39,7 +39,6 @@ import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.ce.CeActivityDto;
import org.sonar.db.ce.CeQueueDto;
-import org.sonar.db.ce.CeTaskMessageDto;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.permission.GlobalPermission;
import org.sonar.server.user.UserSession;
@@ -75,7 +74,10 @@ public class TaskAction implements CeWsAction {
.setResponseExample(getClass().getResource("task-example.json"))
.setSince("5.2")
.setChangelog(
- new Change("6.6", "fields \"branch\" and \"branchType\" added"))
+ new Change("6.6", "fields \"branch\" and \"branchType\" added"),
+ new Change("10.1", "Warnings field will be now always be filled (it is not necessary to mention it explicitly in 'additionalFields'). "
+ + "'additionalFields' value `warning' is deprecated.")
+ )
.setHandler(this);
action
@@ -109,8 +111,7 @@ public class TaskAction implements CeWsAction {
maskErrorStacktrace(ceActivityDto, additionalFields);
wsTaskResponse.setTask(
wsTaskFormatter.formatActivity(dbSession, ceActivityDto,
- extractScannerContext(dbSession, ceActivityDto, additionalFields),
- extractWarnings(dbSession, ceActivityDto, additionalFields)));
+ extractScannerContext(dbSession, ceActivityDto, additionalFields)));
}
writeProtobuf(wsTaskResponse.build(), wsRequest, wsResponse);
}
@@ -151,19 +152,10 @@ public class TaskAction implements CeWsAction {
return null;
}
- private List<String> extractWarnings(DbSession dbSession, CeActivityDto activityDto, Set<AdditionalField> additionalFields) {
- if (additionalFields.contains(AdditionalField.WARNINGS)) {
- List<CeTaskMessageDto> dtos = dbClient.ceTaskMessageDao().selectByTask(dbSession, activityDto.getUuid());
- return dtos.stream()
- .map(CeTaskMessageDto::getMessage)
- .collect(MoreCollectors.toList(dtos.size()));
- }
- return Collections.emptyList();
- }
-
private enum AdditionalField {
STACKTRACE("stacktrace"),
SCANNER_CONTEXT("scannerContext"),
+ @Deprecated(forRemoval = true, since = "10.1")
WARNINGS("warnings");
private final String label;
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/TaskFormatter.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/TaskFormatter.java
index 54f941beb71..d8240d3bbc0 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/TaskFormatter.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/TaskFormatter.java
@@ -37,13 +37,13 @@ import org.sonar.db.DbSession;
import org.sonar.db.ce.CeActivityDto;
import org.sonar.db.ce.CeQueueDto;
import org.sonar.db.ce.CeTaskCharacteristicDto;
+import org.sonar.db.ce.CeTaskMessageDto;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.user.UserDto;
import org.sonarqube.ws.Ce;
import org.sonarqube.ws.Common;
import static java.lang.String.format;
-import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static java.util.Optional.ofNullable;
import static org.sonar.api.utils.DateUtils.formatDateTime;
@@ -90,39 +90,40 @@ public class TaskFormatter {
return builder.build();
}
- public Ce.Task formatActivity(DbSession dbSession, CeActivityDto dto, @Nullable String scannerContext, List<String> warnings) {
- return formatActivity(dto, DtoCache.forActivityDtos(dbClient, dbSession, singletonList(dto)), scannerContext, warnings);
+ public Ce.Task formatActivity(DbSession dbSession, CeActivityDto dto, @Nullable String scannerContext) {
+ return formatActivity(dto, DtoCache.forActivityDtos(dbClient, dbSession, singletonList(dto)), scannerContext);
}
public List<Ce.Task> formatActivity(DbSession dbSession, List<CeActivityDto> dtos) {
DtoCache cache = DtoCache.forActivityDtos(dbClient, dbSession, dtos);
return dtos.stream()
- .map(input -> formatActivity(input, cache, null, emptyList()))
+ .map(input -> formatActivity(input, cache, null))
.collect(MoreCollectors.toList(dtos.size()));
}
- private static Ce.Task formatActivity(CeActivityDto dto, DtoCache cache, @Nullable String scannerContext, List<String> warnings) {
+ private static Ce.Task formatActivity(CeActivityDto activityDto, DtoCache cache, @Nullable String scannerContext) {
Ce.Task.Builder builder = Ce.Task.newBuilder();
- builder.setId(dto.getUuid());
- builder.setStatus(Ce.TaskStatus.valueOf(dto.getStatus().name()));
- builder.setType(dto.getTaskType());
- ofNullable(dto.getNodeName()).ifPresent(builder::setNodeName);
- ofNullable(dto.getComponentUuid()).ifPresent(uuid -> setComponent(builder, uuid, cache).setComponentId(uuid));
- String analysisUuid = dto.getAnalysisUuid();
+ builder.setId(activityDto.getUuid());
+ builder.setStatus(Ce.TaskStatus.valueOf(activityDto.getStatus().name()));
+ builder.setType(activityDto.getTaskType());
+ ofNullable(activityDto.getNodeName()).ifPresent(builder::setNodeName);
+ ofNullable(activityDto.getComponentUuid()).ifPresent(uuid -> setComponent(builder, uuid, cache).setComponentId(uuid));
+ String analysisUuid = activityDto.getAnalysisUuid();
ofNullable(analysisUuid).ifPresent(builder::setAnalysisId);
- setBranchOrPullRequest(builder, dto.getUuid(), cache);
+ setBranchOrPullRequest(builder, activityDto.getUuid(), cache);
ofNullable(analysisUuid).ifPresent(builder::setAnalysisId);
- cache.getUser(dto.getSubmitterUuid()).ifPresent(user -> builder.setSubmitterLogin(user.getLogin()));
- builder.setSubmittedAt(formatDateTime(new Date(dto.getSubmittedAt())));
- ofNullable(dto.getStartedAt()).map(DateUtils::formatDateTime).ifPresent(builder::setStartedAt);
- ofNullable(dto.getExecutedAt()).map(DateUtils::formatDateTime).ifPresent(builder::setExecutedAt);
- ofNullable(dto.getExecutionTimeMs()).ifPresent(builder::setExecutionTimeMs);
- ofNullable(dto.getErrorMessage()).ifPresent(builder::setErrorMessage);
- ofNullable(dto.getErrorStacktrace()).ifPresent(builder::setErrorStacktrace);
- ofNullable(dto.getErrorType()).ifPresent(builder::setErrorType);
+ cache.getUser(activityDto.getSubmitterUuid()).ifPresent(user -> builder.setSubmitterLogin(user.getLogin()));
+ builder.setSubmittedAt(formatDateTime(new Date(activityDto.getSubmittedAt())));
+ ofNullable(activityDto.getStartedAt()).map(DateUtils::formatDateTime).ifPresent(builder::setStartedAt);
+ ofNullable(activityDto.getExecutedAt()).map(DateUtils::formatDateTime).ifPresent(builder::setExecutedAt);
+ ofNullable(activityDto.getExecutionTimeMs()).ifPresent(builder::setExecutionTimeMs);
+ ofNullable(activityDto.getErrorMessage()).ifPresent(builder::setErrorMessage);
+ ofNullable(activityDto.getErrorStacktrace()).ifPresent(builder::setErrorStacktrace);
+ ofNullable(activityDto.getErrorType()).ifPresent(builder::setErrorType);
ofNullable(scannerContext).ifPresent(builder::setScannerContext);
- builder.setHasScannerContext(dto.isHasScannerContext());
- builder.setWarningCount(dto.getWarningCount());
+ builder.setHasScannerContext(activityDto.isHasScannerContext());
+ List<String> warnings = extractWarningMessages(activityDto);
+ builder.setWarningCount(warnings.size());
warnings.forEach(builder::addWarnings);
return builder.build();
@@ -157,6 +158,13 @@ public class TaskFormatter {
return builder;
}
+ private static List<String> extractWarningMessages(CeActivityDto dto) {
+ return dto.getCeTaskMessageDtos().stream()
+ .filter(ceTaskMessageDto -> ceTaskMessageDto.getType().isWarning())
+ .map(CeTaskMessageDto::getMessage)
+ .toList();
+ }
+
private static class DtoCache {
private final Map<String, ComponentDto> componentsByUuid;
private final Multimap<String, CeTaskCharacteristicDto> characteristicsByTaskUuid;
@@ -190,8 +198,8 @@ public class TaskFormatter {
static DtoCache forActivityDtos(DbClient dbClient, DbSession dbSession, Collection<CeActivityDto> ceActivityDtos) {
Map<String, ComponentDto> componentsByUuid = dbClient.componentDao().selectByUuids(
- dbSession,
- getComponentUuidsOfCeActivities(ceActivityDtos))
+ dbSession,
+ getComponentUuidsOfCeActivities(ceActivityDtos))
.stream()
.collect(uniqueIndex(ComponentDto::uuid));
Multimap<String, CeTaskCharacteristicDto> characteristicsByTaskUuid = dbClient.ceTaskCharacteristicsDao()
diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/ws/TaskFormatterTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/ws/TaskFormatterTest.java
index 73d898d8272..ed2da8ed38b 100644
--- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/ws/TaskFormatterTest.java
+++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/ws/TaskFormatterTest.java
@@ -19,42 +19,41 @@
*/
package org.sonar.server.ce.ws;
-import java.util.Arrays;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
-import java.util.Random;
+import java.util.List;
import java.util.stream.IntStream;
import javax.annotation.Nullable;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.utils.DateUtils;
import org.sonar.api.utils.System2;
-import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.ce.CeActivityDto;
import org.sonar.db.ce.CeQueueDto;
+import org.sonar.db.ce.CeTaskMessageDto;
+import org.sonar.db.ce.CeTaskMessageType;
import org.sonar.db.ce.CeTaskTypes;
import org.sonar.db.user.UserDto;
import org.sonarqube.ws.Ce;
import static java.util.Arrays.asList;
-import static java.util.Collections.emptyList;
-import static java.util.stream.Collectors.toList;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.tuple;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.db.ce.CeQueueTesting.makeInProgress;
+import static org.sonar.db.ce.CeTaskMessageType.INFO;
public class TaskFormatterTest {
private static final String NODE_NAME = "nodeName1";
+ private static final int WARNING_COUNT = 5;
+
@Rule
public DbTester db = DbTester.create(System2.INSTANCE);
- private final int warningCount = new Random().nextInt(10);
-
private final System2 system2 = mock(System2.class);
private final TaskFormatter underTest = new TaskFormatter(db.getDbClient(), system2);
@@ -170,21 +169,11 @@ public class TaskFormatterTest {
}
@Test
- public void formatActivity_throws_NPE_if_warnings_parameter_is_null() {
- UserDto user = db.users().insertUser();
- CeActivityDto dto = newActivity("UUID", "COMPONENT_UUID", CeActivityDto.Status.FAILED, user);
-
- DbSession dbSession = db.getSession();
- assertThatThrownBy(() -> underTest.formatActivity(dbSession, dto, "foo", null))
- .isInstanceOf(NullPointerException.class);
- }
-
- @Test
public void formatActivity() {
UserDto user = db.users().insertUser();
CeActivityDto dto = newActivity("UUID", "COMPONENT_UUID", CeActivityDto.Status.FAILED, user);
- Ce.Task wsTask = underTest.formatActivity(db.getSession(), dto, null, emptyList());
+ Ce.Task wsTask = underTest.formatActivity(db.getSession(), dto, null);
assertThat(wsTask.getType()).isEqualTo(CeTaskTypes.REPORT);
assertThat(wsTask.getId()).isEqualTo("UUID");
@@ -195,7 +184,7 @@ public class TaskFormatterTest {
assertThat(wsTask.getExecutionTimeMs()).isEqualTo(500L);
assertThat(wsTask.getAnalysisId()).isEqualTo("U1");
assertThat(wsTask.hasScannerContext()).isFalse();
- assertThat(wsTask.getWarningCount()).isEqualTo(warningCount);
+ assertThat(wsTask.getWarningCount()).isZero();
assertThat(wsTask.getWarningsList()).isEmpty();
}
@@ -204,21 +193,31 @@ public class TaskFormatterTest {
CeActivityDto dto = newActivity("UUID", "COMPONENT_UUID", CeActivityDto.Status.FAILED, null);
String expected = "scanner context baby!";
- Ce.Task wsTask = underTest.formatActivity(db.getSession(), dto, expected, emptyList());
+ Ce.Task wsTask = underTest.formatActivity(db.getSession(), dto, expected);
assertThat(wsTask.hasScannerContext()).isTrue();
assertThat(wsTask.getScannerContext()).isEqualTo(expected);
}
@Test
- public void formatActivity_set_warnings_list_if_argument_is_non_empty_not_checking_consistency_with_warning_count() {
- CeActivityDto dto = newActivity("UUID", "COMPONENT_UUID", CeActivityDto.Status.FAILED, null);
- String[] warnings = IntStream.range(0, warningCount + 1 + new Random().nextInt(5)).mapToObj(i -> "warning_" + i).toArray(String[]::new);
+ public void formatActivity_filterNonWarnings_andSetMessagesAndCount() {
+ TestActivityDto dto = newActivity("UUID", "COMPONENT_UUID", CeActivityDto.Status.FAILED, null);
+ CeTaskMessageDto warning1 = createCeTaskMessageDto(1998, CeTaskMessageType.GENERIC);
+ CeTaskMessageDto warning2 = createCeTaskMessageDto(1999, CeTaskMessageType.GENERIC);
+
+ List<CeTaskMessageDto> ceTaskMessageDtos = new ArrayList<>(dto.getCeTaskMessageDtos());
+ ceTaskMessageDtos.add(warning1);
+ ceTaskMessageDtos.add(warning2);
+ dto.setCeTaskMessageDtos(ceTaskMessageDtos);
- Ce.Task wsTask = underTest.formatActivity(db.getSession(), dto, null, Arrays.stream(warnings).collect(toList()));
+ Ce.Task wsTask = underTest.formatActivity(db.getSession(), dto, null);
+
+ assertThat(wsTask.getWarningCount()).isEqualTo(2);
+ assertThat(wsTask.getWarningsList()).hasSameElementsAs(getMessagesText(List.of(warning1, warning2)));
+ }
- assertThat(wsTask.getWarningCount()).isEqualTo(warningCount);
- assertThat(wsTask.getWarningsList()).containsExactly(warnings);
+ private static List<String> getMessagesText(List<CeTaskMessageDto> ceTaskMessageDtos) {
+ return ceTaskMessageDtos.stream().map(CeTaskMessageDto::getMessage).toList();
}
@Test
@@ -273,7 +272,7 @@ public class TaskFormatterTest {
assertThat(task.hasErrorStacktrace()).isFalse();
}
- private CeActivityDto newActivity(String taskUuid, String componentUuid, CeActivityDto.Status status, @Nullable UserDto user) {
+ private TestActivityDto newActivity(String taskUuid, String componentUuid, CeActivityDto.Status status, @Nullable UserDto user) {
CeQueueDto queueDto = new CeQueueDto()
.setCreatedAt(1_450_000_000_000L)
.setTaskType(CeTaskTypes.REPORT)
@@ -281,14 +280,27 @@ public class TaskFormatterTest {
.setSubmitterUuid(user == null ? null : user.getUuid())
.setUuid(taskUuid);
TestActivityDto testActivityDto = new TestActivityDto(queueDto);
- testActivityDto.setWarningCount(warningCount);
- return testActivityDto
+
+ List<CeTaskMessageDto> ceTaskMessageDtos = IntStream.range(0, WARNING_COUNT)
+ .mapToObj(i -> createCeTaskMessageDto(i, INFO))
+ .toList();
+ testActivityDto.setCeTaskMessageDtos(ceTaskMessageDtos);
+ return (TestActivityDto) testActivityDto
.setStatus(status)
.setNodeName(NODE_NAME)
.setExecutionTimeMs(500L)
.setAnalysisUuid("U1");
}
+ private CeTaskMessageDto createCeTaskMessageDto(int i, CeTaskMessageType ceTaskMessageType) {
+ CeTaskMessageDto ceTaskMessageDto = new CeTaskMessageDto();
+ ceTaskMessageDto.setMessage("message_" + i);
+ ceTaskMessageDto.setCreatedAt(system2.now());
+ ceTaskMessageDto.setTaskUuid("uuid_" + i);
+ ceTaskMessageDto.setType(ceTaskMessageType);
+ return ceTaskMessageDto;
+ }
+
private static class TestActivityDto extends CeActivityDto {
public TestActivityDto(CeQueueDto queueDto) {
@@ -301,8 +313,8 @@ public class TaskFormatterTest {
}
@Override
- public CeActivityDto setWarningCount(int warningCount) {
- return super.setWarningCount(warningCount);
+ public CeActivityDto setCeTaskMessageDtos(List<CeTaskMessageDto> ceTaskMessageDtos) {
+ return super.setCeTaskMessageDtos(ceTaskMessageDtos);
}
}
}