]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6750 Support new SQ Runner API for retrieving issues
authorDuarte Meneses <duarte.meneses@sonarsource.com>
Mon, 3 Aug 2015 15:47:20 +0000 (17:47 +0200)
committerDuarte Meneses <duarte.meneses@sonarsource.com>
Tue, 4 Aug 2015 06:56:01 +0000 (08:56 +0200)
sonar-batch/src/main/java/org/sonar/batch/bootstrapper/IssueListener.java
sonar-batch/src/main/java/org/sonar/batch/issue/DefaultIssueCallback.java
sonar-batch/src/main/java/org/sonar/batch/repository/user/UserRepository.java
sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssueCallbackTest.java
sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java
sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesPreviewMediumTest.java
sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/PreviewAndReportsMediumTest.java

index a8369b045749833929633941e7a78be4c410ed15..b2bf0fd57aa9434dea943920aa87f02985a2711b 100644 (file)
  */
 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;
+    }
+  }
 }
index f148ebf9992a17dca2e2c2e0f5153e91925c981c..d4284f44e479cc51c22bd4333e962abff794347c 100644 (file)
  */
 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;
+  }
 }
index a01f86d5ed7f9e60b0512e4455c45f5bf696d656..a0e4c781290fe9966fee0227ad716180aa6e323f 100644 (file)
@@ -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();
index 1acdd57cf4fb292d0d30fdbf9d00051183fdef28..1ecf5353fabfa384ac367f4a870c2ea65ec59ddb 100644 (file)
@@ -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();
+  }
 }
index 6979b4e6e2cfc14a67fe95c22df552c7c550751f..928c17dd47e8c60b87fef5d299f79b037dc0ca8d 100644 (file)
@@ -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);
     }
   }
index 6177d158ef0ec369e50e1e3045466c4e63766c0b..e1f96fa0e740cc08592a54eb44ac1f973a52df4c 100644 (file)
@@ -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);
     }
   }
index a966d85e3c4e067e8a8b17f5c49c1132e90210df..fa324d08bf7ce4da493342b0cd54b4fe561616d7 100644 (file)
 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);
     }
   }