All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.viae.maven.sonar.mojos.SonarGitBranchDeletionSyncMojo Maven / Gradle / Ivy

The newest version!
package com.viae.maven.sonar.mojos;

import com.viae.maven.sonar.config.SonarStrings;
import com.viae.maven.sonar.exceptions.SonarQualityException;
import com.viae.maven.sonar.utils.JsonUtil;
import com.viae.maven.sonar.utils.SpecialCharacterUtil;
import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.sonar.wsclient.SonarClient;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;
import java.util.stream.Collectors;

/**
 * MOJO to check whether a given git branch still exists: if not, the corresponding SONAR project will be deleted.
 * 

* TODO: clean up code + tests * * @author by Maarten on 25/09/2016. */ @Mojo(name = SonarStrings.MOJO_NAME_SYNC_GIT_REPO, aggregator = true) public class SonarGitBranchDeletionSyncMojo extends AbstractMojo { public static final String DELETE_PROJECT_URL = "/api/projects/"; @Parameter(property = SonarStrings.SERVER, required = true) protected String sonarServer; @Parameter(property = SonarStrings.LOGIN, required = true) protected String sonarUser; @Parameter(property = SonarStrings.PASSWORD, required = true) protected String sonarPassword; @Parameter(property = SonarStrings.REPO_LOGIN, required = true) protected String repoUser; @Parameter(property = SonarStrings.REPO_PASSWORD, required = true) protected String repoPassword; @Parameter(property = SonarStrings.REPO_CONFIGURATION, required = true) protected Map sonarRepoConfigurations; /** * Validate a project against a given quality gate. * * @throws MojoExecutionException will not be thrown. * @throws MojoFailureException will be thrown when the quality gate is not met by the given project. */ @Override public void execute() throws MojoExecutionException, MojoFailureException { getLog().info( String.format( "%s start execution of '%s' for repositories:\n%s", SonarStrings.LOG_PREFIX, SonarStrings.MOJO_NAME_SYNC_GIT_REPO, sonarRepoConfigurations ) ); try { sonarRepoConfigurations.forEach( this::deleteNotExistingBranches ); } catch ( Exception e ) { getLog().error( String.format( "%s %s", SonarStrings.LOG_PREFIX, e.getLocalizedMessage() ) ); throw new RuntimeException( String.format( "%s %s\ncause:\n%s", SonarStrings.LOG_PREFIX, e.getLocalizedMessage(), ExceptionUtils.getStackTrace( e ) ) , e ); } } private void deleteNotExistingBranches( final String projectNameArg, final String repoRootUrl ) { getLog().info( String.format( "%s deleteNotExistingBranches for '%s'", SonarStrings.LOG_PREFIX, projectNameArg ) ); final String projectName = projectNameArg.replaceAll( "---", ":" ); try { final SonarClient client = SonarClient.builder() .url( sonarServer ) .login( sonarUser ) .password( sonarPassword ) .build(); final Set existingRepoBranches = getExistingBranches( repoRootUrl ); final Map sonarBranches = getSonarBranches( projectName, client ); List toDelete = sonarBranches.keySet().stream().filter( sonarBranchName -> !existingRepoBranches.contains( sonarBranchName ) ).collect( Collectors.toList() ); getLog().info( String.format( "%s branches to delete for: %s:\n%s", SonarStrings.LOG_PREFIX, projectName, toDelete ) ); int toDeleteSize = toDelete.size(); int index = 0; for ( String branchName : toDelete ) { String id = sonarBranches.get( branchName ).getId(); String serverOutput = doDelete( String.format( "%s%s%s", "http://sonar.projects.foreach.be", DELETE_PROJECT_URL, id ), sonarUser, sonarPassword ); getLog().info( String.format( "%s Got server output for project %s/%s: \n%s", SonarStrings.LOG_PREFIX, serverOutput, index++, toDeleteSize ) ); } } catch ( final SonarQualityException e ) { getLog().error( String.format( "%s %s", SonarStrings.LOG_PREFIX, e.getLocalizedMessage() ) ); throw new RuntimeException( e ); } } private Map getSonarBranches( final String projectName, final SonarClient client ) throws SonarQualityException { final Map sonarBranches = new ConcurrentHashMap(); String sonarResult = client.get( "/api/projects?format=json" ); JSONArray sonarResultArray = JsonUtil.parseArray( sonarResult ); sonarResultArray.stream().forEach( project -> { String id = ( (JSONObject) project ).get( "id" ).toString(); String projectKey = ( (JSONObject) project ).get( "k" ).toString(); if ( projectKey.startsWith( projectName ) ) { String branchName = Optional.ofNullable( projectKey ).orElse( "" ).replace( String.format( "%s:", projectName ), "" ); sonarBranches.put( branchName, new BranchMetaData( id, projectKey ) ); } } ); return sonarBranches; } private Set getExistingBranches( final String repoRootUrl ) throws SonarQualityException { final Set existingBranches = new HashSet<>(); String json = doGet( repoRootUrl, repoUser, repoPassword ); JSONObject jsonObject = JsonUtil.parse( getLog(), json ); JSONArray jsonArray = (JSONArray) jsonObject.get( "values" ); jsonArray.forEach( branch -> { String displayId = ( (JSONObject) branch ).get( "displayId" ).toString(); existingBranches.add( displayId ); String escapedValue = SpecialCharacterUtil.makeStringFreeOfSpecialCharacters( displayId ); existingBranches.add( escapedValue ); } ); return existingBranches; } private String doGet( final String path, final String username, final String password ) throws SonarQualityException { getLog().info( String.format( "%s try to get data for: %s", SonarStrings.LOG_PREFIX, path ) ); try { StringJoiner joiner = new StringJoiner( "" ); URL url = new URL( path ); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod( "GET" ); conn.setRequestProperty( "Accept", "application/json" ); String userpass = String.format( "%s:%s", username, password ); String basicAuth = "Basic " + new String( new Base64().encode( userpass.getBytes() ) ); conn.setRequestProperty( "Authorization", basicAuth ); if ( conn.getResponseCode() != 200 ) { throw new RuntimeException( "Failed : HTTP error code : " + conn.getResponseCode() ); } BufferedReader br = new BufferedReader( new InputStreamReader( ( conn.getInputStream() ) ) ); String output; while ( ( output = br.readLine() ) != null ) { joiner.add( output ); } conn.disconnect(); return joiner.toString(); } catch ( Exception e ) { throw new SonarQualityException( "failed to load repo data", e ); } } private String doDelete( final String path, final String username, final String password ) throws SonarQualityException { try { URL url = new URL( path ); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setDoOutput( true ); conn.setRequestMethod( "DELETE" ); conn.setRequestProperty( "Content-Type", "application/json" ); String userpass = String.format( "%s:%s", username, password ); String basicAuth = "Basic " + new String( new Base64().encode( userpass.getBytes() ) ); conn.setRequestProperty( "Authorization", basicAuth ); OutputStream os = conn.getOutputStream(); os.flush(); int responseCode = conn.getResponseCode(); getLog().info( SonarStrings.LOG_PREFIX + " got response code for delete: " + responseCode ); if ( responseCode != HttpURLConnection.HTTP_OK ) { BufferedReader br = new BufferedReader( new InputStreamReader( ( conn.getErrorStream() ) ) ); String output; StringJoiner serverOutput = new StringJoiner( "\n" ); while ( ( output = br.readLine() ) != null ) { serverOutput.add( output ); } throw new RuntimeException( "Failed : HTTP error code : " + conn.getResponseCode() + " ;\n" + serverOutput.toString() ); } BufferedReader br = new BufferedReader( new InputStreamReader( ( conn.getInputStream() ) ) ); String output; StringJoiner serverOutput = new StringJoiner( "\n" ); while ( ( output = br.readLine() ) != null ) { serverOutput.add( output ); } conn.disconnect(); return serverOutput.toString(); } catch ( Exception e ) { throw new SonarQualityException( "failed to delete project", e ); } } private class BranchMetaData { private final String id; private final String name; public BranchMetaData( final String id, final String name ) { this.id = id; this.name = name; } public String getId() { return id; } public String getName() { return name; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy