JIRAのJava APIを使ってIssueをエクスポートする

#前置き
JIRAのJava APIを使う機会があり、その紹介をしたいと思います。

REST APIはドキュメントやCurlを使った例などが豊富でしたが、JavaのAPIについてはネットで探しても、
以下のJIRAの公式のチュートリアルが見つかりましたが、情報が古いため有益ではありませんでした。

* https://ecosystem.atlassian.net/wiki/display/JRJC/Tutorial

そのほかにはHttpClientを直接使ってJSONを解析している強者さんのサンプルは見つかりました。

車輪の再発明になりますが、ExcelにJIRAのIssueのサマリをエクスポートする
サンプルを作成したのでそれを紹介したいと思います。

#JIRAのJava APIの使い方の紹介。

JIRAのissueの概要をMS エクセルに出力するJavaのプログラムを例にあげています。 既に標準機能として提供されている(*)のですが、JIRAのJava APIを学びたい人の役に立つと良いです。
\* [JIRA 検索結果を Microsoft Excel にエクスポートする](https://ja.confluence.atlassian.com/jira063/exporting-search-results-to-microsoft-excel-683542534.html)

Javaのバッチプログラムで実行すると第一引数で指定したエクセルに、タイトル、サマリ、説明を出力するようになっています。
なお、以下のGitHubに公開したコードはあくまで例なので、特にExcelを出力する個所が洗練されていません。

* https://github.com/tashxii/jira-export


##調べた順、疑問に感じた点について

以下に調べた順や疑問点等を時系列に書いていきます。結論だけほしい人は次の節を見てください。

###REST APIだけでなく、JavaでラップされたAPIがあるはずだ。
→APIはあります。以下のページの最後に書かれています。
 JIRA Server,Cloud,Software Server, Service Desk Serverとどれを使えばいいのかよくわからないです。
https://developer.atlassian.com/jiradev/jira-apis

###依存ライブラリはそもそも何を使えばいいの？
視点を変えて、Mavenかgradleのどちらでもいいので動くサンプルがないかを探しました。
「pom java JIRA api」等で検索して一番近かったのが以下のページです。
これでも2.0とかなり古いです。
https://community.atlassian.com/t5/Answers-Developer-Questions/JIRA-Rest-Java-Client-libraries/qaq-p/524054

どうやら、以下のライブラリがキーワードっぽいことがわかりました。

* jira-rest-java-client-api
* jira-rest-java-client-core
* jira-rest-java-client-plugin

また、JiraRestClientFactoryというAPIがあることもわかりました。

###チュートリアルのJerseyJiraRestClientFactoryはどこにいったの？
依存ライブラリがわかったので、それをキーにpomを書きました。
「jira-rest-java-client-core maven」で調べると、バージョンが4.0が一番新しいことがわかりました。
https://mvnrepository.com/artifact/com.atlassian.jira/jira-rest-java-client-core

###どういうAPIの構造なの？
依存ライブラリは解決できたので、APIをどう使うか？を調べました。
「JiraRestClientFactory example」をキーに探します。
http://massapi.com/class/ji/JiraRestClientFactory.html
がヒットしました。

コードを見るとJiraRestClientFactory（インターフェース）がエントリーポイントになっていて、昔はJersey…という実装クラス名だったのですが、AsynchronousJiraRestClientFactoryが新しい名前になっています。

Factoryから、JiraRestClientを取得し、検索、更新などなどを行う構造になっています。

━ JiraRestClientFactory (エントリーポイント）
　　┗ AsynchronousJiraRestClientFactory (実装クラス）
　　　　┗ JiraRestClient (ファクトリからとれるClient）
　　　　　┣ IssueClient　（RestClientから取れるサブAPI群）
　　　　　┣ SearchClient
　　　　　┗ ProjectClient

JiraRestClientのJavaDocを見るとよくわかります。

* AuditRestClient	getAuditRestClient() 
* ComponentRestClient	getComponentClient() 
* IssueRestClient	getIssueClient() 
* MetadataRestClient	getMetadataClient() 
* MyPermissionsRestClient	getMyPermissionsRestClient() 
* ProjectRestClient	getProjectClient() 
* ProjectRolesRestClient	getProjectRolesRestClient() 
* SearchRestClient	getSearchClient() 
* SessionRestClient	getSessionClient() 
* UserRestClient	getUserClient() 
* VersionRestClient	getVersionRestClient() 

あとは、Jersey→Asynchronousに置き換えればチュートリアルと同じであることがわかりました。

###認証はどうやるの？
https://developer.atlassian.com/jiradev/jira-apis/jira-rest-apis/jira-rest-api-tutorials
このRESTのチュートリアルを見ればBasic,OAuth他があることがわかりました。
サンプルコードを見ると、以下のコードでBasic認証はできそうです。

    factory.createWithBasicHttpAuthentication(jiraServerUri, yourUsername, yourPassword);


###検索はどうやってやるの？
「SearchClient JIRA example」で検索しました。とにかくexampleを付けるとよいようです。
次のページがヒットしましたが、これも古くJerseyJiraRestClientを使っていましたが参考にはなります。
http://stackoverflow.com/questions/29206524/how-to-get-all-issues-of-project-via-jira-rest-java-client

###検索するだけの簡単なサンプル
上の例から、以下のコードで検索できることがわかりました。
Promiseってなんだ？と思いましたが、claim()すると、イテレーターが返ってきます。
後は例と同じようにループすればよいだけ。

       Promise<SearchResult> searchJqlPromise = client.getSearchClient().searchJql("project = MYPURRJECT AND status in (Closed, Completed, Resolved) ORDER BY assignee, resolutiondate");

        for (Issue issue : searchJqlPromise.claim().getIssues()) {
            System.out.println(issue.getSummary());
        }

##Issueを検索するサンプルを作るための結論

###1. pom.xmlには、以下を書きます。
```xml
    <dependency>
      <groupId>com.atlassian.jira</groupId>
      <artifactId>jira-rest-java-client-core</artifactId>
      <version>4.0.0</version>
    </dependency>

    <dependency>
      <groupId>com.atlassian.jira</groupId>
      <artifactId>jira-rest-java-client-api</artifactId>
      <version>4.0.0</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/com.atlassian.fugue/fugue -->
    <dependency>
      <groupId>com.atlassian.fugue</groupId>
      <artifactId>fugue</artifactId>
      <version>2.6.1</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.7.25</version>
    </dependency>
```

###2. JiraRestClientをBasic認証して取得します。
```java
    JiraRestClientFactory factory = new AsynchronousJiraRestClientFactory();
    URI uri = new URI("https://your-project-name.atlassian.net");
    jiraRestClient = factory.createWithBasicHttpAuthentication(uri, userName, password);
```
###3. SearchClientを使ってIssueを取ります。
APIはちょっと変わっていましたが以下のコードで取れました。

```java
    SearchRestClient searchRestClient = jiraRestClient.getSearchClient();
    final Set<String> fields = new HashSet<String>();
    String jql = "status!=done"; // Only not done issues.
    SearchResult result = searchRestClient.searchJql(jql, max, offset, fields).claim();
    Iterable<Issue> issues = result.getIssues();
    List<Issue> list = new ArrayList<Issue>();
    for (final Issue issue : issues) {
        list.add(issue);
    }
```

###4. IssueのAPIから必要な情報が取れます。

```java
  issue.getKey();
  issue.getSummary();
  issue.getDescription();
```

以上です。

コードはこちら。

* https://github.com/tashxii/jira-export