Jira Api对接:提交缺陷

Posted leo_hou

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Jira Api对接:提交缺陷相关的知识,希望对你有一定的参考价值。

    本文介绍如何通过api提交项目缺陷,由于不同project提交缺陷时要求的必填字段值可能不同,如下图,所以我们需要根据project id动态获取创建缺陷时需要的必填字段以及对应的字段值。

一:获取必填字段

根据project id获取必填字段并根据字段类型设置字段值,代码如下

//创建缺陷时所需要的字段,以及设置默认值
 public static String getBugCreateMeta(String jiraProjectId) {
​
        //api 接口
        String url = "http://you jira address:port/rest/api/2/issue/createmeta?projectIds=" + jiraProjectId + "&expand=projects.issuetypes.fields";
        //初始值
        String issueField = "{\\n  \\"fields\\": {\\n    \\"project\\": {\\n      \\"id\\": \\"" + jiraProjectId + "\\"\\n    }";
        //除了必填项外 需要的字段
        String[] otherRequiredField = {"assignee"};
        //接口调用
        HttpClientResponse httpClientResponse = httpClient(1, url, "");
        JSONObject jsonObject = JSONObject.fromObject(httpClientResponse.getResponseBody().toString());
        //接口返回结果示例参考下图
        //获取项目信息
        JSONArray projects = jsonObject.getJSONArray("projects");
        JSONObject project = JSONObject.fromObject(projects.get(0));
        //获取所有issue类型
        JSONArray issuetypes = project.getJSONArray("issuetypes");
        //查找缺陷类型
        int bugIssueIndex = 0;//用于保存缺陷类型坐标
        for (int i = 0; i < issuetypes.size(); i++) {
​
            JSONObject issuetype = JSONObject.fromObject(issuetypes.get(i));
            if ("缺陷".equals(issuetype.getString("name"))) {
​
                bugIssueIndex = i;
                //添加类型字段
                issueField += replace(jiraFieldOptionTemplate, "issuetype", issuetype);
                break;
            }
        }
        //获取缺陷类型所有信息
        JSONObject issuetype = JSONObject.fromObject(issuetypes.get(bugIssueIndex));
        //获取提交缺陷时所有字段
        JSONObject fields = issuetype.getJSONObject("fields");
        //循环所有字段,并获取默认值
        Iterator<String> iterator = fields.keys();
        while (iterator.hasNext()) {
​
            String key = iterator.next();
            //获取字段信息
            JSONObject field = fields.getJSONObject(key);
            //字段是必填且没有设置默认值,则选择默认值
            if (ArrayUtils.contains(otherRequiredField, key) ||
                    (field.getBoolean("required") && !field.getBoolean("hasDefaultValue"))) {
                //获取字段类型
                JSONObject schema = field.getJSONObject("schema");
                if (field.containsKey("allowedValues")) {
                    //如果字段值有可选项,则默认取值第一个
                    JSONArray allowedValues = field.getJSONArray("allowedValues");
                    JSONObject allowedValue = JSONObject.fromObject(allowedValues.get(0));
                    issueField = getIssueField(schema, issueField, key, allowedValue);
                } else {
                    //字段值默认key
                    issueField = getIssueField(schema, issueField, key, null);
                }
            }
        }
​
        //闭环json
        issueField = issueField + "\\n  }\\n}";
        return issueField;
    }
    
    /**
     * 设置那些类型的字段
     *
     * @param schema
     * @param issueField
     * @param key
     * @param allowedValue
     * @return
     */
    private static String getIssueField(JSONObject schema, String issueField, String key, JSONObject allowedValue) {
        //针对字段不同类型,定制不同模板
         String jiraFieldArrayTemplate = ",\\n    \\"key\\": [\\n      {\\n        \\"id\\": \\"jira_id\\"\\n      }\\n    ]";
         String jiraFieldOptionTemplate = ",\\n    \\"key\\": {\\n      \\"id\\": \\"jira_id\\"\\n    }";
         String jiraFieldStringTemplate = ",\\n    \\"key\\": \\"jira_key\\"";
         String jiraFieldUserTemplate = ",\\n    \\"key\\": {\\n      \\"name\\": \\"jira_key\\"\\n    }";
        //字段类型,需要可以扩展
        switch (schema.getString("type")) {
            case "array":
                issueField += replace(jiraFieldArrayTemplate, key, allowedValue);
                break;
            case "option":
                issueField += replace(jiraFieldOptionTemplate, key, allowedValue);
                break;
            case "string":
                issueField += replace(jiraFieldStringTemplate, key, null);
                break;
            case "user":
                issueField += replace(jiraFieldUserTemplate, key, null);
                break;
            default:
                break;
        }
        return issueField;
    }
    
     /**
     * 替换值
     *
     * @param template
     * @param key
     * @param allowedValue
     * @return
     */
    private static String replace(String template, String key, JSONObject allowedValue) {
​
        //默认值是key,如果有可选值则获取可选值
        String value = key;
        if (allowedValue != null) {
            value = allowedValue.getString("id");
        }
        //以这种方式根据key的不同定制值
        if (key.equals("customfield_10001")) {
            value = "10001";
        }
        return StringUtils.replaceEach(template, new String[]{"key", "jira_id"}, new String[]{key, value});
    }
//url 可使用参数projectIds表示项目id、projectKeys表示项目key、issuetypeIds表示类型Id、issuetypeNames表示类型名称、expand增加展示的字段
//http://jyou jira address:port/rest/api/2/issue/createmeta?projectIds=100001&expand=projects.issuetypes.fields&issuetypeIds=10001
//调用接口返回的结果,根据字段类型、是否必填、是否有默认值进行分析
{
  "expand": "projects",
  "projects": [
    {
      "expand": "issuetypes",
      "self": "http://you jira address:port/rest/api/2/project/1",
      "id": "1",
      "key": "abc",
      "name": "浙江省国办电子印章专项",
      "avatarUrls": {
        "48x48": "http://you jira address:port/secure/projectavatar?avatarId=10324"
      },
      "issuetypes": [
        {
          "self": "http://you jira address:port/rest/api/2/issuetype/2",
          "id": "2",
          "description": "gh.issue.story.desc",
          "iconUrl": "http://you jira address:port/images/icons/issuetypes/story.svg",
          "name": "Story",
          "subtask": false,
          "expand": "fields",
          "fields": {
            "summary": {
              "required": true,
              "schema": {
                "type": "string",
                "system": "summary"
              },
              "name": "主题",
              "hasDefaultValue": false,
              "operations": [
                "set"
              ]
            }
          }
        },
        {
          "self": "http://you jira address:port/rest/api/2/issuetype/3",
          "id": "3",
          "description": "",
          "iconUrl": "http://you jira address:port/secure/viewavatar?size=xsmall&avatarId=3&avatarType=issuetype",
          "name": "缺陷",
          "subtask": false,
          "expand": "fields",
          "fields": {
            "customfield_10001": {
              "required": true,
              "schema": {
                "type": "option",
                "custom": "com.atlassian.jira.plugin.system.customfieldtypes:select",
                "customId": 10001
              },
              "name": "问题环境",
              "hasDefaultValue": false,
              "operations": [
                "set"
              ],
              "allowedValues": [//该字段值可以展示给用户进行选择
                {
                  "self": "http://you jira address:port/rest/api/2/customFieldOption/3",
                  "value": "测试环境",
                  "id": "3"
                },
                {
                  "self": "http://you jira address:port/rest/api/2/customFieldOption/4",
                  "value": "生产环境",
                  "id": "4"
                }
              ]
            }
          }
        }
      ]
    }
  ]
}
//getBugCreateMeta 方法返回的结果,该结果在第二步中做为body内容进行提交
{
  "fields": {
    "project": {
      "id": "10001"
    },
    "issuetype": {
      "id": "10002"
    },
    "summary": "jira_summary",
    "reporter": {
      "name": "huangtai"
    },
    "customfield_10003": {
      "id": "10003"
    },
    "customfield_10004": {
      "id": "10004"
    },
    "customfield_10005": [
      {
        "id": "10005"
      }
    ],
    "customfield_10006": {
      "id": "10006"
    },
    "assignee": {
      "name": "huangtai"
    }
  }
}

二、提交缺陷

根据第一步中的返回结果作为请求body,提交缺陷,并获取缺陷key,代码如下

/**
     * jira上新增缺陷
     *
     * @param requestBody 就是getBugCreateMeta方法返回的结果
     * @return
     */
    public static String addJiraIssue(String requestBody) {
​
        //api接口
        String url = "http://you jira address:port/rest/api/2/issue";
        //请求接口
        HttpClientResponse clientResponse = httpClient(2, url, requestBody);
        if (clientResponse != null && "201".equals(clientResponse.getStateCode()) && clientResponse.getResponseBody() != null) {
​
            //解析结果并返回缺陷key
            JSONObject jsonObject = JSONObject.fromObject(clientResponse.getResponseBody().toString());
            if (jsonObject != null && jsonObject.containsKey("key")) {
​
                return jsonObject.getString("key");
            }
        }
        return null;
    }
//接口返回结果
{
    "id": "12345",
    "key": "abc-1001",
    "self": "http://you jira address:port/rest/api/2/issue/12345"
}

 

 

    总结:按照上面的步骤就可以在其它平台使用api的方式提交缺陷了;有时候需要让用户选择字段值,只需要把allowedValues字段在前端展示给用户选择即可。

 

更多文章请关注公共号

以上是关于Jira Api对接:提交缺陷的主要内容,如果未能解决你的问题,请参考以下文章

Jira Api对接:获取项目和sprint

(番外篇)Jira Api对接:jira-workflow中节点校验条件实践

Jmeter集成Jira提交缺陷

Jmeter集成Jira提交缺陷

Jira Api对接:修改任务状态

confluence与jira账号对接查看到期时间及问题总结