Tuesday, November 24, 2020

Create Sonar Plugin - Scanner Basic

 Scanner is the main functionality of the sonar plugin. All the analysis is done here. As we are using third party tool to analyze our foo language files, we are getting the result of the analysis as a XML or JSON report depending on the situation.

  • So we have few key things
  • Call third party app -  executable Jar
  • Get the analysis report
  • Then read the XML/JSON report and convert to JAVA/POJO
  • Create input files with issues we have collected
  • save those issues to show them in dashboard, SonarQube


  1.  Scanner implements org.sonar.api.batch.sensor.Sensor;
  2. We have two contracts. describe and execute
    1. describe - set Key and Name for our foo language
    2. define the flow of analysis to show the analysis in dashboard
  3. To do our work , we need SensorContext, Filesystem and extractor
    1. org.sonar.api.batch.sensor.SensorContext
      1. to retrieve parameter details we need to run - parameters and values
    2. org.sonar.api.batch.fs.FileSystem
    3. File system has the information of base directory and files used to analyze(name, absolute path, relative path...)
    4. Extractor

    5. Extractor is used to extract third party tool/jar and other related files need for do the analysis 

4. Execute is the main functionality - where all happens

Basically we have divided to three parts

  • setting the context
  • Analyse
  • save Issues

Analyse  - we call the third party app/jar and get the results of the analysis. To call the the jar, we need to make the command with parameters attached.

After the analysis done, we have the results - violations

Then in save issues, we convert them back to POJO and save and show in  the dashboard.


-----------------------------------------------------------------------------------------------


package com.plugin.sonar.scanner;

import com.plugin.sonar.report.foo.Violation;
import com.plugin.sonar.report.foo.Violations;
import com.plugin.sonar.util.Converter;
import com.plugin.sonar.util.Extractor;
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.sensor.Sensor;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.SensorDescriptor;
import org.sonar.api.batch.sensor.issue.NewIssue;
import org.sonar.api.batch.sensor.issue.NewIssueLocation;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.utils.command.Command;
import org.sonar.api.utils.command.CommandExecutor;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;

import java.io.File;
import java.util.Objects;

import static com.plugin.sonar.util.FooConstants.*;

public class FooScanner implements Sensor {

private static final Logger LOG = Loggers.get(FooScanner.class);
private FileSystem fileSystem;
private Extractor extractor;

private SensorContext context;

public FooScanner(final FileSystem fileSystem, final Extractor extractor) {
this.fileSystem = fileSystem;
LOG.debug("Inside PlsqlScanner::Constructor::fileSystem=" + fileSystem);
this.extractor = extractor;
}

@Override
public void describe(SensorDescriptor sensorDescriptor) {
sensorDescriptor.name(LANGUAGE_NAME);
sensorDescriptor.onlyOnLanguages(LANGUAGE_KEY);
}

@Override
public void execute(SensorContext sensorContext) {
LOG.info("executing plsql sensor");
this.context = sensorContext;
LOG.info("start Pl/SQL analysing");
analyze();
LOG.info("executing Pl/SQL sensor: analyze completed.");
saveIssues();
LOG.info("executing Pl/SQL sensor: save issues completed.");
}

private void saveIssues() {
// for each violation we have got,
            // get Input file and save issue for file name / file absolute path
}

private void getResourceAndSaveIssue(final Violation violation, String fileName) {
        // get the Input file from file system
        // save issue with input file using details from the XML/JSON report

}

private void saveIssue(final InputFile inputFile, int line, final String externalRuleKey, final String message) {
//get rule key for file analysed
        // create new issue in context using rule key
        // save issue
}

private Violations getReport() {
// convert XML report to POJO
}

private static String getRepositoryKeyForLanguage(String languageKey) {
return languageKey.toLowerCase() + "-" + LANGUAGE_KEY;
}


private void analyze() {
        // create command to execute jar
        // execute the command


}
}

No comments:

Post a Comment