JIRA Rest JAVA Client API實現問題管理及自定義字段(原創)

JIRA是一個缺陷跟蹤管理系統,被普遍應用於缺陷跟蹤、客戶服務、需求收集、流程審批、任務跟蹤、項目跟蹤和敏捷管理等工做領域,當咱們須要把第三方業務系統集成進來時,能夠調用他的API。java

JIRA自己的API很是強大,但它是一個底層的API體系,並非一個易用的接口,若是要開發和拓展,因此須要咱們二次包裝。web

jira官方爲解決這個問題,推出了方便強大的java client library(目前只有java客戶端庫,沒有.Net類庫)apache

jira的Rest API  最新文檔官網.json

JIRA 6.4.12 REST API documentation

https://docs.atlassian.com/jira/REST/latest/api

JIRA REST API Tutorials:

https://developer.atlassian.com/jiradev/jira-apis/jira-rest-apis/jira-rest-api-tutorialsapp

 

若是是編寫java桌面或web應用,jira提供了更方便的方式(Client類庫),JIRA REST Java Client is a Java library (usable from any JVM language) which allows to easily talk to any JIRA 4.2+ instance using new (and still evolving) REST API.dom

JIRA Java Client library 

https://ecosystem.atlassian.net/wiki/display/JRJC/Homecurl

 

若是使用Client類庫,能夠方便應用各類現成的jira實體類(如項目、問題、備註、自定義字段......),不須要再重複造輪子,大幅提高效率。async

 

首先,必需要了解JIRA api的接口結構,其中<resource-name>能夠理解成api的方法,好比project,就是項目信息,user就是用戶信息,issue就是問題信息....ide

1
http://hostname/rest/<api-name>/<api-version>/<resource-name>
JIRA's REST API is provided by a plugin that is anchored under the URI path component  /rest/. Hence, if your JIRA site is running at:


還先要搞清楚jira api的 認證體系,摘自官網:

 the first step in using the JIRA REST API is to authenticate a user account with your JIRA site. For the purposes of this tutorial we will use HTTP BASIC Authentication, but any authentication that works against JIRA will work against the REST API. This includes:

  1. OAuth
  2. HTTP Cookies
  3. Trusted Applications
  4. os_username/os_password query parameters

爲方便使用,咱們採用Basic Auth

Basic Auth headers

If you need to you may construct and send basic auth headers yourself. To do this you need to perform the following steps:

  1. Build a string of the form username:password
  2. Base64 encode the string
  3. Supply an "Authorization" header with content "Basic " followed by the encoded string. For example, the string "fred:fred" encodes to "ZnJlZDpmcmVk" in base64, so you would make the request as follows.
一個curl的例子,注意紅色字符串是對「username:password」的Base64編碼
curl -D- -X GET -H "Authorization: Basic ZnJlZDpmcmVk" -H "Content-Type: application/json" "http://kelpie9:8081/rest/api/2/issue/QA-31"

JAVA Client類庫實現的API DEMO

package jiraTEST;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;

import org.apache.commons.codec.binary.Base32;
import org.joda.time.DateTime;

import com.atlassian.jira.rest.client.IssueRestClient;
import com.atlassian.jira.rest.client.JiraRestClient;
import com.atlassian.jira.rest.client.SearchRestClient;
import com.atlassian.jira.rest.client.domain.BasicIssue;
import com.atlassian.jira.rest.client.domain.BasicProject;
import com.atlassian.jira.rest.client.domain.BasicUser;
import com.atlassian.jira.rest.client.domain.Comment;
import com.atlassian.jira.rest.client.domain.Field;
import com.atlassian.jira.rest.client.domain.Issue;
import com.atlassian.jira.rest.client.domain.Project;
import com.atlassian.jira.rest.client.domain.SearchResult;
import com.atlassian.jira.rest.client.domain.Transition;
import com.atlassian.jira.rest.client.domain.input.ComplexIssueInputFieldValue;
import com.atlassian.jira.rest.client.domain.input.FieldInput;
import com.atlassian.jira.rest.client.domain.input.IssueInput;
import com.atlassian.jira.rest.client.domain.input.IssueInputBuilder;
import com.atlassian.jira.rest.client.internal.async.AsynchronousJiraRestClientFactory;
import com.atlassian.util.concurrent.Promise;
import com.google.common.collect.Lists;

public class CvteJiraDemo {

    public static String BaseURL = "http://jira-test:8080/";
    public static String User = "admin";
    public static String Password = "admin";
    private static URI jiraServerUri = URI
            .create("http://jira-test:8080/rest/api/2/");
    private static boolean quiet = false;
    private static final long BUG_TYPE_ID = 1L; // JIRA magic value
    private static final long TASK_TYPE_ID = 3L; // JIRA magic value
    private static final DateTime DUE_DATE = new DateTime();
    private static final String PRIORITY = "Trivial";
    private static final String DESCRIPTION = "description";

    

    public static void main(String[] args) throws InterruptedException,
            ExecutionException {

        final AsynchronousJiraRestClientFactory factory = new AsynchronousJiraRestClientFactory();
        URI jiraServerUri;
        try {
            jiraServerUri = new URI(BaseURL);
            final JiraRestClient restClient = (JiraRestClient) factory
                    .createWithBasicHttpAuthentication(jiraServerUri, User,
                            Password);
            getAllProjects(restClient);
            getProject(restClient, "DEMO");
            getIssue(restClient, "FEEDBACK-14");
            getIssueFields(restClient, "FEEDBACK-27");
            addIssue(restClient, "FEEDBACK", "AAAAB");
            addIssueComplex(restClient, "FEEDBACK",DUE_DATE.toString());

        } catch (URISyntaxException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {

        }
    }
    
    private static void println(Object o) {
        if (!quiet) {
            System.out.println(o);
        }
    }

    private static void parseArgs(String[] argsArray) throws URISyntaxException {
        final List<String> args = Lists.newArrayList(argsArray);
        if (args.contains("-q")) {
            quiet = true;
            args.remove(args.indexOf("-q"));
        }

        if (!args.isEmpty()) {
            jiraServerUri = new URI(args.get(0));
        }
    }

    private static Transition getTransitionByName(
            Iterable<Transition> transitions, String transitionName) {
        for (Transition transition : transitions) {
            if (transition.getName().equals(transitionName)) {
                return transition;
            }
        }
        return null;
    }

    // 獲得全部項目信息
    private static void getAllProjects(final JiraRestClient restClient)
            throws InterruptedException, ExecutionException {
        try {

            Promise<Iterable<BasicProject>> list = restClient
                    .getProjectClient().getAllProjects();
            Iterable<BasicProject> a = list.get();
            Iterator<BasicProject> it = a.iterator();
            while (it.hasNext()) {
                System.out.println(it.next());
            }

        } finally {
        }
    }

    // 獲得單一項目信息
    private static void getProject(final JiraRestClient restClient,
            String porjectKEY) throws InterruptedException, ExecutionException {
        try {

            Project project = restClient.getProjectClient()
                    .getProject(porjectKEY).get();
            System.out.println(project);

        } finally {
        }
    }

    // 獲得單一問題信息
    private static void getIssue(final JiraRestClient restClient,
            String issueKEY) throws InterruptedException, ExecutionException {
        try {

            Promise<Issue> list = restClient.getIssueClient()
                    .getIssue(issueKEY);
            Issue issue = list.get();
            System.out.println(issue);

        } finally {
        }
    }
    
    // 建立問題
    public static BasicIssue createIssue(final JiraRestClient jiraRestClient,
            IssueInput newIssue) {
        BasicIssue basicIssue = jiraRestClient.getIssueClient()
                .createIssue(newIssue).claim();
        return basicIssue;
    }
    
    //添加備註到問題
    public static void addCommentToIssue(final JiraRestClient jiraRestClient,Issue issue, String comment) {
        IssueRestClient issueClient = jiraRestClient.getIssueClient();
        issueClient.addComment(issue.getCommentsUri(), Comment.valueOf(comment)).claim();
    }
    
    
    //刪除問題,目前找不到對應API
    public static void deleteIssue(final JiraRestClient jiraRestClient, Issue issue) {
        IssueRestClient issueClient = jiraRestClient.getIssueClient();
        //issueClient.deleteIssue(issue.getKey(), false).claim();
    }

    //經過標題獲取問題
    public static Iterable findIssuesByLabel(final JiraRestClient jiraRestClient, String label) {
        SearchRestClient searchClient = jiraRestClient.getSearchClient();
        String jql = "labels%3D"+label;
        com.atlassian.jira.rest.client.domain.SearchResult results = ((SearchRestClient) jiraRestClient).searchJql(jql).claim();
        return results.getIssues();
    }

    //經過KEY獲取問題
    public static Issue findIssueByIssueKey(final JiraRestClient jiraRestClient, String issueKey) {
        SearchRestClient searchClient = jiraRestClient.getSearchClient();
        String jql = "issuekey = \"" + issueKey + "\"";
        SearchResult results = searchClient.searchJql(jql).claim();
        return (Issue) results.getIssues().iterator().next();
    }

    // 建立問題 :僅有簡單問題名稱
    private static void addIssue(final JiraRestClient restClient,
            String porjectKEY, String issueName) throws InterruptedException,
            ExecutionException {
        try {
            IssueInputBuilder builder = new IssueInputBuilder(porjectKEY,
                    TASK_TYPE_ID, issueName);
            builder.setDescription("issue description");
            final IssueInput input = builder.build();

            try {
                // create issue
                final IssueRestClient client = restClient.getIssueClient();
                final BasicIssue issue = client.createIssue(input).claim();
                final Issue actual = client.getIssue(issue.getKey()).claim();
                System.out.println(actual);
            } finally {
                if (restClient != null) {
                    // restClient.close();
                }
            }

        } finally {
        }
    }

    // 建立問題 :包含自定義字段
    private static void addIssueComplex(final JiraRestClient restClient,
            String porjectKEY, String issueName) throws InterruptedException,
            ExecutionException {
        try {
            IssueInputBuilder builder = new IssueInputBuilder(porjectKEY,
                    TASK_TYPE_ID, issueName);
            builder.setDescription("issue description");
            // builder.setFieldValue("priority", ComplexIssueInputFieldValue.with("name", PRIORITY));
            //單行文本
            builder.setFieldValue("customfield_10042", "單行文本測試");
            
            //單選字段
            builder.setFieldValue("customfield_10043", ComplexIssueInputFieldValue.with("value", "通常"));
            
            //數值自定義字段
            builder.setFieldValue("customfield_10044", 100.08);
            
            //用戶選擇自定義字段
            builder.setFieldValue("customfield_10045", ComplexIssueInputFieldValue.with("name", "admin"));
            //用戶選擇自定義字段(多選)
            Map<String, Object> user1 = new HashMap<String, Object>();
            user1.put("name", "admin");
            Map<String, Object> user2 = new HashMap<String, Object>();
            user2.put("name", "wangxn");            
            ArrayList peoples = new ArrayList();
            peoples.add(user1);
            peoples.add(user2);
            builder.setFieldValue("customfield_10047", peoples); 
            
            //設定父問題
            Map<String, Object> parent = new HashMap<String, Object>();
            parent.put("key", "FEEDBACK-25");
            FieldInput parentField = new FieldInput("parent", new ComplexIssueInputFieldValue(parent));
            builder.setFieldInput(parentField);

            final IssueInput input = builder.build();
            try {
                final IssueRestClient client = restClient.getIssueClient();
                final BasicIssue issue = client.createIssue(input).claim();
                final Issue actual = client.getIssue(issue.getKey()).claim();
                System.out.println(actual);
            } finally {
                if (restClient != null) {
                    // restClient.close();
                }
            }

        } finally {
        }
    }

    
    //獲取問題的全部字段
    private static void getIssueFields(final JiraRestClient restClient,
            String issueKEY) throws InterruptedException, ExecutionException {
        try {

            Promise<Issue> list = restClient.getIssueClient()
                    .getIssue(issueKEY);
            Issue issue = list.get();
            Iterable<Field> fields = issue.getFields();
            Iterator<Field> it = fields.iterator();
            while (it.hasNext()) {
                System.out.println(it.next());
            }

        } finally {
        }
    }

}
相關文章
相關標籤/搜索