需求:拉取并同步jira数据(项目,版本,缺陷,任务)
实现方式以及注意点:
1.jira中没有接口直接获取所有用户,但是可以获取组内用户,每个jira账户都会对应jira_user这个组,所以可以通过该组编码获取所有用户
2.jira中所有的任务,bug等都可以通过获取issue得到,只是类型不同。
3.需要注意的是如果在jira中有自定义字段,需要拿到返回值后查看,然后再对应去取。
4.jira获取出来的项目,需要在通过调用项目详情接口去拿详细信息
实现代码:
/*** @author yangqidong*/@Component@Slf4jpublic class JiraUtil {@Value("${jira.baseUrl}")private String jiraUrl;@Value("${jira.userName}")private String userName;@Value("${jira.password}")private String password;@Value("${jira.groupName}")private String jiraGroup;@AutowiredIJiraDicService jiraDicService;/*** 通过组获取jira所有用户** @return*/public List<JiraUserVO> getJiraUserByGroup() {//构建结果集List<JiraUserVO> result = new ArrayList<>();//封装http调用获取组内用户HttpClient httpClient = HttpClients.createDefault();String url = jiraUrl + "/rest/api/2/group/member?groupname=" + jiraGroup + "&maxResults=50";HttpGet request = new HttpGet(url);// 将用户名和密码进行 Base64 编码String credentials = Base64.getEncoder().encodeToString((userName + ":" + password).getBytes());request.addHeader("Authorization", "Basic " + credentials);try {HttpResponse response = httpClient.execute(request);String jsonResponse = EntityUtils.toString(response.getEntity());//转换结果集JsonObject returnData = new JsonParser().parse(jsonResponse).getAsJsonObject();//获取总数Integer total = Integer.valueOf(returnData.get("total").toString());//根据总数循环调用获取所有用户for (int i = 0; i <= total / 50 + 1; i++) {String queueUrl = String.format(url + "&startAt=%d", i * 50);HttpGet queueRequest = new HttpGet(queueUrl);queueRequest.addHeader("Authorization", "Basic " + credentials);HttpResponse queueResponse = httpClient.execute(queueRequest);String queueJsonResponse = EntityUtils.toString(queueResponse.getEntity());//转换结果集JsonObject queueReturnData = new JsonParser().parse(queueJsonResponse).getAsJsonObject();JsonArray values = queueReturnData.getAsJsonArray("values");for (JsonElement jsonElement : values) {JsonObject item = jsonElement.getAsJsonObject();String name = item.get("name").getAsString();String key = item.get("key").getAsString();String emailAdreess = item.get("emailAddress").getAsString();JiraUserVO jiraUserVO = new JiraUserVO();jiraUserVO.setUserName(name);jiraUserVO.setKey(key);jiraUserVO.setEmailAddress(emailAdreess);result.add(jiraUserVO);}}} catch (Exception e) {throw new ServiceException(ERROR_CODE_40001, "jira数据获取异常");}return result;}/*** 获取所有项目Id*/public List<String> getJiraProjectsId() {//构建结果集List<String> result = new ArrayList<>();//封装http调用获取项目HttpClient httpClient = HttpClients.createDefault();//获取所有项目String url = jiraUrl + "/rest/api/2/project";HttpGet request = new HttpGet(url);//将用户名和密码进行 Base64 编码String credentials = Base64.getEncoder().encodeToString((userName + ":" + password).getBytes());request.addHeader("Authorization", "Basic " + credentials);try {HttpResponse response = httpClient.execute(request);String jsonResponse = EntityUtils.toString(response.getEntity());//转换结果集JsonArray returnData = new JsonParser().parse(jsonResponse).getAsJsonArray();//遍历获取所有项目for (JsonElement jsonElement : returnData) {JsonObject item = jsonElement.getAsJsonObject();String name = item.get("id").getAsString();result.add(name);}} catch (Exception e) {log.error("同步项目失败",e);}return result;}/*** 获取单个项目对应版本* List<String> projectIds*/public List<JiraProjectAO> getJiraProjectVersionsById(List<String> proIds) {//构建结果集List<JiraProjectAO> result = new ArrayList<>();//封装http调用获取项目HttpClient httpClient = HttpClients.createDefault();for (String proId : proIds) {//获取所有项目String url = jiraUrl + "/rest/api/2/project/" + proId;HttpGet request = new HttpGet(url);//将用户名和密码进行 Base64 编码String credentials = Base64.getEncoder().encodeToString((userName + ":" + password).getBytes());request.addHeader("Authorization", "Basic " + credentials);try {HttpResponse response = httpClient.execute(request);String jsonResponse = EntityUtils.toString(response.getEntity());//转换结果集JsonObject queueReturnData = new JsonParser().parse(jsonResponse).getAsJsonObject();JsonArray values = queueReturnData.getAsJsonArray("versions");//遍历版本for (JsonElement jsonElement : values) {JiraProjectAO jiraProjectAO = new JiraProjectAO();//获取项目相关信息String projectId = queueReturnData.getAsJsonPrimitive("id").getAsString();String projectKey = queueReturnData.getAsJsonPrimitive("key").getAsString();String projectName = queueReturnData.getAsJsonPrimitive("name").getAsString();//获取项目负责人相关信息(暂不同步)// JsonObject lead = queueReturnData.getAsJsonObject("lead");// String leadKey = "";// String leadName = "";// if (ObjectUtils.isNotEmpty(lead)) {// leadKey = ObjectUtils.isEmpty(lead.getAsJsonPrimitive("key")) ? "" : lead.getAsJsonPrimitive("key").getAsString();// leadName = ObjectUtils.isEmpty(lead.getAsJsonPrimitive("displayName")) ? "" : lead.getAsJsonPrimitive("displayName").getAsString();// }//获取项目状态相关信息(暂不同步)// JsonObject proCate = queueReturnData.getAsJsonObject("projectCategory");// String proCateId = "";// String proCateName = "";//// if (ObjectUtils.isNotEmpty(proCate)) {// proCateId = ObjectUtils.isEmpty(proCate.getAsJsonPrimitive("id")) ? "" : proCate.getAsJsonPrimitive("id").getAsString();// proCateName = ObjectUtils.isEmpty(proCate.getAsJsonPrimitive("name")) ? "" : proCate.getAsJsonPrimitive("name").getAsString();// }//获取版本相关信息JsonObject item = jsonElement.getAsJsonObject();String versionName = ObjectUtils.isEmpty(item.get("name")) ? "" : item.get("name").getAsString();String versionId = ObjectUtils.isEmpty(item.get("id")) ? "" : item.get("id").getAsString();String versionDesc = ObjectUtils.isEmpty(item.get("description")) ? "" : item.get("description").getAsString();String startDate = ObjectUtils.isEmpty(item.get("startDate")) ? "" : item.get("startDate").getAsString();String releaseDate = ObjectUtils.isEmpty(item.get("releaseDate")) ? "" : item.get("releaseDate").getAsString();//获取版本状态Boolean isArchived = ObjectUtils.isEmpty(item.get("archived")) ? false : item.get("archived").getAsBoolean();Boolean isReleased = ObjectUtils.isEmpty(item.get("released")) ? false : item.get("released").getAsBoolean();jiraProjectAO.setStatus("3");if(isReleased){jiraProjectAO.setStatus("2");}if(isArchived){jiraProjectAO.setStatus("1");}jiraProjectAO.setId(projectId);jiraProjectAO.setKey(projectKey);jiraProjectAO.setName(projectName);jiraProjectAO.setVersionDesc(versionDesc);jiraProjectAO.setStartDate(startDate);jiraProjectAO.setReleaseDate(releaseDate);// jiraProjectAO.setLeadKey(leadKey);// jiraProjectAO.setLeadName(leadName);// jiraProjectAO.setProjectCategoryId(proCateId);// jiraProjectAO.setProjectCategoryName(proCateName);jiraProjectAO.setVersionName(versionName);jiraProjectAO.setVersionId(versionId);result.add(jiraProjectAO);}} catch (Exception e) {log.error("同步项目失败",e);}}return result;}/*** 获取所有Bug*/public List<JiraIssueAO> getJiraIssues(String startTime) {//获取字典表拿到point等jira属性idList<JiraDic> jiraDics = jiraDicService.list();//拿到字典中所有属性JiraDic points = getByKey(jiraDics,Constants.POINTS);JiraDic storyPoints = getByKey(jiraDics,Constants.STORY_POINTS);JiraDic subtask = getByKey(jiraDics, Constants.ISSUE_TYPE_SUBTASK);JiraDic story = getByKey(jiraDics, Constants.ISSUE_TYPE_STORY);JiraDic storyBase = getByKey(jiraDics, Constants.ISSUE_TYPE_STORY_BASE);JiraDic storyIncubate = getByKey(jiraDics, Constants.ISSUE_TYPE_STORY_INCUBATE);JiraDic storyIncubateBase = getByKey(jiraDics, Constants.ISSUE_TYPE_STORY_INCUBATE_BASE);JiraDic displayStep = getByKey(jiraDics, Constants.DISPLAY_STEP);JiraDic defect = getByKey(jiraDics, Constants.ISSUE_TYPE_DEFECT);JiraDic responsible = getByKey(jiraDics, Constants.RESPONSIBLE);//拿到所有类型属性List<JiraDic> issueTypeDic = jiraDics.stream().filter(e -> Constants.ISSUE_TYPE_DIC.equals(e.getType())).collect(Collectors.toList());//构建结果集List<JiraIssueAO> result = new ArrayList<>();//封装http调用获取项目HttpClient httpClient = HttpClients.createDefault();String url = jiraUrl + "rest/api/2/search?jql=";try {//定义起止时间String endTime = DateUtils.formatDateToSecond(new Date());//url构造String param = "issuetype is not empty and status != Closed AND updatedDate >= \"" + startTime + "\" AND updatedDate <= \"" + endTime + "\"";url = url + URLEncoder.encode(param, "UTF-8");url = url + "&maxResults=50";HttpGet request = new HttpGet(url);// 将用户名和密码进行 Base64 编码String credentials = Base64.getEncoder().encodeToString((userName + ":" + password).getBytes());request.addHeader("Authorization", "Basic " + credentials);HttpResponse response = httpClient.execute(request);String jsonResponse = EntityUtils.toString(response.getEntity());//转换gsonGson gson = new Gson();IssueResponse issueResponse = gson.fromJson(jsonResponse, IssueResponse.class);//获取总数量int total = issueResponse.getTotal();//根据总数循环调用获取所有用户for (int i = 0; i <= total / 50 + 1; i++) {int startAt = i * 50;String queueUrl = url + "&startAt="+startAt;HttpGet queueRequest = new HttpGet(queueUrl);queueRequest.addHeader("Authorization", "Basic " + credentials);HttpResponse queueResponse = httpClient.execute(queueRequest);String queueJsonResponse = EntityUtils.toString(queueResponse.getEntity());//转换结果集IssueResponse queueIssueResponse = gson.fromJson(queueJsonResponse, IssueResponse.class);JsonObject returnData = new JsonParser().parse(queueJsonResponse).getAsJsonObject();List<Issue> issues = queueIssueResponse.getIssues();//遍历当前issueint index = 0;for (Issue item : issues) {//测试if(item.getKey().equals("DTFCP-790")){String a = "测试";}JiraIssueAO jiraIssueAO = new JiraIssueAO();Fields fields = item.getFields();if (ObjectUtils.isNotEmpty(fields)) {//获取项目数据Project project = fields.getProject();if (ObjectUtils.isNotEmpty(project)) {jiraIssueAO.setProjectId(project.getId());jiraIssueAO.setProjectName(project.getName());}//获取类型信息IssueType issueType = fields.getIssuetype();if (ObjectUtils.isNotEmpty(issueType)) {for (JiraDic unit : issueTypeDic) {jiraIssueAO.setIssueTypeId(issueType.getId());if (unit.getJiraId().equals(issueType.getId())) {jiraIssueAO.setIssueTypeCode(unit.getCode());}}}//获取issue本身信息jiraIssueAO.setIssueId(item.getId());jiraIssueAO.setIssueName(item.getKey());//设置issue父issueIssueParent issueParent = fields.getParent();if (ObjectUtils.isNotEmpty(issueParent)) {jiraIssueAO.setParentIssueKey(issueParent.getKey());}//获取p值(类型为子任务或者故事)String p = "0.0";JsonArray issueJsonArray = returnData.getAsJsonArray("issues");JsonElement issueJsonElement = issueJsonArray.get(index);JsonObject fieldObject = issueJsonElement.getAsJsonObject().getAsJsonObject("fields");if (subtask.getJiraId().equals(issueType.getId())) {JsonElement jsonElement = fieldObject.get(points.getJiraId());if (!jsonElement.isJsonNull()) {p = jsonElement.getAsString();}jiraIssueAO.setPoints(new BigDecimal(p));//获取任务修复版本信息List<FixVersion> versions = fields.getFixVersions();if (ObjectUtils.isNotEmpty(versions)) {FixVersion fixVersion = versions.get(0);jiraIssueAO.setProjectVersionName(fixVersion.getName());jiraIssueAO.setProjectVersionId(fixVersion.getId());}}//如果类型为故事类型if (storyIncubateBase.getJiraId().equals(issueType.getId())||story.getJiraId().equals(issueType.getId())||storyBase.getJiraId().equals(issueType.getId())||storyIncubate.getJiraId().equals(issueType.getId())) {JsonElement jsonElement = fieldObject.get(storyPoints.getJiraId());if (ObjectUtils.isNotEmpty(jsonElement)&&!jsonElement.isJsonNull()) {p = jsonElement.getAsString();}jiraIssueAO.setPoints(new BigDecimal(p));//获取任务修复版本信息List<FixVersion> versions = fields.getFixVersions();if (ObjectUtils.isNotEmpty(versions)) {FixVersion fixVersion = versions.get(0);jiraIssueAO.setProjectVersionName(fixVersion.getName());jiraIssueAO.setProjectVersionId(fixVersion.getId());}}//获取缺陷发现阶段和责任人if (defect.getJiraId().equals(issueType.getId())) {JsonElement jsonElement = fieldObject.get(displayStep.getJiraId());if (!jsonElement.isJsonNull()) {JsonObject step = jsonElement.getAsJsonObject();JsonElement valueJsonElement = step.get("value");if (!valueJsonElement.isJsonNull()) {jiraIssueAO.setDisplayStepName(valueJsonElement.getAsString());}}//获取责任人JsonElement responsibleJsonElement = fieldObject.get(responsible.getJiraId());if(!responsibleJsonElement.isJsonNull()){JsonArray responsibleJsonArray = responsibleJsonElement.getAsJsonArray();List<String> responsibleKeys = new ArrayList<>();for (JsonElement unit : responsibleJsonArray) {JsonObject responsibleObj = unit.getAsJsonObject();String responsibleKey = ObjectUtils.isEmpty(responsibleObj.get("key")) ? "" : responsibleObj.get("key").getAsString();responsibleKeys.add(responsibleKey);}jiraIssueAO.setResponsible(responsibleKeys);}//获取缺陷影响版本信息List<FixVersion> versions = fields.getVersions();if (ObjectUtils.isNotEmpty(versions)) {FixVersion fixVersion = versions.get(0);jiraIssueAO.setProjectVersionName(fixVersion.getName());jiraIssueAO.setProjectVersionId(fixVersion.getId());}}//设置问题创建人Reporter reporter = fields.getReporter();if (ObjectUtils.isNotEmpty(reporter)) {jiraIssueAO.setJiraCreateKey(reporter.getKey());}Assignee assignee = fields.getAssignee();if (ObjectUtils.isNotEmpty(assignee)) {jiraIssueAO.setJiraAssigneeKey(assignee.getKey());}//设置任务创建时间更新时间jiraIssueAO.setCreated(fields.getCreated());jiraIssueAO.setUpdated(fields.getUpdated());//任务状态Status status = fields.getStatus();if (ObjectUtils.isNotEmpty(status)) {StatusCategory statusCategory = status.getStatusCategory();if (ObjectUtils.isNotEmpty(statusCategory)) {jiraIssueAO.setStatusKey(statusCategory.getKey());jiraIssueAO.setStatusName(statusCategory.getName());}}result.add(jiraIssueAO);index++;}}}} catch (Exception e) {log.error("同步失败", e);}return result;}private JiraDic getByKey(List<JiraDic> jiraDics,String key) {return jiraDics.stream().filter(e -> key.equals(e.getCode())).findFirst().get();}}