SonarQube には、sonarqube/sonar-ws at master · SonarSource/sonarqube という Web API の client ライブラリがあります。python 経由で Web API を実行 を試していたのですが、仕事で使うなら言語揃えておいたほうがいいかと思ったので、Issue のデータを取得するサンプルプログラムを実装してみました。結果を記載します。
API で データを抽出したい動機
SonarQube version 6.2 以降 widget が削除され、ユーザ側での、グラフ表現の追加が難しくなりました。1、2 SonarQube 内でのデータ可視化が難しいなら、データを取り出して外部のツールで、データ描画を行ってしまえば良い、Web API があるのでそれで抽出しようと考えました。
[1] しっかり調べたわけではないですが、画面を見る限りは、6.2以降でも指標やディメンションのコントロールはできそうです。
[2] 削除理由はSonarSource Blog » SonarQube 6.x series: Focused and Efficientの、User-needs oriented spaces
に記載されています。
参考
-
Sonar Web APIを使ってみました - Qiita
Java から HttpRequest で Web API を叩く際の参考になります。 -
Using the Web Service Java client - SonarQube-4.5 - Doc SonarQube
過去 Version の ドキュメント 現状の API とは IF が違います。
Java client について
ライブラリ名称
version 5.1 まで と、version 5以降 では、ライブラリ名が異なります。
-
version 5.1 まで
Maven Repository: org.codehaus.sonar » sonar-ws-client -
version 5.2 以降
Maven Repository: org.sonarsource.sonarqube » sonar-ws
クライアントの実装方式
クライアントの内部的の実装方式についてですが、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 について
が、sonar-ws java client のライブラリになります。// 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'
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); } }
-
説明 実行方法
以下で、テストクラス経由で実行可能です。
gradle 経由ではない場合、IDE から メインメソッドを実行していただければよいかと思います。./gradlew clean test
データ取得はうまくいきました。
作成したプログラムは gist にもアップしていますので、必要であればご参照ください。
SonarQube 6.5 sonar-ws example
以上です。
コメント