fix(测试跟踪): 同步缺陷异步执行无法获取请求头
This commit is contained in:
parent
136117de74
commit
1cc2326c6f
|
@ -26,6 +26,7 @@ import io.metersphere.request.testcase.AuthUserIssueRequest;
|
||||||
import io.metersphere.request.testcase.IssuesCountRequest;
|
import io.metersphere.request.testcase.IssuesCountRequest;
|
||||||
import io.metersphere.service.BaseCheckPermissionService;
|
import io.metersphere.service.BaseCheckPermissionService;
|
||||||
import io.metersphere.service.IssuesService;
|
import io.metersphere.service.IssuesService;
|
||||||
|
import io.metersphere.service.IssuesSyncService;
|
||||||
import io.metersphere.service.PlatformPluginService;
|
import io.metersphere.service.PlatformPluginService;
|
||||||
import io.metersphere.xpack.track.dto.*;
|
import io.metersphere.xpack.track.dto.*;
|
||||||
import io.metersphere.xpack.track.dto.request.IssuesRequest;
|
import io.metersphere.xpack.track.dto.request.IssuesRequest;
|
||||||
|
@ -47,6 +48,8 @@ public class IssuesController {
|
||||||
@Resource
|
@Resource
|
||||||
private IssuesService issuesService;
|
private IssuesService issuesService;
|
||||||
@Resource
|
@Resource
|
||||||
|
private IssuesSyncService issuesSyncService;
|
||||||
|
@Resource
|
||||||
private BaseCheckPermissionService baseCheckPermissionService;
|
private BaseCheckPermissionService baseCheckPermissionService;
|
||||||
@Resource
|
@Resource
|
||||||
private PlatformPluginService platformPluginService;
|
private PlatformPluginService platformPluginService;
|
||||||
|
@ -159,12 +162,12 @@ public class IssuesController {
|
||||||
|
|
||||||
@GetMapping("/sync/{projectId}")
|
@GetMapping("/sync/{projectId}")
|
||||||
public void syncThirdPartyIssues(@PathVariable String projectId) {
|
public void syncThirdPartyIssues(@PathVariable String projectId) {
|
||||||
issuesService.syncThirdPartyIssues(projectId);
|
issuesSyncService.syncIssues(projectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/sync/all")
|
@PostMapping("/sync/all")
|
||||||
public void syncThirdPartyAllIssues(@RequestBody IssueSyncRequest request) {
|
public void syncThirdPartyAllIssues(@RequestBody IssueSyncRequest request) {
|
||||||
issuesService.syncThirdPartyAllIssues(request);
|
issuesSyncService.syncAllIssues(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/sync/check/{projectId}")
|
@GetMapping("/sync/check/{projectId}")
|
||||||
|
|
|
@ -72,6 +72,7 @@ import org.apache.ibatis.session.SqlSessionFactory;
|
||||||
import org.mybatis.spring.SqlSessionUtils;
|
import org.mybatis.spring.SqlSessionUtils;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
|
import org.springframework.scheduling.annotation.Async;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Propagation;
|
import org.springframework.transaction.annotation.Propagation;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
@ -95,6 +96,9 @@ public class IssuesService {
|
||||||
@Resource
|
@Resource
|
||||||
private TrackProjectService trackProjectService;
|
private TrackProjectService trackProjectService;
|
||||||
@Resource
|
@Resource
|
||||||
|
@Lazy
|
||||||
|
private IssuesSyncService issuesSyncService;
|
||||||
|
@Resource
|
||||||
private BaseUserService baseUserService;
|
private BaseUserService baseUserService;
|
||||||
@Resource
|
@Resource
|
||||||
private BaseProjectService baseProjectService;
|
private BaseProjectService baseProjectService;
|
||||||
|
@ -146,9 +150,6 @@ public class IssuesService {
|
||||||
private UserService userService;
|
private UserService userService;
|
||||||
@Resource
|
@Resource
|
||||||
private BasePluginService basePluginService;
|
private BasePluginService basePluginService;
|
||||||
@Resource
|
|
||||||
@Lazy
|
|
||||||
private IssuesService issuesService;
|
|
||||||
|
|
||||||
private static final String SYNC_THIRD_PARTY_ISSUES_KEY = "ISSUE:SYNC";
|
private static final String SYNC_THIRD_PARTY_ISSUES_KEY = "ISSUE:SYNC";
|
||||||
private static final String SYNC_THIRD_PARTY_ISSUES_ERROR_KEY = "ISSUE:SYNC:ERROR";
|
private static final String SYNC_THIRD_PARTY_ISSUES_ERROR_KEY = "ISSUE:SYNC:ERROR";
|
||||||
|
@ -877,8 +878,7 @@ public class IssuesService {
|
||||||
List<String> projectIds = trackProjectService.getThirdPartProjectIds();
|
List<String> projectIds = trackProjectService.getThirdPartProjectIds();
|
||||||
projectIds.forEach(id -> {
|
projectIds.forEach(id -> {
|
||||||
try {
|
try {
|
||||||
// 使用代理对象调用,防止事务注解失效
|
issuesSyncService.syncIssues(id);
|
||||||
issuesService.syncThirdPartyIssues(id);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e.getMessage(), e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
@ -941,47 +941,29 @@ public class IssuesService {
|
||||||
stringRedisTemplate.delete(SYNC_THIRD_PARTY_ISSUES_ERROR_KEY + ":" + projectId);
|
stringRedisTemplate.delete(SYNC_THIRD_PARTY_ISSUES_ERROR_KEY + ":" + projectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Async
|
||||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||||
public void syncThirdPartyIssues(String projectId) {
|
public void syncThirdPartyIssues(List<IssuesDao> issues, IssuesRequest issuesRequest, Project project) {
|
||||||
if (StringUtils.isNotBlank(projectId)) {
|
try {
|
||||||
String syncValue = getSyncKey(projectId);
|
if (PlatformPluginService.isPluginPlatform(project.getPlatform())) {
|
||||||
if (StringUtils.isEmpty(syncValue)) {
|
// 分批处理
|
||||||
setSyncKey(projectId);
|
SubListUtil.dealForSubList(issues, 500, (subIssue) ->
|
||||||
Project project = baseProjectService.getProjectById(projectId);
|
syncPluginThirdPartyIssues(subIssue, project, issuesRequest.getDefaultCustomFields()));
|
||||||
List<IssuesDao> issues = extIssuesMapper.getIssueForSync(projectId, project.getPlatform());
|
} else {
|
||||||
|
IssuesPlatform platform = IssueFactory.createPlatform(project.getPlatform(), issuesRequest);
|
||||||
if (CollectionUtils.isEmpty(issues)) {
|
syncThirdPartyIssues(platform::syncIssues, project, issues);
|
||||||
deleteSyncKey(projectId);
|
|
||||||
} else {
|
|
||||||
new Thread(() -> {
|
|
||||||
IssuesRequest issuesRequest = new IssuesRequest();
|
|
||||||
issuesRequest.setProjectId(projectId);
|
|
||||||
issuesRequest.setWorkspaceId(project.getWorkspaceId());
|
|
||||||
try {
|
|
||||||
issuesRequest.setDefaultCustomFields(getDefaultCustomField(project));
|
|
||||||
if (PlatformPluginService.isPluginPlatform(project.getPlatform())) {
|
|
||||||
// 分批处理
|
|
||||||
SubListUtil.dealForSubList(issues, 500, (subIssue) ->
|
|
||||||
syncPluginThirdPartyIssues(subIssue, project, issuesRequest.getDefaultCustomFields()));
|
|
||||||
} else {
|
|
||||||
IssuesPlatform platform = IssueFactory.createPlatform(project.getPlatform(), issuesRequest);
|
|
||||||
syncThirdPartyIssues(platform::syncIssues, project, issues);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogUtil.error(e);
|
|
||||||
// 同步缺陷异常, 当前同步错误信息 -> Redis(check接口获取)
|
|
||||||
setSyncErrorMsg(projectId, e.getMessage());
|
|
||||||
} finally {
|
|
||||||
// 异常或正常结束都得删除当前项目执行同步的Key
|
|
||||||
deleteSyncKey(projectId);
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.error(e);
|
||||||
|
// 同步缺陷异常, 当前同步错误信息 -> Redis(check接口获取)
|
||||||
|
setSyncErrorMsg(project.getId(), e.getMessage());
|
||||||
|
} finally {
|
||||||
|
// 异常或正常结束都得删除当前项目执行同步的Key
|
||||||
|
deleteSyncKey(project.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getDefaultCustomField(Project project) {
|
public String getDefaultCustomField(Project project) {
|
||||||
if (isThirdPartTemplate(project)) {
|
if (isThirdPartTemplate(project)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1938,35 +1920,21 @@ public class IssuesService {
|
||||||
&& platformPluginService.isThirdPartTemplateSupport(project.getPlatform());
|
&& platformPluginService.isThirdPartTemplateSupport(project.getPlatform());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void syncThirdPartyAllIssues(IssueSyncRequest syncRequest) {
|
@Async
|
||||||
syncRequest.setProjectId(syncRequest.getProjectId());
|
public void syncThirdPartyAllIssues(IssueSyncRequest syncRequest, Project project) {
|
||||||
XpackIssueService xpackIssueService = CommonBeanFactory.getBean(XpackIssueService.class);
|
try {
|
||||||
if (StringUtils.isNotBlank(syncRequest.getProjectId())) {
|
XpackIssueService xpackIssueService = CommonBeanFactory.getBean(XpackIssueService.class);
|
||||||
// 获取当前项目执行同步缺陷Key
|
xpackIssueService.syncThirdPartyIssues(project, syncRequest);
|
||||||
String syncValue = getSyncKey(syncRequest.getProjectId());
|
if (platformPluginService.isPluginPlatform(project.getPlatform())) {
|
||||||
if (StringUtils.isEmpty(syncValue)) {
|
syncAllPluginIssueAttachment(project, syncRequest);
|
||||||
// 同步Key不存在, 设置保证唯一性, 并开始同步
|
|
||||||
setSyncKey(syncRequest.getProjectId());
|
|
||||||
new Thread(() -> {
|
|
||||||
try {
|
|
||||||
Project project = baseProjectService.getProjectById(syncRequest.getProjectId());
|
|
||||||
if (!isThirdPartTemplate(project)) {
|
|
||||||
syncRequest.setDefaultCustomFields(getDefaultCustomFields(syncRequest.getProjectId()));
|
|
||||||
}
|
|
||||||
xpackIssueService.syncThirdPartyIssues(project, syncRequest);
|
|
||||||
if (platformPluginService.isPluginPlatform(project.getPlatform())) {
|
|
||||||
syncAllPluginIssueAttachment(project, syncRequest);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogUtil.error(e);
|
|
||||||
// 同步缺陷异常, 当前同步错误信息 -> Redis(check接口获取)
|
|
||||||
setSyncErrorMsg(syncRequest.getProjectId(), e.getMessage());
|
|
||||||
} finally {
|
|
||||||
// 异常或正常结束都得删除当前项目执行同步的Key
|
|
||||||
deleteSyncKey(syncRequest.getProjectId());
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.error(e);
|
||||||
|
// 同步缺陷异常, 当前同步错误信息 -> Redis(check接口获取)
|
||||||
|
setSyncErrorMsg(syncRequest.getProjectId(), e.getMessage());
|
||||||
|
} finally {
|
||||||
|
// 异常或正常结束都得删除当前项目执行同步的Key
|
||||||
|
deleteSyncKey(syncRequest.getProjectId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1977,7 +1945,6 @@ public class IssuesService {
|
||||||
Platform platform = platformPluginService.getPlatform(project.getPlatform(), project.getWorkspaceId());
|
Platform platform = platformPluginService.getPlatform(project.getPlatform(), project.getWorkspaceId());
|
||||||
SyncAllIssuesRequest syncAllIssuesRequest = new SyncAllIssuesRequest();
|
SyncAllIssuesRequest syncAllIssuesRequest = new SyncAllIssuesRequest();
|
||||||
BeanUtils.copyBean(syncAllIssuesRequest, issueSyncRequest);
|
BeanUtils.copyBean(syncAllIssuesRequest, issueSyncRequest);
|
||||||
syncAllIssuesRequest.setDefaultCustomFields(getDefaultCustomField(project));
|
|
||||||
syncAllIssuesRequest.setProjectConfig(PlatformPluginService.getCompatibleProjectConfig(project));
|
syncAllIssuesRequest.setProjectConfig(PlatformPluginService.getCompatibleProjectConfig(project));
|
||||||
syncAllIssuesRequest.setHandleSyncFunc(issueSyncRequest.getHandleSyncFunc());
|
syncAllIssuesRequest.setHandleSyncFunc(issueSyncRequest.getHandleSyncFunc());
|
||||||
platform.syncAllIssues(syncAllIssuesRequest);
|
platform.syncAllIssues(syncAllIssuesRequest);
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
package io.metersphere.service;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.Project;
|
||||||
|
import io.metersphere.base.mapper.ext.ExtIssuesMapper;
|
||||||
|
import io.metersphere.commons.exception.MSException;
|
||||||
|
import io.metersphere.xpack.track.dto.IssueSyncRequest;
|
||||||
|
import io.metersphere.xpack.track.dto.IssuesDao;
|
||||||
|
import io.metersphere.xpack.track.dto.request.IssuesRequest;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author song-cc-rock
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public class IssuesSyncService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IssuesService issuesService;
|
||||||
|
@Resource
|
||||||
|
private BaseProjectService baseProjectService;
|
||||||
|
@Resource
|
||||||
|
private ExtIssuesMapper extIssuesMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xpack用户
|
||||||
|
* @param syncRequest 同步参数
|
||||||
|
*/
|
||||||
|
public void syncAllIssues(IssueSyncRequest syncRequest) {
|
||||||
|
try {
|
||||||
|
if (StringUtils.isNotBlank(syncRequest.getProjectId())) {
|
||||||
|
// 获取当前项目执行同步缺陷Key
|
||||||
|
String syncValue = issuesService.getSyncKey(syncRequest.getProjectId());
|
||||||
|
if (StringUtils.isEmpty(syncValue)) {
|
||||||
|
// 同步Key不存在, 设置保证唯一性, 并开始同步
|
||||||
|
issuesService.setSyncKey(syncRequest.getProjectId());
|
||||||
|
Project project = baseProjectService.getProjectById(syncRequest.getProjectId());
|
||||||
|
if (!issuesService.isThirdPartTemplate(project)) {
|
||||||
|
syncRequest.setDefaultCustomFields(issuesService.getDefaultCustomFields(syncRequest.getProjectId()));
|
||||||
|
}
|
||||||
|
issuesService.syncThirdPartyAllIssues(syncRequest, project);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
issuesService.deleteSyncKey(syncRequest.getProjectId());
|
||||||
|
MSException.throwException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 非xpack用户
|
||||||
|
* @param projectId 项目ID
|
||||||
|
*/
|
||||||
|
public void syncIssues(String projectId) {
|
||||||
|
try {
|
||||||
|
if (StringUtils.isNotBlank(projectId)) {
|
||||||
|
String syncValue = issuesService.getSyncKey(projectId);
|
||||||
|
if (StringUtils.isEmpty(syncValue)) {
|
||||||
|
issuesService.setSyncKey(projectId);
|
||||||
|
Project project = baseProjectService.getProjectById(projectId);
|
||||||
|
List<IssuesDao> issues = extIssuesMapper.getIssueForSync(projectId, project.getPlatform());
|
||||||
|
|
||||||
|
if (CollectionUtils.isEmpty(issues)) {
|
||||||
|
issuesService.deleteSyncKey(projectId);
|
||||||
|
} else {
|
||||||
|
IssuesRequest issuesRequest = new IssuesRequest();
|
||||||
|
issuesRequest.setProjectId(projectId);
|
||||||
|
issuesRequest.setWorkspaceId(project.getWorkspaceId());
|
||||||
|
issuesRequest.setDefaultCustomFields(issuesService.getDefaultCustomField(project));
|
||||||
|
issuesService.syncThirdPartyIssues(issues, issuesRequest, project);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
issuesService.deleteSyncKey(projectId);
|
||||||
|
MSException.throwException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -598,43 +598,38 @@ export default {
|
||||||
"createTime": data.createTime.getTime(),
|
"createTime": data.createTime.getTime(),
|
||||||
"pre": data.preValue
|
"pre": data.preValue
|
||||||
}
|
}
|
||||||
syncAllIssues(param)
|
syncIssues()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
checkSyncIssues(this.loading, false, (errorData) => {
|
this.repeatCheckSyncRes();
|
||||||
this.loading = false;
|
}).catch(() => {
|
||||||
this.syncDisable = false;
|
this.resetSyncParam();
|
||||||
if (errorData.syncResult && errorData.syncResult !== '') {
|
});
|
||||||
this.$error(errorData.syncResult, false);
|
|
||||||
} else {
|
|
||||||
this.$success(this.$t('test_track.issue.sync_complete'), false);
|
|
||||||
this.getIssues();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
this.loading = false;
|
|
||||||
this.syncDisable = false;
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
syncIssues() {
|
syncIssues() {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.syncDisable = false;
|
this.syncDisable = true;
|
||||||
syncIssues()
|
syncIssues()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
checkSyncIssues(this.loading, false, (errorData) => {
|
this.repeatCheckSyncRes();
|
||||||
this.loading = false;
|
|
||||||
this.syncDisable = false;
|
|
||||||
if (errorData.syncResult && errorData.syncResult !== '') {
|
|
||||||
this.$error(errorData.syncResult, false);
|
|
||||||
} else {
|
|
||||||
this.$success(this.$t('test_track.issue.sync_complete'), false);
|
|
||||||
this.getIssues();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
this.loading = false;
|
this.resetSyncParam();
|
||||||
this.syncDisable = false;
|
});
|
||||||
});
|
},
|
||||||
|
repeatCheckSyncRes() {
|
||||||
|
checkSyncIssues(this.loading, false, (errorData) => {
|
||||||
|
this.loading = false;
|
||||||
|
this.syncDisable = false;
|
||||||
|
if (errorData.syncResult && errorData.syncResult !== '') {
|
||||||
|
this.$error(errorData.syncResult, false);
|
||||||
|
} else {
|
||||||
|
this.$success(this.$t('test_track.issue.sync_complete'), false);
|
||||||
|
this.getIssues();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
resetSyncParam() {
|
||||||
|
this.loading = false;
|
||||||
|
this.syncDisable = false;
|
||||||
},
|
},
|
||||||
editParam() {
|
editParam() {
|
||||||
let id = this.$route.query.id;
|
let id = this.$route.query.id;
|
||||||
|
|
Loading…
Reference in New Issue