aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLéo Geoffroy <99647462+leo-geoffroy-sonarsource@users.noreply.github.com>2022-11-29 11:41:09 +0100
committersonartech <sonartech@sonarsource.com>2022-12-01 20:03:12 +0000
commit89369349a6cc93f8bb5ea04cc0b568d932897447 (patch)
tree4448b743fc98c86e744e6ae0186bcbbed5277395
parent1f5842ee24c4b544acb2c8dea81754809e70dab9 (diff)
downloadsonarqube-89369349a6cc93f8bb5ea04cc0b568d932897447.tar.gz
sonarqube-89369349a6cc93f8bb5ea04cc0b568d932897447.zip
SONAR-17592 - Add support for message formattings in import and export
-rw-r--r--server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectexport/issue/ExportIssuesStep.java31
-rw-r--r--server/sonar-ce-task-projectanalysis/src/main/protobuf/project_dump.proto12
-rw-r--r--server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectexport/issue/ExportIssuesStepTest.java32
3 files changed, 66 insertions, 9 deletions
diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectexport/issue/ExportIssuesStep.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectexport/issue/ExportIssuesStep.java
index b34a38d220b..9461e12016d 100644
--- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectexport/issue/ExportIssuesStep.java
+++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectexport/issue/ExportIssuesStep.java
@@ -19,14 +19,17 @@
*/
package org.sonar.ce.task.projectexport.issue;
+import com.google.common.annotations.VisibleForTesting;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.sonarsource.governance.projectdump.protobuf.ProjectDump;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
+import java.util.List;
import java.util.Objects;
import java.util.Optional;
+import java.util.stream.Collectors;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.utils.log.Loggers;
import org.sonar.ce.task.projectexport.component.ComponentRepository;
@@ -58,7 +61,7 @@ public class ExportIssuesStep implements ComputationStep {
" i.resolution, i.severity, i.manual_severity, i.gap, effort," +
" i.assignee, i.author_login, i.tags, i.issue_creation_date," +
" i.issue_update_date, i.issue_close_date, i.locations, i.project_uuid," +
- " i.rule_description_context_key " +
+ " i.rule_description_context_key, i.message_formattings " +
" from issues i" +
" join rules r on r.uuid = i.rule_uuid and r.status <> ?" +
" join components p on p.uuid = i.project_uuid" +
@@ -148,6 +151,7 @@ public class ExportIssuesStep implements ComputationStep {
.setProjectUuid(rs.getString(23));
Optional.ofNullable(rs.getString(24)).ifPresent(builder::setRuleDescriptionContextKey);
setLocations(builder, rs, issueUuid);
+ setMessageFormattings(builder, rs, issueUuid);
return builder.build();
}
@@ -171,6 +175,31 @@ public class ExportIssuesStep implements ComputationStep {
}
}
+ private static void setMessageFormattings(ProjectDump.Issue.Builder builder, ResultSet rs, String issueUuid) throws SQLException {
+ try {
+ byte[] bytes = rs.getBytes(25);
+ if (bytes != null) {
+ // fail fast, ensure we can read data from DB
+ DbIssues.MessageFormattings messageFormattings = DbIssues.MessageFormattings.parseFrom(bytes);
+ if (messageFormattings != null) {
+ builder.addAllMessageFormattings(dbToDumpMessageFormatting(messageFormattings.getMessageFormattingList()));
+ }
+ }
+ } catch (InvalidProtocolBufferException e) {
+ throw new IllegalStateException(format("Fail to read message formattings from DB for issue %s", issueUuid), e);
+ }
+ }
+
+ @VisibleForTesting
+ static List<ProjectDump.MessageFormatting> dbToDumpMessageFormatting(List<DbIssues.MessageFormatting> messageFormattingList) {
+ return messageFormattingList.stream()
+ .map(e -> ProjectDump.MessageFormatting.newBuilder()
+ .setStart(e.getStart())
+ .setEnd(e.getEnd())
+ .setType(ProjectDump.MessageFormattingType.valueOf(e.getType().name())).build())
+ .collect(Collectors.toList());
+ }
+
private static class RuleRegistrar {
private final RuleRepository ruleRepository;
private Rule previousRule = null;
diff --git a/server/sonar-ce-task-projectanalysis/src/main/protobuf/project_dump.proto b/server/sonar-ce-task-projectanalysis/src/main/protobuf/project_dump.proto
index b1e5066d8fe..2623f5ce877 100644
--- a/server/sonar-ce-task-projectanalysis/src/main/protobuf/project_dump.proto
+++ b/server/sonar-ce-task-projectanalysis/src/main/protobuf/project_dump.proto
@@ -123,6 +123,8 @@ message Issue {
string rule_ref = 23;
optional string ruleDescriptionContextKey = 24;
+
+ repeated MessageFormatting messageFormattings = 25;
}
// Stream of issues changelog stored in file issues_changelog.pb
@@ -218,3 +220,13 @@ message NewCodePeriod {
int64 created_at = 6;
int64 updated_at = 7;
}
+
+message MessageFormatting {
+ int32 start = 1;
+ int32 end = 2;
+ MessageFormattingType type = 3;
+}
+
+enum MessageFormattingType {
+ CODE = 0;
+}
diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectexport/issue/ExportIssuesStepTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectexport/issue/ExportIssuesStepTest.java
index 03136fac933..cb88189219f 100644
--- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectexport/issue/ExportIssuesStepTest.java
+++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectexport/issue/ExportIssuesStepTest.java
@@ -19,6 +19,7 @@
*/
package org.sonar.ce.task.projectexport.issue;
+import com.google.protobuf.InvalidProtocolBufferException;
import com.sonarsource.governance.projectdump.protobuf.ProjectDump;
import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
@@ -58,6 +59,7 @@ import org.sonar.db.issue.IssueDto;
import org.sonar.db.project.ProjectDto;
import org.sonar.db.protobuf.DbIssues;
import org.sonar.db.protobuf.DbIssues.Locations;
+import org.sonar.db.protobuf.DbIssues.MessageFormattingType;
import org.sonar.db.rule.RuleDto;
import org.sonar.db.rule.RuleDto.Scope;
@@ -77,6 +79,7 @@ public class ExportIssuesStepTest {
private static final String PROJECT_KEY = "projectkey";
private static final String SOME_REPO = "rule repo";
private static final String READY_RULE_KEY = "rule key 1";
+ public static final DbIssues.MessageFormatting MESSAGE_FORMATTING = DbIssues.MessageFormatting.newBuilder().setStart(0).setEnd(4).setType(MessageFormattingType.CODE).build();
@Rule
public DbTester dbTester = DbTester.create(System2.INSTANCE);
@@ -200,15 +203,17 @@ public class ExportIssuesStepTest {
}
@Test
- public void verify_field_by_field_mapping() {
+ public void verify_field_by_field_mapping() throws InvalidProtocolBufferException {
String componentUuid = "component uuid";
long componentRef = 5454;
componentRepository.register(componentRef, componentUuid, false);
+ DbIssues.MessageFormattings messageFormattings = DbIssues.MessageFormattings.newBuilder().addMessageFormatting(MESSAGE_FORMATTING).build();
IssueDto issueDto = new IssueDto()
.setKee("issue uuid")
.setComponentUuid(componentUuid)
.setType(988)
.setMessage("msg")
+ .setMessageFormattings(messageFormattings)
.setLine(10)
.setChecksum("checksum")
.setResolution("resolution")
@@ -257,6 +262,8 @@ public class ExportIssuesStepTest {
assertThat(issue.getIssueUpdatedAt()).isEqualTo(issueDto.getIssueUpdateTime());
assertThat(issue.getIssueClosedAt()).isEqualTo(issueDto.getIssueCloseTime());
assertThat(issue.getLocations()).isNotEmpty();
+ assertThat(issue.getMessageFormattingsList())
+ .isEqualTo(ExportIssuesStep.dbToDumpMessageFormatting(messageFormattings.getMessageFormattingList()));
}
@Test
@@ -298,6 +305,15 @@ public class ExportIssuesStepTest {
}
@Test
+ public void message_formattings_is_empty_in_protobuf_if_null_in_DB() {
+ insertIssue(readyRuleDto, SOME_PROJECT_UUID, STATUS_OPEN);
+
+ underTest.execute(new TestComputationStepContext());
+
+ assertThat(getWrittenIssue().getMessageFormattingsList()).isEmpty();
+ }
+
+ @Test
public void execute_fails_with_ISE_if_locations_cannot_be_parsed_to_protobuf() throws URISyntaxException, IOException {
byte[] rubbishBytes = getRubbishBytes();
String uuid = insertIssue(createBaseIssueDto(readyRuleDto, SOME_PROJECT_UUID).setLocations(rubbishBytes)).getKey();
@@ -337,14 +353,14 @@ public class ExportIssuesStepTest {
return dumpWriter.getWrittenMessagesOf(DumpElement.ISSUES).get(0);
}
-// private void expectExportFailure() {
-// expectExportFailure(0);
-// }
+ // private void expectExportFailure() {
+ // expectExportFailure(0);
+ // }
-// private void expectExportFailure(int i) {
-// expectedException.expect(IllegalStateException.class);
-// expectedException.expectMessage("Issue export failed after processing " + i + " issues successfully");
-// }
+ // private void expectExportFailure(int i) {
+ // expectedException.expect(IllegalStateException.class);
+ // expectedException.expectMessage("Issue export failed after processing " + i + " issues successfully");
+ // }
private int issueUuidGenerator = 1;