fix(测试跟踪): 非xpack同步jira缺陷报错
This commit is contained in:
parent
133f474d39
commit
6142f28f76
|
@ -153,9 +153,9 @@ public class IssuesController {
|
|||
return issuesService.getZentaoBuilds(request);
|
||||
}
|
||||
|
||||
@PostMapping("/sync")
|
||||
public boolean getPlatformIssue(@RequestBody IssueSyncRequest request) {
|
||||
return issuesService.syncThirdPartyIssues(request);
|
||||
@GetMapping("/sync/{projectId}")
|
||||
public boolean getPlatformIssue(@PathVariable String projectId) {
|
||||
return issuesService.syncThirdPartyIssues(projectId);
|
||||
}
|
||||
|
||||
@GetMapping("/sync/check/{projectId}")
|
||||
|
|
|
@ -886,9 +886,7 @@ public class IssuesService {
|
|||
List<String> projectIds = trackProjectService.getThirdPartProjectIds();
|
||||
projectIds.forEach(id -> {
|
||||
try {
|
||||
IssueSyncRequest request = new IssueSyncRequest();
|
||||
request.setProjectId(id);
|
||||
syncThirdPartyIssues(request);
|
||||
syncThirdPartyIssues(id);
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
}
|
||||
|
@ -931,38 +929,35 @@ public class IssuesService {
|
|||
stringRedisTemplate.delete(SYNC_THIRD_PARTY_ISSUES_KEY + ":" + projectId);
|
||||
}
|
||||
|
||||
public boolean syncThirdPartyIssues(IssueSyncRequest syncRequest) {
|
||||
if (StringUtils.isNotBlank(syncRequest.getProjectId())) {
|
||||
String syncValue = getSyncKey(syncRequest.getProjectId());
|
||||
public boolean syncThirdPartyIssues(String projectId) {
|
||||
if (StringUtils.isNotBlank(projectId)) {
|
||||
String syncValue = getSyncKey(projectId);
|
||||
if (StringUtils.isNotEmpty(syncValue)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
setSyncKey(syncRequest.getProjectId());
|
||||
setSyncKey(projectId);
|
||||
|
||||
Project project = baseProjectService.getProjectById(syncRequest.getProjectId());
|
||||
List<IssuesDao> issues = extIssuesMapper.getIssueForSync(syncRequest.getProjectId(), project.getPlatform());
|
||||
if (syncRequest.getCreateTime() != null) {
|
||||
issues = filterSyncIssuesByCreated(issues, syncRequest);
|
||||
}
|
||||
Project project = baseProjectService.getProjectById(projectId);
|
||||
List<IssuesDao> issues = extIssuesMapper.getIssueForSync(projectId, project.getPlatform());
|
||||
|
||||
if (CollectionUtils.isEmpty(issues)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
IssuesRequest issuesRequest = new IssuesRequest();
|
||||
issuesRequest.setProjectId(syncRequest.getProjectId());
|
||||
issuesRequest.setProjectId(projectId);
|
||||
issuesRequest.setWorkspaceId(project.getWorkspaceId());
|
||||
|
||||
try {
|
||||
if (!trackProjectService.isThirdPartTemplate(project)) {
|
||||
String defaultCustomFields = getDefaultCustomFields(syncRequest.getProjectId());
|
||||
String defaultCustomFields = getDefaultCustomFields(projectId);
|
||||
issuesRequest.setDefaultCustomFields(defaultCustomFields);
|
||||
}
|
||||
if (PlatformPluginService.isPluginPlatform(project.getPlatform())) {
|
||||
// 分批处理
|
||||
SubListUtil.dealForSubList(issues, 500, (subIssue) ->
|
||||
syncPluginThirdPartyIssues(subIssue, project));
|
||||
syncPluginThirdPartyIssues(subIssue, project, issuesRequest.getDefaultCustomFields()));
|
||||
} else {
|
||||
IssuesPlatform platform = IssueFactory.createPlatform(project.getPlatform(), issuesRequest);
|
||||
syncThirdPartyIssues(platform::syncIssues, project, issues);
|
||||
|
@ -970,13 +965,13 @@ public class IssuesService {
|
|||
} catch (Exception e) {
|
||||
throw e;
|
||||
} finally {
|
||||
deleteSyncKey(syncRequest.getProjectId());
|
||||
deleteSyncKey(projectId);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void syncPluginThirdPartyIssues(List<IssuesDao> issues, Project project) {
|
||||
public void syncPluginThirdPartyIssues(List<IssuesDao> issues, Project project, String defaultCustomFields) {
|
||||
List<PlatformIssuesDTO> platformIssues = JSON.parseArray(JSON.toJSONString(issues), PlatformIssuesDTO.class);
|
||||
platformIssues.stream().forEach(item -> {
|
||||
// 给缺陷添加自定义字段
|
||||
|
@ -991,6 +986,7 @@ public class IssuesService {
|
|||
});
|
||||
SyncIssuesRequest request = new SyncIssuesRequest();
|
||||
request.setIssues(platformIssues);
|
||||
request.setDefaultCustomFields(defaultCustomFields);
|
||||
request.setProjectConfig(PlatformPluginService.getCompatibleProjectConfig(project));
|
||||
Platform platform = platformPluginService.getPlatform(project.getPlatform());
|
||||
|
||||
|
@ -999,38 +995,39 @@ public class IssuesService {
|
|||
List<IssuesWithBLOBs> updateIssues = syncIssuesResult.getUpdateIssues();
|
||||
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
IssuesMapper issueBatchMapper = sqlSession.getMapper(IssuesMapper.class);
|
||||
AttachmentModuleRelationMapper batchAttachmentModuleRelationMapper = sqlSession.getMapper(AttachmentModuleRelationMapper.class);
|
||||
|
||||
// 批量更新
|
||||
updateIssues.stream()
|
||||
.map(item -> {
|
||||
IssuesWithBLOBs issuesWithBLOBs = new IssuesWithBLOBs();
|
||||
BeanUtils.copyBean(issuesWithBLOBs, item);
|
||||
return issuesWithBLOBs;
|
||||
})
|
||||
.forEach(issueBatchMapper::updateByPrimaryKeySelective);
|
||||
|
||||
// 批量删除
|
||||
syncIssuesResult.getDeleteIssuesIds()
|
||||
.stream()
|
||||
.forEach(issueBatchMapper::deleteByPrimaryKey);
|
||||
|
||||
try {
|
||||
// 同步附件
|
||||
syncPluginIssueAttachment(platform, syncIssuesResult, batchAttachmentModuleRelationMapper);
|
||||
IssuesMapper issueBatchMapper = sqlSession.getMapper(IssuesMapper.class);
|
||||
AttachmentModuleRelationMapper batchAttachmentModuleRelationMapper = sqlSession.getMapper(AttachmentModuleRelationMapper.class);
|
||||
|
||||
// 批量更新
|
||||
updateIssues.forEach(issueBatchMapper::updateByPrimaryKeySelective);
|
||||
|
||||
// 批量删除
|
||||
syncIssuesResult.getDeleteIssuesIds()
|
||||
.stream()
|
||||
.forEach(issueBatchMapper::deleteByPrimaryKey);
|
||||
|
||||
try {
|
||||
// 同步附件
|
||||
syncPluginIssueAttachment(platform, syncIssuesResult, batchAttachmentModuleRelationMapper);
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e);
|
||||
}
|
||||
|
||||
HashMap<String, List<CustomFieldResourceDTO>> customFieldMap = new HashMap<>();
|
||||
updateIssues.forEach(item -> {
|
||||
List<CustomFieldResourceDTO> customFieldResource = baseCustomFieldService.getCustomFieldResourceDTO(item.getCustomFields());
|
||||
customFieldMap.put(item.getId(), customFieldResource);
|
||||
});
|
||||
|
||||
// 修改自定义字段
|
||||
customFieldIssuesService.batchEditFields(customFieldMap);
|
||||
|
||||
sqlSession.commit();
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e);
|
||||
sqlSession.close();
|
||||
MSException.throwException(e);
|
||||
}
|
||||
|
||||
HashMap<String, List<CustomFieldResourceDTO>> customFieldMap = new HashMap<>();
|
||||
updateIssues.forEach(item -> {
|
||||
List<CustomFieldResourceDTO> customFieldResource = baseCustomFieldService.getCustomFieldResourceDTO(item.getCustomFields());
|
||||
customFieldMap.put(item.getId(), customFieldResource);
|
||||
});
|
||||
|
||||
// 修改自定义字段
|
||||
customFieldIssuesService.batchEditFields(customFieldMap);
|
||||
}
|
||||
|
||||
private void syncPluginIssueAttachment(Platform platform, SyncIssuesResult syncIssuesResult, AttachmentModuleRelationMapper batchAttachmentModuleRelationMapper) {
|
||||
|
@ -1049,8 +1046,8 @@ public class IssuesService {
|
|||
|
||||
List<PlatformAttachment> syncAttachments = attachmentMap.get(issueId);
|
||||
for (PlatformAttachment syncAttachment : syncAttachments) {
|
||||
jiraAttachmentSet.add(syncAttachment.getFileName());
|
||||
if (!attachmentsNameSet.contains(syncAttachment.getFileName())) {
|
||||
jiraAttachmentSet.add(syncAttachment.getFileName());
|
||||
try {
|
||||
byte[] content = platform.getAttachmentContent(syncAttachment.getFileKey());
|
||||
if (content == null) {
|
||||
|
|
|
@ -3,7 +3,6 @@ package io.metersphere.service.wapper;
|
|||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.service.PlatformPluginService;
|
||||
import io.metersphere.xpack.track.dto.request.IssuesRequest;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
@ -35,10 +34,7 @@ public class IssueProxyResourceService {
|
|||
MSException.throwException(Translator.get("invalid_parameter"));
|
||||
}
|
||||
if (StringUtils.isNotBlank(platform)) {
|
||||
IssuesRequest issuesRequest = new IssuesRequest();
|
||||
issuesRequest.setProjectId(projectId);
|
||||
issuesRequest.setWorkspaceId(workspaceId);
|
||||
return platformPluginService.getPlatform(platform)
|
||||
return platformPluginService.getPlatform(platform, workspaceId)
|
||||
.proxyForGet(url, byte[].class);
|
||||
|
||||
}
|
||||
|
|
|
@ -146,16 +146,18 @@ export function getRelateIssues(page) {
|
|||
});
|
||||
}
|
||||
|
||||
export function syncIssues(param) {
|
||||
let url = 'issues/sync';
|
||||
if (hasLicense()) {
|
||||
url = 'xpack/issue/sync';
|
||||
}
|
||||
export function syncAllIssues(param) {
|
||||
// 浏览器默认策略,请求同一个url,可能导致 stalled 时间过长,加个uuid防止请求阻塞
|
||||
url = url + "?stamp=" + getUUID();
|
||||
let url = 'xpack/issue/sync' + "?stamp=" + getUUID();
|
||||
return post(url, param);
|
||||
}
|
||||
|
||||
export function syncIssues() {
|
||||
// 浏览器默认策略,请求同一个url,可能导致 stalled 时间过长,加个uuid防止请求阻塞
|
||||
let url = 'issues/sync/' + getCurrentProjectID() + "?stamp=" + getUUID();
|
||||
return get(url);
|
||||
}
|
||||
|
||||
// 轮询同步状态
|
||||
export function checkSyncIssues(loading, isNotFirst) {
|
||||
let url = 'issues/sync/check/' + getCurrentProjectID() + "?stamp=" + getUUID();
|
||||
|
|
|
@ -7,7 +7,21 @@
|
|||
:create-tip="$t('test_track.issue.create_issue')"
|
||||
:tip="$t('commons.search_by_name_or_id')">
|
||||
<template v-slot:button>
|
||||
<ms-table-button icon="el-icon-refresh" :content="$t('test_track.issue.sync_bugs')" v-if="isThirdPart && hasPermission('PROJECT_TRACK_ISSUE:READ+CREATE')" @click="syncIssues"/>
|
||||
|
||||
<span v-if="isThirdPart && hasPermission('PROJECT_TRACK_ISSUE:READ+CREATE')">
|
||||
<ms-table-button
|
||||
v-if="hasLicense"
|
||||
icon="el-icon-refresh"
|
||||
:content="$t('test_track.issue.sync_bugs')"
|
||||
@click="syncAllIssues"/>
|
||||
<ms-table-button
|
||||
v-if="!hasLicense"
|
||||
icon="el-icon-refresh"
|
||||
:content="$t('test_track.issue.sync_bugs')"
|
||||
@click="syncIssues"/>
|
||||
</span>
|
||||
|
||||
|
||||
<ms-table-button icon="el-icon-upload2" :content="$t('commons.import')" v-if="hasPermission('PROJECT_TRACK_ISSUE:READ+CREATE')" @click="handleImport"/>
|
||||
<ms-table-button icon="el-icon-download" :content="$t('commons.export')" v-if="hasPermission('PROJECT_TRACK_ISSUE:READ')" @click="handleExport"/>
|
||||
</template>
|
||||
|
@ -195,7 +209,7 @@ import {
|
|||
getIssues,
|
||||
syncIssues,
|
||||
deleteIssue,
|
||||
getIssuesById, batchDeleteIssue, getPlatformOption
|
||||
getIssuesById, batchDeleteIssue, getPlatformOption, syncAllIssues
|
||||
} from "@/api/issue";
|
||||
import {
|
||||
getCustomFieldValue,
|
||||
|
@ -214,6 +228,7 @@ import {
|
|||
getAdvSearchCustomField
|
||||
} from "metersphere-frontend/src/components/search/custom-component";
|
||||
import MsMarkDownText from "metersphere-frontend/src/components/MsMarkDownText";
|
||||
import {hasLicense} from "metersphere-frontend/src/utils/permission";
|
||||
|
||||
export default {
|
||||
name: "IssueList",
|
||||
|
@ -269,7 +284,8 @@ export default {
|
|||
creatorFilters: [],
|
||||
loading: false,
|
||||
dataSelectRange: "",
|
||||
platformOptions: []
|
||||
platformOptions: [],
|
||||
hasLicense: false
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
|
@ -303,6 +319,8 @@ export default {
|
|||
.then((r) => {
|
||||
this.platformOptions = r.data;
|
||||
});
|
||||
|
||||
this.hasLicense = hasLicense();
|
||||
},
|
||||
computed: {
|
||||
platformFilters() {
|
||||
|
@ -467,7 +485,7 @@ export default {
|
|||
}
|
||||
return false;
|
||||
},
|
||||
syncIssues() {
|
||||
syncAllIssues() {
|
||||
this.$refs.issueSyncSelect.open();
|
||||
},
|
||||
handleImport() {
|
||||
|
@ -500,7 +518,20 @@ export default {
|
|||
"createTime": data.createTime.getTime(),
|
||||
"pre": data.preValue
|
||||
}
|
||||
syncIssues(param)
|
||||
syncAllIssues(param)
|
||||
.then((response) => {
|
||||
if (response.data === false) {
|
||||
checkSyncIssues(this.loading);
|
||||
} else {
|
||||
this.$success(this.$t('test_track.issue.sync_complete'));
|
||||
this.loading = false;
|
||||
this.getIssues();
|
||||
}
|
||||
});
|
||||
},
|
||||
syncIssues() {
|
||||
this.loading = true;
|
||||
syncIssues()
|
||||
.then((response) => {
|
||||
if (response.data === false) {
|
||||
checkSyncIssues(this.loading);
|
||||
|
|
Loading…
Reference in New Issue