SonarQube Java client 介して Web API を 実行する


SonarQube には、sonarqube/sonar-ws at master · SonarSource/sonarqube という Web API の client ライブラリがあります。python 経由で Web API を実行 を試していたのですが、仕事で使うなら言語揃えておいたほうがいいかと思ったので、Issue のデータを取得するサンプルプログラムを実装してみました。結果を記載します。


API で データを抽出したい動機

SonarQube version 6.2 以降 widget が削除され、ユーザ側での、グラフ表現の追加が難しくなりました。12 SonarQube 内でのデータ可視化が難しいなら、データを取り出して外部のツールで、データ描画を行ってしまえば良い、Web API があるのでそれで抽出しようと考えました。

[1] しっかり調べたわけではないですが、画面を見る限りは、6.2以降でも指標やディメンションのコントロールはできそうです。
[2] 削除理由はSonarSource Blog » SonarQube 6.x series: Focused and Efficientの、User-needs oriented spaces に記載されています。


参考


Java client について

ライブラリ名称

version 5.1 まで と、version 5以降 では、ライブラリ名が異なります。

クライアントの実装方式

クライアントの内部的の実装方式についてですが、JSON 文字列を返す API ではなく、google/protobuf: Protocol Buffers - Google’s data interchange format を使った Binary を返す API を使っています。JSON 文字列を返す API とは、URL なり、parameter なりが多少異なるのかと思います。3
また、google/protobuf: Protocol Buffers - Google’s data interchange format なのか、sonar-ws なのか、 Intelij IDEA の問題なのか不明ですが、Intelij IDEA 上からの実行では、以下のようなエラーが発生し、実行確認ができなかったので、gradle から動作確認を行いました。4

  • エラー内容
    Error:(28, 40) java: com.google.protobuf.GeneratedMessageにアクセスできません
      com.google.protobuf.GeneratedMessageのクラス・ファイルが見つかりません
    Error:(33, 49) java: com.google.protobuf.MessageOrBuilderにアクセスできません
      com.google.protobuf.MessageOrBuilderのクラス・ファイルが見つかりません
    

[3] ドキュメントが見つけられず、詳細不明です。申し訳ございません。
[4] 挙動的には Intelij IDEA の設定が足りないそうに思います。


動作確認した環境

以下の環境で作業は実施しています。

  • OS

    % sw_vers 
    ProductName:    Mac OS X
    ProductVersion: 10.12.6
    BuildVersion:   16G29
    

  • java の version

    % java -version
    java version "1.8.0_45"
    Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
    Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
    

  • gradle の version

    % gradle -v
    
    ------------------------------------------------------------
    Gradle 4.1
    ------------------------------------------------------------
    
    Build time:   2017-08-07 14:38:48 UTC
    Revision:     941559e020f6c357ebb08d5c67acdb858a3defc2
    
    Groovy:       2.4.11
    Ant:          Apache Ant(TM) version 1.9.6 compiled on June 29 2015
    JVM:          1.8.0_45 (Oracle Corporation 25.45-b02)
    OS:           Mac OS X 10.12.6 x86_64
    

  • SonarQube の Version
    SonarQube 6.5


作成したサンプル

作成したサンプルは以下になります。プログラムは、デフォルトパッケージに配置してもらえれば動作します。
また、localhost:9000 で SonarQube が起動している必要があります。
他 host で SonarQube が存在する場合は、host の指定箇所を書き換えてください。

  • build.gradle

    /*
     * This build file was generated by the Gradle 'init' task.
     *
     * This generated file contains a sample Java Library project to get you started.
     * For more details take a look at the Java Libraries chapter in the Gradle
     * user guide available at https://docs.gradle.org/4.1/userguide/java_library_plugin.html
     */
    // Apply the java-library plugin to add support for Java Library
    apply plugin: 'java-library'
    
    // In this section you declare where to find the dependencies of your project
    repositories {
        // Use jcenter for resolving your dependencies.
        // You can declare any Maven/Ivy/file repository here.
        jcenter()
    }
    dependencies {
        // This dependency is exported to consumers, that is to say found on their compile classpath.
        api 'org.apache.commons:commons-math3:3.6.1'
    
        // This dependency is used internally, and not exposed to consumers on their own compile classpath.
        implementation 'com.google.guava:guava:22.0'
        // https://mvnrepository.com/artifact/org.sonarsource.sonarqube/sonar-ws
        implementation 'org.sonarsource.sonarqube:sonar-ws:6.5'
        // https://mvnrepository.com/artifact/org.apache.commons/commons-lang3
        implementation 'org.apache.commons:commons-lang3:3.6'
    
        testImplementation 'junit:junit:4.12'
    }
    
    test {
        testLogging {
            events "passed", "skipped", "failed", "standardOut", "standardError"
        }
    }
    

  • 説明 sonar-ws について

        // https://mvnrepository.com/artifact/org.sonarsource.sonarqube/sonar-ws
        implementation 'org.sonarsource.sonarqube:sonar-ws:6.5'
    
    が、sonar-ws java client のライブラリになります。

  • 説明 戻り値の出力 について

        // https://mvnrepository.com/artifact/org.apache.commons/commons-lang3
        implementation 'org.apache.commons:commons-lang3:3.6'
    
    に含まれる ToStringBuilder を、標準出力に戻り値を出力するために使用しています。

  • SearchIssues.java

    import org.apache.commons.lang3.builder.ToStringBuilder;
    import org.apache.commons.lang3.builder.ToStringStyle;
    import org.sonarqube.ws.Common;
    import org.sonarqube.ws.Issues;
    import org.sonarqube.ws.client.HttpConnector;
    import org.sonarqube.ws.client.WsClient;
    import org.sonarqube.ws.client.WsClientFactories;
    import org.sonarqube.ws.client.issue.SearchWsRequest;
    
    import java.util.List;
    
    /*
     * This Java source file was generated by the Gradle 'init' task.
     */
    public class SearchIssues {
        /**
         * Main method..
         *
         * @param args
         */
        public static void main(String... args) {
            // execute search Issues 
            HttpConnector httpConnector = HttpConnector.newBuilder().url("http://localhost:9000").credentials("admin", "admin").token("your_token").build();
            WsClient wsClient = WsClientFactories.getDefault().newClient(httpConnector);
            SearchWsRequest searchWsRequest = new SearchWsRequest();
            Issues.SearchWsResponse response = wsClient.issues().search(searchWsRequest);
    
            // STD Out Paging Object
            Common.Paging paging = response.getPaging();
            System.out.println("------------------------------------------------------------");
            System.out.println(ToStringBuilder.reflectionToString(paging, ToStringStyle.JSON_STYLE));
            System.out.println("------------------------------------------------------------");
    
            // STD Out issue
            List<Issues.Issue> issuesList = response.getIssuesList();
            for (Issues.Issue issue : issuesList) {
                System.out.println("------------------------------------------------------------");
                System.out.println(ToStringBuilder.reflectionToString(issue, ToStringStyle.JSON_STYLE));
                System.out.println("------------------------------------------------------------");
            }
        }
    }
    

  • 説明 認証について

        HttpConnector httpConnector = HttpConnector.newBuilder().url("http://localhost:9000").credentials("admin", "admin").token("your_token").build();
    
    で、認証情報を生成しています。credentials の設定、token の設定はどちらかを実施すれば、認証は通ります。
    token の生成については、SonarQube Web API を python から実行する | Monotalk で実施しています。生成が必要であればご確認ください。

  • 説明 response.getPaging() の戻り値について
    戻り値の標準出力の結果は以下の通りです。

    {"bitField0_":7,"pageIndex_":1,"pageSize_":100,"total_":734,"memoizedIsInitialized":-1,"unknownFields":"","memoizedSize":-1,"memoizedHashCode":0}
    
    "total_":734 が、issue の総数を示しています。
    "pageSize_":100で、戻りに含まれる issue数、"pageIndex_":1 で何ページ目なのかが返ります。
    全ての issue を取得する場合は、この戻り値を元に、SearchWsRequest に値を設定し、loop を回す必要があります。

  • 説明 SearchWsRequestについて
    パッケージ違いで SearchWsRequest が存在します。叩く API ごとに、使用するSearchWsRequestが違いますので、ご注意ください。

  • SearchIssuesTest.java

    import org.junit.Test;
    
    public class SearchIssuesTest {
        @Test
        public void main() throws Exception {
            String arg = null;
            SearchIssues.main(arg);
        }
    }
    

  • 説明 実行方法
    以下で、テストクラス経由で実行可能です。

    ./gradlew clean test
    
    gradle 経由ではない場合、IDE から メインメソッドを実行していただければよいかと思います。

データ取得はうまくいきました。
作成したプログラムは gist にもアップしていますので、必要であればご参照ください。
SonarQube 6.5 sonar-ws example
以上です。

コメント

カテゴリー