feat: 禅道同步全量缺陷

This commit is contained in:
chenjianxing 2021-11-20 00:06:16 +08:00 committed by jianxing
parent 6e8991ea1f
commit efe9b3af9f
16 changed files with 233 additions and 196 deletions

View File

@ -61,6 +61,7 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
protected String key;
protected String workspaceId;
protected String userId;
protected String defaultCustomFields;
public String getKey() {
@ -92,6 +93,7 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
this.projectId = issuesRequest.getProjectId();
this.workspaceId = issuesRequest.getWorkspaceId();
this.userId = issuesRequest.getUserId();
this.defaultCustomFields = issuesRequest.getDefaultCustomFields();
}
public AbstractIssuePlatform() {
@ -382,7 +384,7 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
}
@Override
public void syncAllIssues(Project project, String defaultCustomFields) {}
public void syncAllIssues(Project project) {}
protected List<IssuesWithBLOBs> getIssuesByPlatformIds(List<String> platformIds) {
IssuesService issuesService = CommonBeanFactory.getBean(IssuesService.class);
@ -418,4 +420,26 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
}
return syncDeleteIds;
}
protected void mergeCustomField(IssuesWithBLOBs issues, String defaultCustomField) {
if (StringUtils.isNotBlank(defaultCustomField)) {
String issuesCustomFields = issues.getCustomFields();
if (StringUtils.isNotBlank(issuesCustomFields) || issuesCustomFields.startsWith("{")) issuesCustomFields = "[]";
JSONArray issueFields = JSONArray.parseArray(issuesCustomFields);
Set<String> ids = issueFields.stream().map(i -> ((JSONObject) i).getString("id")).collect(Collectors.toSet());
JSONArray defaultFields = JSONArray.parseArray(defaultCustomField);
defaultFields.forEach(item -> { // 如果自定义字段里没有模板新加的字段就把新字段加上
if (!ids.contains(((JSONObject) item).getString("id"))) {
issueFields.add(item);
}
});
issues.setCustomFields(issueFields.toJSONString());
}
}
public <T> T getConfig(String platform, Class<T> clazz) {
String config = getPlatformConfig(platform);
if (StringUtils.isBlank(config)) MSException.throwException("配置为空");
return JSONObject.parseObject(config, clazz);
}
}

View File

@ -69,5 +69,5 @@ public interface IssuesPlatform {
* 同步缺陷全量的缺陷
* @param project
*/
void syncAllIssues(Project project, String defaultCustomFields);
void syncAllIssues(Project project);
}

View File

@ -40,33 +40,12 @@ public class JiraPlatform extends AbstractIssuePlatform {
protected String key = IssuesManagePlatform.Jira.toString();
private JiraClientV2 jiraClientV2 = new JiraClientV2();
protected JiraClientV2 jiraClientV2;
public JiraPlatform(IssuesRequest issuesRequest) {
super(issuesRequest);
}
public JiraConfig getConfig() {
String config = getPlatformConfig(IssuesManagePlatform.Jira.toString());
JiraConfig jiraConfig = JSONObject.parseObject(config, JiraConfig.class);
validateConfig(jiraConfig);
return jiraConfig;
}
public JiraConfig getUserConfig() {
JiraConfig jiraConfig = null;
String config = getPlatformConfig(IssuesManagePlatform.Jira.toString());
if (StringUtils.isNotBlank(config)) {
jiraConfig = JSONObject.parseObject(config, JiraConfig.class);
UserDTO.PlatformInfo userPlatInfo = getUserPlatInfo(this.workspaceId);
if (userPlatInfo != null && StringUtils.isNotBlank(userPlatInfo.getJiraAccount())
&& StringUtils.isNotBlank(userPlatInfo.getJiraPassword())) {
jiraConfig.setAccount(userPlatInfo.getJiraAccount());
jiraConfig.setPassword(userPlatInfo.getJiraPassword());
}
}
validateConfig(jiraConfig);
return jiraConfig;
jiraClientV2 = new JiraClientV2();
setConfig();
}
@Override
@ -81,12 +60,16 @@ public class JiraPlatform extends AbstractIssuePlatform {
return issues;
}
public void parseIssue(IssuesWithBLOBs item, JiraIssue jiraIssue, String customFieldsStr) {
String lastmodify = "";
JSONObject fields = jiraIssue.getFields();
public IssuesWithBLOBs getUpdateIssue(IssuesWithBLOBs issue, JiraIssue jiraIssue) {
if (issue == null) {
issue = new IssuesWithBLOBs();
issue.setCustomFields(defaultCustomFields);
} else {
mergeCustomField(issue, defaultCustomFields);
}
JSONObject fields = jiraIssue.getFields();
String status = getStatus(fields);
JSONObject assignee = (JSONObject) fields.get("assignee");
String description = fields.getString("description");
Parser parser = Parser.builder().build();
@ -96,16 +79,15 @@ public class JiraPlatform extends AbstractIssuePlatform {
description = renderer.render(document);
}
if (assignee != null) {
lastmodify = assignee.getString("displayName");
}
item.setTitle(fields.getString("summary"));
item.setCreateTime(fields.getLong("created"));
item.setLastmodify(lastmodify);
item.setDescription(description);
item.setPlatformStatus(status);
item.setPlatform(IssuesManagePlatform.Jira.toString());
item.setCustomFields(syncIssueCustomField(customFieldsStr, jiraIssue.getFields()));
JSONObject assignee = (JSONObject) fields.get("assignee");
issue.setTitle(fields.getString("summary"));
issue.setCreateTime(fields.getLong("created"));
issue.setLastmodify(assignee == null ? "" : assignee.getString("displayName"));
issue.setDescription(description);
issue.setPlatformStatus(status);
issue.setPlatform(IssuesManagePlatform.Jira.toString());
issue.setCustomFields(syncIssueCustomField(issue.getCustomFields(), jiraIssue.getFields()));
return issue;
}
private String getStatus(JSONObject fields) {
@ -200,7 +182,8 @@ public class JiraPlatform extends AbstractIssuePlatform {
@Override
public void addIssue(IssuesUpdateRequest issuesRequest) {
JSONObject addJiraIssueParam = buildUpdateParam(issuesRequest);
JiraConfig jiraConfig = setUserConfig();
JSONObject addJiraIssueParam = buildUpdateParam(issuesRequest, jiraConfig.getIssuetype());
JiraAddIssueResponse result = jiraClientV2.addIssue(JSONObject.toJSONString(addJiraIssueParam));
JiraIssue issues = jiraClientV2.getIssues(result.getId());
@ -224,13 +207,10 @@ public class JiraPlatform extends AbstractIssuePlatform {
handleTestCaseIssues(issuesRequest);
}
private JSONObject buildUpdateParam(IssuesUpdateRequest issuesRequest) {
private JSONObject buildUpdateParam(IssuesUpdateRequest issuesRequest, String issuetypeStr) {
issuesRequest.setPlatform(IssuesManagePlatform.Jira.toString());
JiraConfig config = getUserConfig();
jiraClientV2.setConfig(config);
String jiraKey = validateJiraKey(issuesRequest.getProjectId());
JSONObject fields = new JSONObject();
@ -243,7 +223,7 @@ public class JiraPlatform extends AbstractIssuePlatform {
project.put("key", jiraKey);
JSONObject issuetype = new JSONObject();
issuetype.put("name", config.getIssuetype());
issuetype.put("name", issuetypeStr);
fields.put("summary", issuesRequest.getTitle());
// fields.put("description", new JiraIssueDescription(desc));
@ -254,7 +234,6 @@ public class JiraPlatform extends AbstractIssuePlatform {
addJiraIssueParam.put("fields", fields);
List<CustomFieldItemDTO> customFields = CustomFieldService.getCustomFields(issuesRequest.getCustomFields());
jiraClientV2.setConfig(config);
customFields.forEach(item -> {
String fieldName = item.getCustomData();
@ -293,7 +272,8 @@ public class JiraPlatform extends AbstractIssuePlatform {
@Override
public void updateIssue(IssuesUpdateRequest request) {
JSONObject param = buildUpdateParam(request);
JiraConfig jiraConfig = setUserConfig();
JSONObject param = buildUpdateParam(request, jiraConfig.getIssuetype());
handleIssueUpdate(request);
jiraClientV2.updateIssue(request.getPlatformId(), JSONObject.toJSONString(param));
}
@ -302,24 +282,17 @@ public class JiraPlatform extends AbstractIssuePlatform {
public void deleteIssue(String id) {
IssuesWithBLOBs issuesWithBLOBs = issuesMapper.selectByPrimaryKey(id);
super.deleteIssue(id);
setConfig();
jiraClientV2.deleteIssue(issuesWithBLOBs.getPlatformId());
}
@Override
public void testAuth() {
setConfig();
jiraClientV2.auth();
}
@Override
public void userAuth(UserDTO.PlatformInfo userInfo) {
String config = getPlatformConfig(IssuesManagePlatform.Jira.toString());
JiraConfig jiraConfig = JSONObject.parseObject(config, JiraConfig.class);
jiraConfig.setAccount(userInfo.getJiraAccount());
jiraConfig.setPassword(userInfo.getJiraPassword());
validateConfig(jiraConfig);
jiraClientV2.setConfig(jiraConfig);
setUserConfig(userInfo);
jiraClientV2.auth();
}
@ -330,12 +303,10 @@ public class JiraPlatform extends AbstractIssuePlatform {
@Override
public void syncIssues(Project project, List<IssuesDao> issues) {
setConfig();
issues.forEach(item -> {
setConfig();
try {
IssuesWithBLOBs issuesWithBLOBs = issuesMapper.selectByPrimaryKey(item.getId());
parseIssue(item, jiraClientV2.getIssues(item.getPlatformId()), issuesWithBLOBs.getCustomFields());
getUpdateIssue(item, jiraClientV2.getIssues(item.getPlatformId()));
String desc = htmlDesc2MsDesc(item.getDescription());
// 保留之前上传的图片
String images = getImages(issuesWithBLOBs.getDescription());
@ -364,9 +335,30 @@ public class JiraPlatform extends AbstractIssuePlatform {
return project.getJiraKey();
}
public JiraConfig getConfig() {
return getConfig(IssuesManagePlatform.Jira.toString(), JiraConfig.class);
}
public JiraConfig setConfig() {
JiraConfig config = getConfig();
validateConfig(config);
jiraClientV2.setConfig(config);
return config;
}
public JiraConfig setUserConfig(UserDTO.PlatformInfo userInfo) {
JiraConfig config = getConfig();
if (userInfo != null && StringUtils.isNotBlank(userInfo.getJiraAccount())
&& StringUtils.isNotBlank(userInfo.getJiraPassword())) {
config.setAccount(userInfo.getJiraAccount());
config.setPassword(userInfo.getJiraPassword());
}
validateConfig(config);
jiraClientV2.setConfig(config);
return config;
}
public JiraConfig setUserConfig() {
return setUserConfig(getUserPlatInfo(this.workspaceId));
}
}

View File

@ -27,12 +27,10 @@ import io.metersphere.track.request.testcase.IssuesRequest;
import io.metersphere.track.request.testcase.IssuesUpdateRequest;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.util.ArrayList;
import java.util.List;
@ -44,10 +42,12 @@ public class TapdPlatform extends AbstractIssuePlatform {
protected String key = IssuesManagePlatform.Tapd.toString();
protected TapdClient tapdClient = new TapdClient();
protected TapdClient tapdClient;
public TapdPlatform(IssuesRequest issueRequest) {
super(issueRequest);
tapdClient = new TapdClient();
setConfig();
}
@Override
@ -111,7 +111,6 @@ public class TapdPlatform extends AbstractIssuePlatform {
private MultiValueMap<String, Object> buildUpdateParam(IssuesUpdateRequest issuesRequest) {
issuesRequest.setPlatform(IssuesManagePlatform.Tapd.toString());
setConfig();
String tapdId = getProjectId(issuesRequest.getProjectId());
@ -156,19 +155,7 @@ public class TapdPlatform extends AbstractIssuePlatform {
@Override
public void testAuth() {
try {
String tapdConfig = getPlatformConfig(IssuesManagePlatform.Tapd.toString());
JSONObject object = JSON.parseObject(tapdConfig);
String account = object.getString("account");
String password = object.getString("password");
HttpHeaders headers = auth(account, password);
HttpEntity<MultiValueMap> requestEntity = new HttpEntity<>(headers);
RestTemplate restTemplate = new RestTemplate();
restTemplate.exchange("https://api.tapd.cn/quickstart/testauth", HttpMethod.GET, requestEntity, String.class);
} catch (Exception e) {
LogUtil.error(e.getMessage(), e);
MSException.throwException("验证失败!");
}
tapdClient.auth();
}
@Override
@ -179,16 +166,9 @@ public class TapdPlatform extends AbstractIssuePlatform {
@Override
public List<PlatformUser> getPlatformUser() {
List<PlatformUser> users = new ArrayList<>();
String id = getProjectId(projectId);
if (StringUtils.isBlank(id)) {
MSException.throwException("未关联Tapd项目ID");
}
String url = "https://api.tapd.cn/workspaces/users?workspace_id=" + id;
ResultHolder call = call(url);
String listJson = JSON.toJSONString(call.getData());
JSONArray jsonArray = JSON.parseArray(listJson);
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject o = jsonArray.getJSONObject(i);
JSONArray res = tapdClient.getPlatformUser(projectId);
for (int i = 0; i < res.size(); i++) {
JSONObject o = res.getJSONObject(i);
PlatformUser user = o.getObject("UserWorkspace", PlatformUser.class);
users.add(user);
}
@ -212,8 +192,6 @@ public class TapdPlatform extends AbstractIssuePlatform {
return;
}
setConfig();
Map<String, String> statusMap = tapdClient.getStatusMap(project.getTapdId());
while (count == limit) {
@ -244,7 +222,12 @@ public class TapdPlatform extends AbstractIssuePlatform {
}
protected IssuesWithBLOBs getUpdateIssue(IssuesWithBLOBs issue, JSONObject bug, Map<String, String> statusMap) {
if (issue == null) issue = new IssuesWithBLOBs();
if (issue == null) {
issue = new IssuesWithBLOBs();
issue.setCustomFields(defaultCustomFields);
} else {
mergeCustomField(issue, defaultCustomFields);
}
TapdBug bugObj = JSONObject.parseObject(bug.toJSONString(), TapdBug.class);
BeanUtils.copyBean(issue, bugObj);
issue.setPlatformStatus(statusMap.get(bugObj.getStatus()));
@ -265,10 +248,13 @@ public class TapdPlatform extends AbstractIssuePlatform {
}
public TapdConfig getConfig() {
String config = getPlatformConfig(IssuesManagePlatform.Tapd.toString());
TapdConfig tapdConfig = JSONObject.parseObject(config, TapdConfig.class);
// validateConfig(tapdConfig);
return tapdConfig;
return getConfig(IssuesManagePlatform.Tapd.toString(), TapdConfig.class);
}
public TapdConfig setConfig() {
TapdConfig config = getConfig();
tapdClient.setConfig(config);
return config;
}
public String getReporter() {
@ -279,12 +265,6 @@ public class TapdPlatform extends AbstractIssuePlatform {
return null;
}
public TapdConfig setConfig() {
TapdConfig config = getConfig();
tapdClient.setConfig(config);
return config;
}
private ResultHolder call(String url) {
return call(url, HttpMethod.GET, null);
}

View File

@ -7,12 +7,12 @@ import org.apache.commons.lang3.StringUtils;
public class ZentaoFactory {
public static ZentaoClient getInstance(String url, String type) {
public static ZentaoClient getInstance(String type) {
if (StringUtils.equals(type, "PATH_INFO")) {
return new ZentaoPathInfoClient(url);
return new ZentaoPathInfoClient();
} else if (StringUtils.equals(type, "GET")) {
return new ZentaoGetClient(url);
return new ZentaoGetClient();
}
return new ZentaoPathInfoClient(url);
return new ZentaoPathInfoClient();
}
}

View File

@ -14,6 +14,7 @@ import io.metersphere.track.dto.DemandDTO;
import io.metersphere.track.issue.client.ZentaoClient;
import io.metersphere.track.issue.domain.PlatformUser;
import io.metersphere.track.issue.domain.zentao.AddIssueResponse;
import io.metersphere.track.issue.domain.zentao.GetIssueResponse;
import io.metersphere.track.issue.domain.zentao.ZentaoBuild;
import io.metersphere.track.issue.domain.zentao.ZentaoConfig;
import io.metersphere.track.request.testcase.IssuesRequest;
@ -34,37 +35,16 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ZentaoPlatform extends AbstractIssuePlatform {
/**
* zentao account
*/
private final String account;
/**
* zentao password
*/
private final String password;
/**
* zentao url eg:http://x.x.x.x/zentao
*/
private final String url;
private final ZentaoClient zentaoClient;
protected final ZentaoClient zentaoClient;
protected String key = IssuesManagePlatform.Zentao.toString();
public ZentaoPlatform(IssuesRequest issuesRequest) {
super(issuesRequest);
String config = getPlatformConfig(IssuesManagePlatform.Zentao.toString());
// todo
if (StringUtils.isBlank(config)) {
MSException.throwException("未集成禅道平台!");
}
JSONObject object = JSON.parseObject(config);
this.account = object.getString("account");
this.password = object.getString("password");
this.url = object.getString("url");
String type = object.getString("request");
ZentaoConfig zentaoConfig = getConfig();
this.workspaceId = issuesRequest.getWorkspaceId();
this.zentaoClient = ZentaoFactory.getInstance(this.url, type);
this.zentaoClient = ZentaoFactory.getInstance(zentaoConfig.getRequest());
this.zentaoClient.setConfig(zentaoConfig);
}
@Override
@ -94,7 +74,6 @@ public class ZentaoPlatform extends AbstractIssuePlatform {
//getTestStories
List<DemandDTO> list = new ArrayList<>();
try {
setConfig();
String session = zentaoClient.login();
String key = getProjectId(projectId);
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(new HttpHeaders());
@ -146,31 +125,36 @@ public class ZentaoPlatform extends AbstractIssuePlatform {
return list;
}
public IssuesDao getZentaoIssues(IssuesDao issue) {
JSONObject bug = zentaoClient.getBugById(issue.getPlatformId());
String description = bug.getString("steps");
public IssuesWithBLOBs getUpdateIssues(IssuesWithBLOBs issue, JSONObject bug) {
GetIssueResponse.Issue bugObj = JSONObject.parseObject(bug.toJSONString(), GetIssueResponse.Issue.class);
String description = bugObj.getSteps();
String steps = description;
try {
steps = zentao2MsDescription(description);
} catch (Exception e) {
LogUtil.error(e.getMessage(), e);
}
IssuesDao issues = new IssuesDao();
issues.setPlatformStatus(bug.getString("status"));
if (StringUtils.equals(bug.getString("deleted"),"1")) {
issues.setPlatformStatus(IssuesStatus.DELETE.toString());
issuesMapper.updateByPrimaryKeySelective(issues);
if (issue == null) {
issue = new IssuesWithBLOBs();
issue.setCustomFields(defaultCustomFields);
} else {
mergeCustomField(issue, defaultCustomFields);
}
issues.setTitle(bug.getString("title"));
issues.setDescription(steps);
issues.setReporter(bug.getString("openedBy"));
IssuesWithBLOBs issuesWithBLOBs = issuesMapper.selectByPrimaryKey(issue.getId());
issuesWithBLOBs.setCustomFields(syncIssueCustomField(issuesWithBLOBs.getCustomFields(), bug));
return issues;
issue.setPlatformStatus(bugObj.getStatus());
if (StringUtils.equals(bugObj.getDeleted(),"1")) {
issue.setPlatformStatus(IssuesStatus.DELETE.toString());
issuesMapper.updateByPrimaryKeySelective(issue);
}
issue.setTitle(bugObj.getTitle());
issue.setDescription(steps);
issue.setReporter(bugObj.getOpenedBy());
issue.setCustomFields(syncIssueCustomField(issue.getCustomFields(), bug));
return issue;
}
@Override
public void addIssue(IssuesUpdateRequest issuesRequest) {
setUserConfig();
MultiValueMap<String, Object> param = buildUpdateParam(issuesRequest);
AddIssueResponse.Issue issue = zentaoClient.addIssue(param);
@ -196,16 +180,14 @@ public class ZentaoPlatform extends AbstractIssuePlatform {
@Override
public void updateIssue(IssuesUpdateRequest request) {
setUserConfig();
MultiValueMap<String, Object> param = buildUpdateParam(request);
handleIssueUpdate(request);
zentaoClient.setConfig(getUserConfig());
zentaoClient.updateIssue(request.getPlatformId(), param);
}
private MultiValueMap<String, Object> buildUpdateParam(IssuesUpdateRequest issuesRequest) {
issuesRequest.setPlatform(IssuesManagePlatform.Zentao.toString());
zentaoClient.setConfig(getUserConfig());
String projectId = getProjectId(issuesRequest.getProjectId());
if (StringUtils.isBlank(projectId)) {
MSException.throwException("未关联禅道项目ID.");
@ -245,59 +227,47 @@ public class ZentaoPlatform extends AbstractIssuePlatform {
public void deleteIssue(String id) {
IssuesWithBLOBs issuesWithBLOBs = issuesMapper.selectByPrimaryKey(id);
super.deleteIssue(id);
zentaoClient.setConfig(getUserConfig());
zentaoClient.deleteIssue(issuesWithBLOBs.getPlatformId());
}
@Override
public void testAuth() {
setConfig();
zentaoClient.login();
}
@Override
public void userAuth(UserDTO.PlatformInfo userInfo) {
String config = getPlatformConfig(IssuesManagePlatform.Zentao.toString());
ZentaoConfig zentaoConfig = JSONObject.parseObject(config, ZentaoConfig.class);
zentaoConfig.setAccount(userInfo.getZentaoUserName());
zentaoConfig.setPassword(userInfo.getZentaoPassword());
zentaoClient.setConfig(zentaoConfig);
setUserConfig();
zentaoClient.login();
}
public ZentaoConfig getConfig() {
return getConfig(IssuesManagePlatform.Zentao.toString(), ZentaoConfig.class);
}
public ZentaoConfig setConfig() {
ZentaoConfig config = getConfig();
zentaoClient.setConfig(config);
return config;
}
public ZentaoConfig getConfig() {
ZentaoConfig zentaoConfig = null;
String config = getPlatformConfig(IssuesManagePlatform.Zentao.toString());
zentaoConfig = JSONObject.parseObject(config, ZentaoConfig.class);
// validateConfig(tapdConfig);
return zentaoConfig;
public ZentaoConfig setUserConfig() {
return setUserConfig(getUserPlatInfo(this.workspaceId));
}
public ZentaoConfig getUserConfig() {
ZentaoConfig zentaoConfig = null;
String config = getPlatformConfig(IssuesManagePlatform.Zentao.toString());
if (StringUtils.isNotBlank(config)) {
zentaoConfig = JSONObject.parseObject(config, ZentaoConfig.class);
UserDTO.PlatformInfo userPlatInfo = getUserPlatInfo(this.workspaceId);
if (userPlatInfo != null && StringUtils.isNotBlank(userPlatInfo.getZentaoUserName())
&& StringUtils.isNotBlank(userPlatInfo.getZentaoPassword())) {
zentaoConfig.setAccount(userPlatInfo.getZentaoUserName());
zentaoConfig.setPassword(userPlatInfo.getZentaoPassword());
}
public ZentaoConfig setUserConfig(UserDTO.PlatformInfo userPlatInfo) {
ZentaoConfig zentaoConfig = getConfig();
if (userPlatInfo != null && StringUtils.isNotBlank(userPlatInfo.getZentaoUserName())
&& StringUtils.isNotBlank(userPlatInfo.getZentaoPassword())) {
zentaoConfig.setAccount(userPlatInfo.getZentaoUserName());
zentaoConfig.setPassword(userPlatInfo.getZentaoPassword());
}
// validateConfig(jiraConfig);
zentaoClient.setConfig(zentaoConfig);
return zentaoConfig;
}
@Override
public List<PlatformUser> getPlatformUser() {
setConfig();
String session = zentaoClient.login();;
HttpHeaders httpHeaders = new HttpHeaders();
HttpEntity<MultiValueMap<String,String>> requestEntity = new HttpEntity<>(httpHeaders);
@ -328,15 +298,15 @@ public class ZentaoPlatform extends AbstractIssuePlatform {
@Override
public void syncIssues(Project project, List<IssuesDao> issues) {
issues.forEach(item -> {
setConfig();
IssuesDao issuesDao = getZentaoIssues(item);
issuesDao.setId(item.getId());
issuesMapper.updateByPrimaryKeySelective(issuesDao);
IssuesWithBLOBs issue = issuesMapper.selectByPrimaryKey(item.getId());
JSONObject bug = zentaoClient.getBugById(item.getPlatformId());
issue = getUpdateIssues(issue, bug);
issue.setId(item.getId());
issuesMapper.updateByPrimaryKeySelective(issue);
});
}
public List<ZentaoBuild> getBuilds() {
setConfig();
String session = zentaoClient.login();;
String projectId1 = getProjectId(projectId);
HttpHeaders httpHeaders = new HttpHeaders();
@ -368,7 +338,6 @@ public class ZentaoPlatform extends AbstractIssuePlatform {
private String uploadFile(FileSystemResource resource) {
String id = "";
zentaoClient.setConfig(getUserConfig());
String session = zentaoClient.login();
HttpHeaders httpHeaders = new HttpHeaders();
MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<>();

View File

@ -6,6 +6,7 @@ import io.metersphere.track.issue.domain.Jira.JiraAddIssueResponse;
import io.metersphere.track.issue.domain.Jira.JiraConfig;
import io.metersphere.track.issue.domain.Jira.JiraField;
import io.metersphere.track.issue.domain.Jira.JiraIssue;
import io.metersphere.track.issue.domain.Jira.JiraIssueListResponse;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.*;
@ -124,4 +125,10 @@ public abstract class JiraAbstractClient extends BaseClient {
USER_NAME = config.getAccount();
PASSWD = config.getPassword();
}
public JiraIssueListResponse getProjectIssues(int startAt, int maxResults, String projectKey) {
ResponseEntity<String> responseEntity;
responseEntity = restTemplate.exchange(getBaseUrl() + "/search?startAt={1}&maxResults={2}&jql=project={3}", HttpMethod.GET, getAuthHttpEntity(), String.class, startAt, maxResults, projectKey);
return (JiraIssueListResponse)getResultForObject(JiraIssueListResponse.class, responseEntity);
}
}

View File

@ -1,5 +1,6 @@
package io.metersphere.track.issue.client;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.LogUtil;
@ -14,6 +15,7 @@ import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.util.List;
import java.util.Map;
@ -41,6 +43,22 @@ public class TapdClient extends BaseClient {
return JSONObject.parseObject(data, Map.class);
}
public JSONArray getPlatformUser(String projectId) {
String url = getBaseUrl() + "/workspaces/users?workspace_id=" + projectId;
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, getAuthHttpEntity(), String.class, projectId);
return JSONArray.parseArray(response.getBody());
}
public void auth() {
try {
RestTemplate restTemplate = new RestTemplate();
restTemplate.exchange("https://api.tapd.cn/quickstart/testauth", HttpMethod.GET, getAuthHttpEntity(), String.class);
} catch (Exception e) {
LogUtil.error(e.getMessage(), e);
MSException.throwException("验证失败: " + e.getMessage());
}
}
public TapdGetIssueResponse getIssueForPageByIds(String projectId, int pageNum, int limit, List<String> ids) {
String url = getBaseUrl() + "/bugs?workspace_id={1}&page={2}&limit={3}&fields={4}";
StringBuilder idStr = new StringBuilder();

View File

@ -1,5 +1,6 @@
package io.metersphere.track.issue.client;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.LogUtil;
@ -24,9 +25,7 @@ public abstract class ZentaoClient extends BaseClient {
public RequestUrl requestUrl;
protected String url;
public ZentaoClient(String url) {
ENDPOINT = url;
}
private static final String BUG_LIST_URL="?m=bug&f=browse&productID={0}&branch=&browseType=&param=0&orderBy=&pageID={1}&recPerPage={2}&t=json&zentaosid=";
public String login() {
GetUserResponse getUserResponse = new GetUserResponse();
@ -115,6 +114,13 @@ public abstract class ZentaoClient extends BaseClient {
return JSONObject.parseObject(getIssueResponse.getData());
}
public JSONArray getBugsByProjectId(String projectId, int pageNum, int pageSize) {
String sessionId = login();
ResponseEntity<String> response = restTemplate.exchange(getBaseUrl() + BUG_LIST_URL,
HttpMethod.GET, null, String.class, projectId, pageNum, pageSize, sessionId);
return JSONObject.parseObject(response.getBody()).getJSONObject("data").getJSONArray("bugs");
}
protected String getBaseUrl() {
if (ENDPOINT.endsWith("/")) {
return ENDPOINT.substring(0, ENDPOINT.length() - 1);

View File

@ -37,10 +37,6 @@ public class ZentaoGetClient extends ZentaoClient {
requestUrl = request;
}
public ZentaoGetClient(String url) {
super(url);
}
private String getUrl(String url) {
return getBaseUrl() + "/?m=api&f=getModel" + url;
}

View File

@ -20,7 +20,7 @@ public class ZentaoPathInfoClient extends ZentaoClient {
private static final String REPLACE_IMG_URL = "<img src=\"/zentao/file-read-$1\"/>";
private static final Pattern IMG_PATTERN = Pattern.compile("file-read-(.*?)\"/>");
RequestUrl request = new RequestUrl();
protected RequestUrl request = new RequestUrl();
{
request.setLogin(getUrl(LOGIN));
@ -38,11 +38,7 @@ public class ZentaoPathInfoClient extends ZentaoClient {
requestUrl = request;
}
public ZentaoPathInfoClient(String url) {
super(url);
}
private String getUrl(String url) {
protected String getUrl(String url) {
return getBaseUrl() + url;
}
}

View File

@ -0,0 +1,16 @@
package io.metersphere.track.issue.domain.Jira;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class JiraIssueListResponse {
private String expand;
private int startAt;
private int maxResults;
private int total;
private List<JiraIssue> issues;
}

View File

@ -10,4 +10,5 @@ public class ZentaoConfig {
private String password;
private String url;
private String requestType;
private String request;
}

View File

@ -36,4 +36,5 @@ public class IssuesRequest extends BaseQueryRequest {
private String requestType;
private String status;
private String defaultCustomFields;
}

View File

@ -1,6 +1,7 @@
package io.metersphere.track.service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
@ -12,11 +13,13 @@ import io.metersphere.commons.constants.IssuesStatus;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.*;
import io.metersphere.controller.request.IntegrationRequest;
import io.metersphere.dto.CustomFieldTemplateDao;
import io.metersphere.dto.IssueTemplateDao;
import io.metersphere.log.utils.ReflexObjectUtil;
import io.metersphere.log.vo.DetailColumn;
import io.metersphere.log.vo.OperatingLogDetails;
import io.metersphere.log.vo.track.TestPlanReference;
import io.metersphere.notice.service.NoticeSendService;
import io.metersphere.service.CustomFieldTemplateService;
import io.metersphere.service.IntegrationService;
import io.metersphere.service.IssueTemplateService;
import io.metersphere.service.ProjectService;
@ -59,15 +62,13 @@ public class IssuesService {
@Resource
private IssuesMapper issuesMapper;
@Resource
private NoticeSendService noticeSendService;
@Resource
private TestCaseIssuesMapper testCaseIssuesMapper;
@Resource
private IssueTemplateMapper issueTemplateMapper;
@Resource
private ExtIssuesMapper extIssuesMapper;
@Resource
private WorkspaceMapper workspaceMapper;
private CustomFieldTemplateService customFieldTemplateService;
@Resource
private IssueTemplateService issueTemplateService;
@Resource
@ -442,6 +443,9 @@ public class IssuesService {
IssuesRequest issuesRequest = new IssuesRequest();
issuesRequest.setProjectId(projectId);
issuesRequest.setWorkspaceId(project.getWorkspaceId());
String defaultCustomFields = getDefaultCustomFields(projectId);
issuesRequest.setDefaultCustomFields(defaultCustomFields);
if (CollectionUtils.isNotEmpty(tapdIssues)) {
TapdPlatform tapdPlatform = new TapdPlatform(issuesRequest);
syncThirdPartyIssues(tapdPlatform::syncIssues, project, tapdIssues);
@ -468,6 +472,33 @@ public class IssuesService {
}
}
/**
* 获取默认的自定义字段的取值同步之后更新成第三方平台的值
* @param projectId
* @return
*/
public String getDefaultCustomFields(String projectId) {
IssueTemplateDao template = issueTemplateService.getTemplate(projectId);
CustomFieldTemplate request = new CustomFieldTemplate();
request.setTemplateId(template.getId());
List<CustomFieldTemplateDao> customFields = customFieldTemplateService.list(request);
JSONArray fields = new JSONArray();
customFields.forEach(item -> {
JSONObject field = new JSONObject(true);
field.put("customData", item.getCustomData());
field.put("id", item.getId());
field.put("name", item.getName());
field.put("type", item.getType());
String defaultValue = item.getDefaultValue();
if (StringUtils.isNotBlank(defaultValue)) {
field.put("value", JSONObject.parse(defaultValue));
}
fields.add(field);
});
return fields.toJSONString();
}
public void syncThirdPartyIssues(BiConsumer<Project, List<IssuesDao>> syncFuc, Project project, List<IssuesDao> issues) {
try {
syncFuc.accept(project, issues);

@ -1 +1 @@
Subproject commit 1a1a00814f367d827975b524781771b74a7e7938
Subproject commit b699018b5e5cd513f24a3db091c97280f859b54e