Skip to end of metadata
Go to start of metadata

Use Cases

Hooks allow SonarQube to notify external applications when a project analysis is completed. Many use cases can benefit from that. Here are some examples.

Analysis of Pull Requests

The new issues on touched code are sent as comments on the pull request. The status of pull request can also be changed.

Blogs: how it helps to fix the leak and how it is used at Microsoft with VSTS

Examples: GitHub and Bitbucket plugins 

IRC Notification

An IRC channel is notified when a Quality gate fails. Developers can take immediate actions to Clean as They Code, by fixing new problems immediately.

Example in HipChat (plugin not released at the time of writing):

Continuous Delivery

You could imagine that SonarQube is involved in the build pipeline, for example by stopping the deployment of artifacts if Quality Gate does not succeed.  

Architecture

Implementing hooks requires an understanding of the architecture. As described in API Basics SonarQube is composed of three stacks since version 5.2. Analysing a project traverses two of these stacks:

  • Scanner parses source code, detects issues and computes raw measures (ncloc for instance). A report is generated and sent to web server.
  • Compute Engine, which is a process hosted within web server, processes the scanner report and finalizes the project analysis.

Scanner does not wait for the end of analysis by Compute Engine. It stops as soon as its report is sent.

This split of stacks implies that:

  • Scanner generates only raw measures only such as the number of lines of code on a file. It does not know the total number of lines of code on the project.
  • Scanner does not consolidate data (measures, issues, duplications, coverage details, SCM blame). It does not need to access and use the generated raw data. 
  • Scanner does not access Quality gate: it does not load thresholds and does not compute gate status.

  • By default, scanner does not match issues with the issues of previous analysis. That means that advanced data is unknown: creation date, assignee, effective severity (if it was changed by user), changelog, comments, effective tags, status (marked as false-positive for instance).

Extension Points

Plugins can implement two different types of hooks :

  • when the scanner sends the raw report to Compute Engine. The extension point org.sonar.api.batch.postjob.PostJob must be implemented. Measures and Quality gate can not be accessed.The GitHub and Bitbucket plugins rely on this extension point.
  • when Compute Engine finishes analysis. The extension point org.sonar.api.ce.posttask.PostProjectAnalysisTask must be implemented. It has access to Quality gates, including status and thresholds. It is used for instance by the HipChat plugin. Note that currently only project metadata (key/name) and Quality gate are available. Extensions can not access measures or issues. The hook can't generate a dozens-of-pages long email with details of all issues on all files.

Breaking Change in Version 5.2

Version 5.2 brought a major technological change. Previously scanners accessed the database directly, so the responsibilities of the Compute Engine were handled by the scanner itself. That allowed scanner hooks, through Decorator or PostJob extension points, to access final data, including Quality gate status and issues.

Dropping the access to the database from scanners was the most-voted improvement at that time. Such access was a pain to configure, a production vulnerability (write permission required for scanner), and a performance issue. The scanner was slow, was a resource consumer, and was an obstacle for delivering SonarLint

For technical reasons the compatibility with org.sonar.api.batch.Decorator was not kept. Moreover the scope of data available to PostJob was reduced as described in the previous sections.

Web Server URL

As you can see in the HipChat screenshot above, the project name links to the project homepage in SonarQube. The base URL of web server can be loaded by extensions through the core component org.sonar.api.platform.Server

MyHook.java
import org.sonar.api.ce.posttask.PostProjectAnalysisTask;
import org.sonar.api.server.Server;
 
public class MyHook implements PostProjectAnalysisTask {
  private final Server server;

  public MyHook(Server server) {
    this.server = server;
  }

  @Override
  public void finished(ProjectAnalysis analysis) {
    QualityGate gate = analysis.getQualityGate();
    if (gate.getStatus()== QualityGate.Status.ERROR) {
      String baseUrl = server.getURL();
      // TODO send notification
    }
  }

 

 

  • No labels