diff options
author | Léo Geoffroy <99647462+leo-geoffroy-sonarsource@users.noreply.github.com> | 2022-11-29 11:41:09 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2022-12-01 20:03:12 +0000 |
commit | 89369349a6cc93f8bb5ea04cc0b568d932897447 (patch) | |
tree | 4448b743fc98c86e744e6ae0186bcbbed5277395 | |
parent | 1f5842ee24c4b544acb2c8dea81754809e70dab9 (diff) | |
download | sonarqube-89369349a6cc93f8bb5ea04cc0b568d932897447.tar.gz sonarqube-89369349a6cc93f8bb5ea04cc0b568d932897447.zip |
SONAR-17592 - Add support for message formattings in import and export
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; |