diff options
author | Duarte Meneses <duarte.meneses@sonarsource.com> | 2015-08-03 17:47:20 +0200 |
---|---|---|
committer | Duarte Meneses <duarte.meneses@sonarsource.com> | 2015-08-04 08:56:01 +0200 |
commit | b73fcc97d7e963a87766808b18db4d101c64ffd1 (patch) | |
tree | 7857db461ea5fdb786b364942d40e3393b55efaf /sonar-batch | |
parent | e39b1ab39d3854fbb6266d8a9048a152ee54fdb6 (diff) | |
download | sonarqube-b73fcc97d7e963a87766808b18db4d101c64ffd1.tar.gz sonarqube-b73fcc97d7e963a87766808b18db4d101c64ffd1.zip |
SONAR-6750 Support new SQ Runner API for retrieving issues
Diffstat (limited to 'sonar-batch')
7 files changed, 267 insertions, 29 deletions
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/IssueListener.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/IssueListener.java index a8369b04574..b2bf0fd57aa 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/IssueListener.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/IssueListener.java @@ -19,8 +19,117 @@ */ package org.sonar.batch.bootstrapper; -import org.sonar.api.issue.Issue; - public interface IssueListener { void handle(Issue issue); + + class Issue { + private String key; + private String componentKey; + private Integer line; + private String message; + private String ruleKey; + private String ruleName; + private String status; + private String resolution; + private boolean isNew; + private String assigneeLogin; + private String assigneeName; + private String severity; + + public String getSeverity() { + return severity; + } + + public void setSeverity(String severity) { + this.severity = severity; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getComponentKey() { + return componentKey; + } + + public void setComponentKey(String componentKey) { + this.componentKey = componentKey; + } + + public Integer getLine() { + return line; + } + + public void setLine(Integer line) { + this.line = line; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getRuleKey() { + return ruleKey; + } + + public void setRuleKey(String ruleKey) { + this.ruleKey = ruleKey; + } + + public String getRuleName() { + return ruleName; + } + + public void setRuleName(String ruleName) { + this.ruleName = ruleName; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getResolution() { + return resolution; + } + + public void setResolution(String resolution) { + this.resolution = resolution; + } + + public boolean isNew() { + return isNew; + } + + public void setNew(boolean isNew) { + this.isNew = isNew; + } + + public String getAssigneeLogin() { + return assigneeLogin; + } + + public void setAssigneeLogin(String assigneeLogin) { + this.assigneeLogin = assigneeLogin; + } + + public String getAssigneeName() { + return assigneeName; + } + + public void setAssigneeName(String assigneeName) { + this.assigneeName = assigneeName; + } + } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/DefaultIssueCallback.java b/sonar-batch/src/main/java/org/sonar/batch/issue/DefaultIssueCallback.java index f148ebf9992..d4284f44e47 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/issue/DefaultIssueCallback.java +++ b/sonar-batch/src/main/java/org/sonar/batch/issue/DefaultIssueCallback.java @@ -19,24 +19,44 @@ */ package org.sonar.batch.issue; -import org.sonar.batch.bootstrapper.IssueListener; +import org.sonar.api.rule.RuleKey; +import org.sonar.api.batch.rule.Rule; +import org.sonar.api.batch.rule.Rules; +import org.sonar.batch.protocol.input.BatchInput.User; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import org.sonar.batch.repository.user.UserRepository; +import org.sonar.batch.bootstrapper.IssueListener; import org.sonar.core.issue.DefaultIssue; public class DefaultIssueCallback implements IssueCallback { private final IssueCache issues; private final IssueListener listener; + private final UserRepository userRepository; + private final Rules rules; - public DefaultIssueCallback(IssueCache issues, IssueListener listener) { + private Set<String> userLoginNames = new HashSet<>(); + private Map<String, String> userMap = new HashMap<>(); + private Set<RuleKey> ruleKeys = new HashSet<>(); + + public DefaultIssueCallback(IssueCache issues, IssueListener listener, UserRepository userRepository, Rules rules) { this.issues = issues; this.listener = listener; + this.userRepository = userRepository; + this.rules = rules; } /** * If no listener exists, this constructor will be used by pico. */ - public DefaultIssueCallback(IssueCache issues) { - this(issues, null); + public DefaultIssueCallback(IssueCache issues, UserRepository userRepository, Rules rules) { + this(issues, null, userRepository, rules); } @Override @@ -46,7 +66,52 @@ public class DefaultIssueCallback implements IssueCallback { } for (DefaultIssue issue : issues.all()) { - listener.handle(issue); + collectInfo(issue); + } + + getUsers(); + + for (DefaultIssue issue : issues.all()) { + IssueListener.Issue newIssue = new IssueListener.Issue(); + newIssue.setAssigneeLogin(issue.assignee()); + newIssue.setAssigneeName(getAssigneeName(issue.assignee())); + newIssue.setComponentKey(issue.componentKey()); + newIssue.setKey(issue.key()); + newIssue.setLine(issue.getLine()); + newIssue.setMessage(issue.getMessage()); + newIssue.setNew(issue.isNew()); + newIssue.setResolution(issue.resolution()); + newIssue.setRuleKey(issue.getRuleKey().rule()); + newIssue.setRuleName(getRuleName(issue.getRuleKey())); + newIssue.setSeverity(issue.severity()); + newIssue.setStatus(issue.status()); + + listener.handle(newIssue); + } + } + + private void collectInfo(DefaultIssue issue) { + if (issue.assignee() != null) { + userLoginNames.add(issue.assignee()); + } + if (issue.getRuleKey() != null) { + ruleKeys.add(issue.getRuleKey()); + } + } + + private String getAssigneeName(String login) { + return userMap.get(login); + } + + private void getUsers() { + Collection<User> users = userRepository.loadFromWs(new ArrayList<>(userLoginNames)); + for (User user : users) { + userMap.put(user.getLogin(), user.getName()); } } + + private String getRuleName(RuleKey ruleKey) { + Rule rule = rules.find(ruleKey); + return rule != null ? rule.name() : null; + } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/repository/user/UserRepository.java b/sonar-batch/src/main/java/org/sonar/batch/repository/user/UserRepository.java index a01f86d5ed7..a0e4c781290 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/repository/user/UserRepository.java +++ b/sonar-batch/src/main/java/org/sonar/batch/repository/user/UserRepository.java @@ -46,7 +46,7 @@ public class UserRepository { public UserRepository(WSLoader wsLoader) { this.wsLoader = wsLoader; } - + public Collection<BatchInput.User> loadFromWs(List<String> userLogins) { if (userLogins.isEmpty()) { return Collections.emptyList(); diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssueCallbackTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssueCallbackTest.java index 1acdd57cf4f..1ecf5353fab 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssueCallbackTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssueCallbackTest.java @@ -21,41 +21,69 @@ package org.sonar.batch.issue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import org.sonar.api.batch.rule.Rule; +import org.sonar.api.rule.RuleKey; +import org.sonar.batch.bootstrapper.IssueListener.Issue; +import org.sonar.batch.protocol.input.BatchInput; +import org.mockito.MockitoAnnotations; +import org.mockito.Mock; +import org.sonar.api.batch.rule.Rules; +import org.sonar.batch.repository.user.UserRepository; import org.sonar.batch.bootstrapper.IssueListener; import org.junit.Before; import com.google.common.collect.ImmutableList; import org.sonar.core.issue.DefaultIssue; -import org.sonar.api.issue.Issue; import java.util.LinkedList; import java.util.List; -import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyListOf; +import static org.assertj.core.api.Assertions.assertThat; import org.junit.Test; public class DefaultIssueCallbackTest { + @Mock private IssueCache issueCache; + @Mock + private UserRepository userRepository; + @Mock + private Rules rules; + private DefaultIssue issue; @Before public void setUp() { + MockitoAnnotations.initMocks(this); + + RuleKey ruleKey = RuleKey.of("repo", "key"); issue = new DefaultIssue(); issue.setKey("key"); + issue.setAssignee("user"); + issue.setRuleKey(ruleKey); - issueCache = mock(IssueCache.class); when(issueCache.all()).thenReturn(ImmutableList.of(issue)); + + BatchInput.User.Builder userBuilder = BatchInput.User.newBuilder(); + userBuilder.setLogin("user"); + userBuilder.setName("name"); + when(userRepository.loadFromWs(anyListOf(String.class))).thenReturn(ImmutableList.of(userBuilder.build())); + + Rule r = mock(Rule.class); + when(r.name()).thenReturn("rule name"); + when(rules.find(ruleKey)).thenReturn(r); } @Test public void testWithoutListener() { - DefaultIssueCallback issueCallback = new DefaultIssueCallback(issueCache); + DefaultIssueCallback issueCallback = new DefaultIssueCallback(issueCache, userRepository, rules); issueCallback.execute(); } @Test public void testWithListener() { - final List<Issue> issueList = new LinkedList<>(); + final List<IssueListener.Issue> issueList = new LinkedList<>(); IssueListener listener = new IssueListener() { @Override public void handle(Issue issue) { @@ -63,10 +91,47 @@ public class DefaultIssueCallbackTest { } }; - DefaultIssueCallback issueCallback = new DefaultIssueCallback(issueCache, listener); + DefaultIssueCallback issueCallback = new DefaultIssueCallback(issueCache, listener, userRepository, rules); issueCallback.execute(); - - assertThat(issueList).containsExactly(issue); + + assertThat(issueList).hasSize(1); + Issue callbackIssue = issueList.get(0); + + assertThat(callbackIssue.getAssigneeName()).isEqualTo("name"); + assertThat(callbackIssue.getRuleName()).isEqualTo("rule name"); } + @Test + public void testWithNulls() { + final List<IssueListener.Issue> issueList = new LinkedList<>(); + IssueListener listener = new IssueListener() { + @Override + public void handle(Issue issue) { + issueList.add(issue); + } + }; + + issue.setKey(null); + issue.setAssignee(null); + + DefaultIssueCallback issueCallback = new DefaultIssueCallback(issueCache, listener, userRepository, rules); + issueCallback.execute(); + } + + @Test + public void testDecorationNotFound() { + final List<IssueListener.Issue> issueList = new LinkedList<>(); + IssueListener listener = new IssueListener() { + @Override + public void handle(Issue issue) { + issueList.add(issue); + } + }; + + when(userRepository.loadFromWs(anyListOf(String.class))).thenReturn(new LinkedList<BatchInput.User>()); + when(rules.find(any(RuleKey.class))).thenReturn(null); + + DefaultIssueCallback issueCallback = new DefaultIssueCallback(issueCache, listener, userRepository, rules); + issueCallback.execute(); + } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java index 6979b4e6e2c..928c17dd47e 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java @@ -103,7 +103,7 @@ public class IssuesMediumTest { .start(); List<Issue> issues = result.issuesFor(result.inputFile("xources/hello/HelloJava.xoo")); - assertThat(issues).hasSize(8 /* lines */ + 1 /* file */); + assertThat(issues).hasSize(8 /* lines */+ 1 /* file */); } @Test @@ -174,10 +174,10 @@ public class IssuesMediumTest { } private class IssueRecorder implements IssueListener { - List<org.sonar.api.issue.Issue> issueList = new LinkedList<>(); + List<Issue> issueList = new LinkedList<>(); @Override - public void handle(org.sonar.api.issue.Issue issue) { + public void handle(Issue issue) { issueList.add(issue); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesPreviewMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesPreviewMediumTest.java index 6177d158ef0..e1f96fa0e74 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesPreviewMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesPreviewMediumTest.java @@ -75,27 +75,26 @@ public class IssuesPreviewMediumTest { .setIssueListener(issueListener) .property(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_PREVIEW) .start(); - + assertThat(result1.trackedIssues()).hasSize(14); assertThat(issueListener.issueList).hasSize(14); issueListener = new IssueRecorder(); - + TaskResult result2 = testerPreview .newScanTask(new File(tmpDir, "sonar-project.properties")) .setIssueListener(issueListener) .property(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_PREVIEW) .start(); - - + assertThat(result2.trackedIssues()).hasSize(28); assertThat(issueListener.issueList).hasSize(28); } private class IssueRecorder implements IssueListener { - List<org.sonar.api.issue.Issue> issueList = new LinkedList<>(); + List<Issue> issueList = new LinkedList<>(); @Override - public void handle(org.sonar.api.issue.Issue issue) { + public void handle(Issue issue) { issueList.add(issue); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/PreviewAndReportsMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/PreviewAndReportsMediumTest.java index a966d85e3c4..fa324d08bf7 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/PreviewAndReportsMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/PreviewAndReportsMediumTest.java @@ -20,12 +20,14 @@ package org.sonar.batch.mediumtest.preview; import com.google.common.collect.ImmutableMap; + import java.io.File; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.LinkedList; import java.util.List; + import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.io.FileUtils; import org.apache.commons.io.filefilter.FileFilterUtils; @@ -45,7 +47,6 @@ import org.sonar.batch.protocol.input.ActiveRule; import org.sonar.batch.scan.report.ConsoleReport; import org.sonar.xoo.XooPlugin; import org.sonar.xoo.rule.XooRulesDefinition; - import static org.assertj.core.api.Assertions.assertThat; public class PreviewAndReportsMediumTest { @@ -250,14 +251,13 @@ public class PreviewAndReportsMediumTest { assertThat(result.trackedIssues()).hasSize(20); assertThat(issueListener.issueList).hasSize(20); - assertThat(result.trackedIssues()).containsExactlyElementsOf(issueListener.issueList); } private class IssueRecorder implements IssueListener { - List<org.sonar.api.issue.Issue> issueList = new LinkedList<>(); + List<Issue> issueList = new LinkedList<>(); @Override - public void handle(org.sonar.api.issue.Issue issue) { + public void handle(Issue issue) { issueList.add(issue); } } |