refactor(项目设置): 优化缺陷同步定时任务配置逻辑

This commit is contained in:
song-cc-rock 2024-01-29 16:11:56 +08:00 committed by 刘瑞斌
parent e15e0611f7
commit 97ece4ad80
19 changed files with 200 additions and 224 deletions

View File

@ -94,4 +94,10 @@ public class MsSyncBugDTO {
* 缺陷描述
*/
private String description;
/**
* 缺陷位置
*/
private Long pos;
}

View File

@ -10,7 +10,7 @@ public class SyncAllBugRequest extends SyncBugRequest {
/**
* 创建时间前后
*/
private boolean pre;
private Boolean pre;
/**
* 条件: 缺陷创建时间

View File

@ -12,7 +12,7 @@ public class BugSyncRequest implements Serializable {
private String projectId;
@Schema(description = "创建时间前或后", requiredMode = Schema.RequiredMode.REQUIRED)
private boolean pre;
private Boolean pre;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private Long createTime;

View File

@ -2,13 +2,18 @@ package io.metersphere.bug.job;
import io.metersphere.bug.service.BugSyncService;
import io.metersphere.bug.service.XpackBugService;
import io.metersphere.project.service.ProjectApplicationService;
import io.metersphere.sdk.util.CommonBeanFactory;
import io.metersphere.sdk.util.LogUtils;
import io.metersphere.system.domain.ServiceIntegration;
import io.metersphere.system.dto.sdk.LicenseDTO;
import io.metersphere.system.schedule.BaseScheduleJob;
import io.metersphere.system.service.LicenseService;
import org.apache.commons.lang3.StringUtils;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobKey;
import org.quartz.TriggerKey;
/**
* 缺陷同步定时任务
@ -18,30 +23,55 @@ public class BugSyncJob extends BaseScheduleJob {
private final LicenseService licenseService;
private final BugSyncService bugSyncService;
private final XpackBugService xpackBugService;
private final ProjectApplicationService projectApplicationService;
public BugSyncJob() {
licenseService = CommonBeanFactory.getBean(LicenseService.class);
xpackBugService = CommonBeanFactory.getBean(XpackBugService.class);
bugSyncService = CommonBeanFactory.getBean(BugSyncService.class);
projectApplicationService = CommonBeanFactory.getBean(ProjectApplicationService.class);
}
public static JobKey getJobKey(String resourceId) {
return new JobKey(resourceId, BugSyncJob.class.getName());
}
public static TriggerKey getTriggerKey(String resourceId) {
return new TriggerKey(resourceId, BugSyncJob.class.getName());
}
@Override
protected void businessExecute(JobExecutionContext context) {
JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
String resourceId = jobDataMap.getString("resourceId");
String userId = jobDataMap.getString("userId");
if (!checkBeforeSync(resourceId)) {
return;
}
LogUtils.info("bug sync job start......");
if (licenseService == null) {
LogUtils.info("license is null, sync remain bug");
bugSyncService.syncPlatformBugBySchedule();
bugSyncService.syncPlatformBugBySchedule(resourceId, userId);
} else {
LicenseDTO licenseDTO = licenseService.validate();
if (licenseDTO != null && licenseDTO.getLicense() != null
&& StringUtils.equals(licenseDTO.getStatus(), "valid")) {
LogUtils.info("license is valid, sync all bug");
xpackBugService.syncPlatformBugsBySchedule();
xpackBugService.syncPlatformBugsBySchedule(resourceId, userId);
} else {
LogUtils.info("license is invalid, sync remain bug");
bugSyncService.syncPlatformBugBySchedule();
bugSyncService.syncPlatformBugBySchedule(resourceId, userId);
}
}
LogUtils.info("bug sync job end......");
}
/**
* 同步前检验, 同步配置的平台是否开启插件集成
* @return 是否放行
*/
private boolean checkBeforeSync(String projectId) {
ServiceIntegration serviceIntegration = projectApplicationService.getPlatformServiceIntegrationWithSyncOrDemand(projectId, true);
return serviceIntegration != null && serviceIntegration.getEnable();
}
}

View File

@ -0,0 +1,67 @@
package io.metersphere.bug.service;
import io.metersphere.bug.job.BugSyncJob;
import io.metersphere.project.domain.ProjectApplication;
import io.metersphere.sdk.constants.ProjectApplicationType;
import io.metersphere.sdk.constants.ScheduleResourceType;
import io.metersphere.sdk.constants.ScheduleType;
import io.metersphere.system.domain.Schedule;
import io.metersphere.system.schedule.ScheduleService;
import io.metersphere.system.service.BaseBugScheduleService;
import io.metersphere.system.uid.IDGenerator;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
@Service
@Transactional(rollbackFor = Exception.class)
public class BugScheduleServiceImpl implements BaseBugScheduleService {
@Resource
private ScheduleService scheduleService;
@Override
public void updateBugSyncScheduleConfig(List<ProjectApplication> bugSyncConfigs, String projectId, String currentUser) {
List<ProjectApplication> syncCron = bugSyncConfigs.stream().filter(config -> config.getType().equals(ProjectApplicationType.BUG.BUG_SYNC.name() + "_" + ProjectApplicationType.BUG_SYNC_CONFIG.CRON_EXPRESSION.name())).toList();
List<ProjectApplication> syncEnable = bugSyncConfigs.stream().filter(config -> config.getType().equals(ProjectApplicationType.BUG.BUG_SYNC.name() + "_" + ProjectApplicationType.BUG_SYNC_CONFIG.SYNC_ENABLE.name())).toList();
if (CollectionUtils.isNotEmpty(syncCron)) {
Boolean enable = Boolean.valueOf(syncEnable.get(0).getTypeValue());
String typeValue = syncCron.get(0).getTypeValue();
Schedule schedule = scheduleService.getScheduleByResource(projectId, BugSyncJob.class.getName());
Optional<Schedule> optional = Optional.ofNullable(schedule);
optional.ifPresentOrElse(s -> {
s.setEnable(enable);
s.setValue(typeValue);
scheduleService.editSchedule(s);
scheduleService.addOrUpdateCronJob(s, BugSyncJob.getJobKey(projectId), BugSyncJob.getTriggerKey(projectId), BugSyncJob.class);
}, () -> {
Schedule request = new Schedule();
request.setName("Bug Sync Job");
request.setResourceId(projectId);
request.setKey(IDGenerator.nextStr());
request.setProjectId(projectId);
request.setEnable(enable);
request.setCreateUser(currentUser);
request.setType(ScheduleType.CRON.name());
request.setValue(typeValue);
request.setJob(BugSyncJob.class.getName());
request.setResourceType(ScheduleResourceType.BUG_SYNC.name());
scheduleService.addSchedule(request);
scheduleService.addOrUpdateCronJob(request, BugSyncJob.getJobKey(projectId), BugSyncJob.getTriggerKey(projectId), BugSyncJob.class);
});
}
}
@Override
public void enableOrNotBugSyncSchedule(String projectId, String currentUser, Boolean enable) {
Schedule schedule = scheduleService.getScheduleByResource(projectId, BugSyncJob.class.getName());
if (schedule != null) {
schedule.setEnable(enable);
scheduleService.editSchedule(schedule);
}
}
}

View File

@ -7,13 +7,11 @@ import io.metersphere.bug.dto.request.BugSyncRequest;
import io.metersphere.bug.enums.BugPlatform;
import io.metersphere.bug.mapper.BugMapper;
import io.metersphere.project.domain.Project;
import io.metersphere.project.domain.ProjectExample;
import io.metersphere.project.mapper.ProjectMapper;
import io.metersphere.project.service.ProjectApplicationService;
import io.metersphere.project.service.ProjectTemplateService;
import io.metersphere.sdk.constants.TemplateScene;
import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.util.LogUtils;
import io.metersphere.system.domain.Template;
import io.metersphere.system.domain.TemplateExample;
import io.metersphere.system.mapper.TemplateMapper;
@ -134,18 +132,8 @@ public class BugSyncService {
/**
* 定时任务同步缺陷(存量)
*/
public void syncPlatformBugBySchedule() {
ProjectExample example = new ProjectExample();
List<Project> projects = projectMapper.selectByExample(example);
List<String> allProjectIds = projects.stream().map(Project::getId).collect(Collectors.toList());
List<String> syncProjectIds = projectApplicationService.filterNeedSyncProject(allProjectIds);
syncProjectIds.forEach(id -> {
try {
syncBugs(id, "admin");
} catch (Exception e) {
LogUtils.error(e.getMessage(), e);
}
});
public void syncPlatformBugBySchedule(String projectId, String scheduleUser) {
syncBugs(projectId, scheduleUser);
}
/**

View File

@ -14,8 +14,10 @@ public interface XpackBugService {
/**
* 同步系统下所有第三方平台项目缺陷(定时任务)
* @param projectId 项目ID
* @param scheduleUser 定时任务执行用户
*/
void syncPlatformBugsBySchedule();
void syncPlatformBugsBySchedule(String projectId, String scheduleUser);
/**
* 同步当前项目第三方平台缺陷(前台调用, 全量同步)

View File

@ -554,8 +554,7 @@ public class BugControllerTests extends BaseTest {
this.requestGetWithOk(BUG_HEADER_STATUS_OPTION + "/default-project-for-bug");
this.requestGetWithOk(BUG_HEADER_HANDLER_OPTION + "/default-project-for-bug");
// 同步删除缺陷(default-bug-id-jira-sync)
// 一条模板不存在的缺陷(手动删除default-bug-id-jira-sync-1, 影响后续测试)
// 同步并删除的两条缺陷
this.requestGetWithOk(BUG_SYNC + "/default-project-for-bug");
bugMapper.deleteByPrimaryKey("default-bug-id-jira-sync-1");
@ -618,6 +617,12 @@ public class BugControllerTests extends BaseTest {
deleteLocalFile(updateRequest2.getId()); // 手动删除关联的文件, 重新同步时会下载平台附件
bugService.syncPlatformBugs(remainBugs, defaultProject, "admin");
// 全选删除所有Jira缺陷
BugBatchRequest request = new BugBatchRequest();
request.setProjectId("default-project-for-bug");
request.setSelectAll(true);
this.requestPost(BUG_BATCH_DELETE, request);
// 集成配置为空
addRequest.setProjectId("default-project-for-not-integration");
MultiValueMap<String, Object> notIntegrationParam = getDefaultMultiPartParam(addRequest, file);
@ -638,7 +643,7 @@ public class BugControllerTests extends BaseTest {
@Order(97)
void coverSyncScheduleTests() {
// 定时同步存量缺陷
bugSyncService.syncPlatformBugBySchedule();
bugSyncService.syncPlatformBugBySchedule("default-project-for-bug", "admin");
// 异常信息
bugSyncExtraService.setSyncErrorMsg("default-project-for-bug", "sync error!");
String syncErrorMsg = bugSyncExtraService.getSyncErrorMsg("default-project-for-bug");
@ -823,7 +828,7 @@ public class BugControllerTests extends BaseTest {
summaryField.setId("summary");
summaryField.setName("摘要");
summaryField.setType("input");
summaryField.setValue("这是一段summary内容!!!!");
summaryField.setValue("这是一段summary内容1!!!!");
BugCustomFieldDTO descriptionField = new BugCustomFieldDTO();
descriptionField.setId("description");
descriptionField.setName("描述");

View File

@ -1,50 +0,0 @@
package io.metersphere.bug.job;
import io.metersphere.system.dto.sdk.LicenseDTO;
import io.metersphere.system.dto.sdk.LicenseInfoDTO;
import io.metersphere.system.service.LicenseService;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.mockito.Mockito;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.util.ReflectionTestUtils;
@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class BugSyncJobTests {
@Resource
private LicenseService licenseService;
@Test
void test() {
// set licenseService field to null by reflection
BugSyncJob noLicenseMockObj = new BugSyncJob();
ReflectionTestUtils.setField(noLicenseMockObj, "licenseService", null);
noLicenseMockObj.businessExecute(null);
// set mocLicenseService field
BugSyncJob syncJob = new BugSyncJob();
// mock license validate return null
Mockito.when(licenseService.validate()).thenReturn(null);
syncJob.businessExecute(null);
// mock license validate return empty info
Mockito.when(licenseService.validate()).thenReturn(new LicenseDTO());
syncJob.businessExecute(null);
// mock license validate return invalid && license info
LicenseDTO invalid = new LicenseDTO();
invalid.setStatus("invalid");
invalid.setLicense(new LicenseInfoDTO());
Mockito.when(licenseService.validate()).thenReturn(invalid);
syncJob.businessExecute(null);
// mock license validate return valid && license info
LicenseDTO valid = new LicenseDTO();
valid.setStatus("valid");
valid.setLicense(new LicenseInfoDTO());
Mockito.when(licenseService.validate()).thenReturn(valid);
syncJob.businessExecute(null);
}
}

View File

@ -13,7 +13,7 @@ import java.util.List;
public class XpackBugMockServiceImpl implements XpackBugService {
@Override
public void syncPlatformBugsBySchedule() {
public void syncPlatformBugsBySchedule(String projectId, String scheduleUser) {
}

View File

@ -286,7 +286,7 @@ public class ProjectApplicationController {
@Operation(summary = "缺陷管理-同步缺陷配置")
@RequiresPermissions(PermissionConstants.PROJECT_APPLICATION_BUG_UPDATE)
@Log(type = OperationLogType.UPDATE, expression = "#msClass.updateBugSyncLog(#projectId, #configs)", msClass = ProjectApplicationService.class)
public void syncBugConfig(@PathVariable("projectId") String projectId, @RequestBody Map<String, String> configs) {
public void syncBugConfig(@PathVariable("projectId") String projectId, @RequestBody Map<String, Object> configs) {
projectApplicationService.syncBugConfig(projectId, configs, SessionUtils.getUserId());
}

View File

@ -19,4 +19,7 @@ public class ProjectTemplateDTO extends Template implements Serializable {
@Schema(description = "是否是默认模板")
private Boolean enableDefault = false;
@Schema(description = "是否是平台自动获取模板")
private Boolean enablePlatformDefault = false;
}

View File

@ -1,21 +0,0 @@
package io.metersphere.project.job;
import io.metersphere.system.schedule.BaseScheduleJob;
import org.quartz.JobExecutionContext;
import org.quartz.JobKey;
import org.quartz.TriggerKey;
public class BugSyncJob extends BaseScheduleJob {
@Override
protected void businessExecute(JobExecutionContext context) {
//TODO 定时任务执行 同步issue
}
public static JobKey getJobKey(String projectId) {
return new JobKey(projectId, BugSyncJob.class.getName());
}
public static TriggerKey getTriggerKey(String projectId) {
return new TriggerKey(projectId, BugSyncJob.class.getName());
}
}

View File

@ -8,25 +8,26 @@ import io.metersphere.project.domain.Project;
import io.metersphere.project.domain.ProjectApplication;
import io.metersphere.project.domain.ProjectApplicationExample;
import io.metersphere.project.dto.ModuleDTO;
import io.metersphere.project.job.BugSyncJob;
import io.metersphere.project.mapper.*;
import io.metersphere.project.request.ProjectApplicationRequest;
import io.metersphere.project.utils.ModuleSortUtils;
import io.metersphere.sdk.constants.OperationLogConstants;
import io.metersphere.sdk.constants.ProjectApplicationType;
import io.metersphere.sdk.constants.ScheduleResourceType;
import io.metersphere.sdk.constants.ScheduleType;
import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.util.CommonBeanFactory;
import io.metersphere.sdk.util.JSON;
import io.metersphere.sdk.util.Translator;
import io.metersphere.system.domain.*;
import io.metersphere.system.domain.Plugin;
import io.metersphere.system.domain.ServiceIntegration;
import io.metersphere.system.domain.ServiceIntegrationExample;
import io.metersphere.system.domain.User;
import io.metersphere.system.dto.sdk.OptionDTO;
import io.metersphere.system.log.constants.OperationLogModule;
import io.metersphere.system.log.constants.OperationLogType;
import io.metersphere.system.log.dto.LogDTO;
import io.metersphere.system.mapper.PluginMapper;
import io.metersphere.system.mapper.ServiceIntegrationMapper;
import io.metersphere.system.schedule.ScheduleService;
import io.metersphere.system.service.BaseBugScheduleService;
import io.metersphere.system.service.PlatformPluginService;
import io.metersphere.system.service.PluginLoadService;
import io.metersphere.system.service.ServiceIntegrationService;
@ -49,9 +50,6 @@ public class ProjectApplicationService {
@Resource
private ProjectApplicationMapper projectApplicationMapper;
@Resource
private ScheduleService scheduleService;
@Resource
private ExtProjectUserRoleMapper extProjectUserRoleMapper;
@ -105,54 +103,14 @@ public class ProjectApplicationService {
}
private void doBeforeUpdate(ProjectApplication application, String currentUser) {
//TODO 后续清理合并完没问题再清理===== 清理报告只有一个定时任务项目配置时不需要在添加定时任务了
/*String type = application.getType();
if (StringUtils.equals(type, ProjectApplicationType.TEST_PLAN.TEST_PLAN_CLEAN_REPORT.name())
|| StringUtils.equals(type, ProjectApplicationType.UI.UI_CLEAN_REPORT.name())
|| StringUtils.equals(type, ProjectApplicationType.LOAD_TEST.LOAD_TEST_CLEAN_REPORT.name())
|| StringUtils.equals(type, ProjectApplicationType.API.API_CLEAN_REPORT.name())) {
//清除 测试计划/UI测试/性能测试/接口测试 报告 定时任务
this.doHandleSchedule(application, currentUser);
}*/
BaseBugScheduleService baseBugScheduleService = CommonBeanFactory.getBean(BaseBugScheduleService.class);
if (StringUtils.equals(ProjectApplicationType.BUG.BUG_SYNC.name() + "_" + ProjectApplicationType.BUG_SYNC_CONFIG.SYNC_ENABLE.name(),
application.getType()) && baseBugScheduleService != null) {
// 缺陷同步配置开启或关闭
baseBugScheduleService.enableOrNotBugSyncSchedule(application.getProjectId(), currentUser, Boolean.valueOf(application.getTypeValue()));
}
}
/*private void doHandleSchedule(ProjectApplication application, String currentUser) {
String typeValue = application.getTypeValue();
String projectId = application.getProjectId();
Boolean enable = BooleanUtils.isTrue(Boolean.valueOf(typeValue));
Schedule schedule = scheduleService.getScheduleByResource(application.getProjectId(), CleanUpReportJob.class.getName());
Optional<Schedule> optional = Optional.ofNullable(schedule);
optional.ifPresentOrElse(s -> {
s.setEnable(enable);
s.setCreateUser(currentUser);
scheduleService.editSchedule(s);
scheduleService.addOrUpdateCronJob(s,
CleanUpReportJob.getJobKey(projectId),
CleanUpReportJob.getTriggerKey(projectId),
CleanUpReportJob.class);
}, () -> {
Schedule request = new Schedule();
request.setName("Clean Report Job");
request.setResourceId(projectId);
request.setKey(projectId);
request.setProjectId(projectId);
request.setEnable(enable);
request.setCreateUser(currentUser);
request.setType(ScheduleType.CRON.name());
// 每天凌晨2点执行清理任务
request.setValue("0 0 2 * * ?");
request.setJob(CleanUpReportJob.class.getName());
request.setResourceType(ScheduleResourceType.CLEAN_REPORT.name());
scheduleService.addSchedule(request);
scheduleService.addOrUpdateCronJob(request,
CleanUpReportJob.getJobKey(projectId),
CleanUpReportJob.getTriggerKey(projectId),
CleanUpReportJob.class);
});
}*/
/**
* 获取配置信息
*
@ -237,10 +195,9 @@ public class ProjectApplicationService {
* @param projectId
* @param configs
*/
public void syncBugConfig(String projectId, Map<String, String> configs, String currentUser) {
List<ProjectApplication> bugSyncConfigs = configs.entrySet().stream().map(config -> new ProjectApplication(projectId, ProjectApplicationType.BUG.BUG_SYNC.name() + "_" + config.getKey().toUpperCase(), config.getValue())).collect(Collectors.toList());
//处理同步缺陷定时任务配置
doSaveOrUpdateSchedule(bugSyncConfigs, projectId, currentUser);
public void syncBugConfig(String projectId, Map<String, Object> configs, String currentUser) {
List<ProjectApplication> bugSyncConfigs = configs.entrySet().stream().map(config -> new ProjectApplication(projectId, ProjectApplicationType.BUG.BUG_SYNC.name() + "_" + config.getKey().toUpperCase(),
(config.getValue() instanceof String) ? config.getValue().toString() : JSON.toJSONString(config.getValue()))).toList();
ProjectApplicationExample example = new ProjectApplicationExample();
example.createCriteria().andProjectIdEqualTo(projectId).andTypeLike(ProjectApplicationType.BUG.BUG_SYNC.name() + "%");
if (projectApplicationMapper.countByExample(example) > 0) {
@ -251,47 +208,13 @@ public class ProjectApplicationService {
} else {
projectApplicationMapper.batchInsert(bugSyncConfigs);
}
}
private void doSaveOrUpdateSchedule(List<ProjectApplication> bugSyncConfigs, String projectId, String currentUser) {
List<ProjectApplication> syncCron = bugSyncConfigs.stream().filter(config -> config.getType().equals(ProjectApplicationType.BUG.BUG_SYNC.name() + "_" + ProjectApplicationType.BUG_SYNC_CONFIG.CRON_EXPRESSION.name())).collect(Collectors.toList());
List<ProjectApplication> syncEnable = bugSyncConfigs.stream().filter(config -> config.getType().equals(ProjectApplicationType.BUG.BUG_SYNC.name() + "_" + ProjectApplicationType.BUG_SYNC_CONFIG.SYNC_ENABLE.name())).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(syncCron)) {
Boolean enable = Boolean.valueOf(syncEnable.get(0).getTypeValue());
String typeValue = syncCron.get(0).getTypeValue();
Schedule schedule = scheduleService.getScheduleByResource(projectId, BugSyncJob.class.getName());
Optional<Schedule> optional = Optional.ofNullable(schedule);
optional.ifPresentOrElse(s -> {
s.setEnable(enable);
s.setValue(typeValue);
scheduleService.editSchedule(s);
scheduleService.addOrUpdateCronJob(s,
BugSyncJob.getJobKey(projectId),
BugSyncJob.getTriggerKey(projectId),
BugSyncJob.class);
}, () -> {
Schedule request = new Schedule();
request.setName("Bug Sync Job");
request.setResourceId(projectId);
request.setKey(projectId);
request.setProjectId(projectId);
request.setEnable(enable);
request.setCreateUser(currentUser);
request.setType(ScheduleType.CRON.name());
// 每天凌晨2点执行清理任务
request.setValue(typeValue);
request.setJob(BugSyncJob.class.getName());
request.setResourceType(ScheduleResourceType.BUG_SYNC.name());
scheduleService.addSchedule(request);
scheduleService.addOrUpdateCronJob(request,
BugSyncJob.getJobKey(projectId),
BugSyncJob.getTriggerKey(projectId),
BugSyncJob.class);
});
// 更新缺陷定时任务配置
BaseBugScheduleService baseBugScheduleService = CommonBeanFactory.getBean(BaseBugScheduleService.class);
if (baseBugScheduleService != null) {
baseBugScheduleService.updateBugSyncScheduleConfig(bugSyncConfigs, projectId, currentUser);
}
}
/**
* 获取同步缺陷配置
*
@ -604,26 +527,6 @@ public class ProjectApplicationService {
return getPluginName(platformKeyConfig.getTypeValue());
}
/**
* 过滤出能够同步的项目
*
* @param projectIds 项目ID集合
* @return 同步的项目ID集合
*/
public List<String> filterNeedSyncProject(List<String> projectIds) {
Iterator<String> iterator = projectIds.iterator();
while (iterator.hasNext()) {
String projectId = iterator.next();
ServiceIntegration serviceIntegration = getPlatformServiceIntegrationWithSyncOrDemand(projectId, true);
String platformName = getPlatformName(projectId);
if (serviceIntegration == null || StringUtils.equals("Local", platformName)) {
// 项目未配置第三方平台 或者 项目同步配置为Local
iterator.remove();
}
}
return projectIds;
}
/**
* 获取项目同步机制
*

View File

@ -62,10 +62,37 @@ public class ProjectTemplateService extends BaseTemplateService {
public List list(String projectId, String scene) {
projectService.checkResourceExist(projectId);
List<Template> templates = super.list(projectId, scene);
List<ProjectTemplateDTO> templateDTOS = templates.stream().map(item -> BeanUtils.copyBean(new ProjectTemplateDTO(), item)).collect(Collectors.toList());
// 缺陷模板需要获取第三方平台模板
templates = addPluginBugTemplate(projectId, scene, templates);
if (StringUtils.equals(scene, TemplateScene.BUG.name())) {
Template pluginBugTemplate = getPluginBugTemplate(projectId);
if (pluginBugTemplate != null) {
ProjectTemplateDTO pluginTemplate = BeanUtils.copyBean(new ProjectTemplateDTO(), pluginBugTemplate);
pluginTemplate.setEnablePlatformDefault(true);
templateDTOS.add(pluginTemplate);
}
}
// 标记默认模板
return tagDefaultTemplate(projectId, scene, templates);
// 查询项目下设置中配置的默认模板
String defaultProjectId = getDefaultTemplateId(projectId, scene);
ProjectTemplateDTO defaultTemplate = templateDTOS.stream()
.filter(t -> StringUtils.equals(defaultProjectId, t.getId()))
.findFirst()
.orElse(null);
// 如果查询不到默认模板设置内置模板为默认模板
if (defaultTemplate == null) {
Optional<ProjectTemplateDTO> internalTemplate = templateDTOS.stream()
.filter(ProjectTemplateDTO::getInternal).findFirst();
if (internalTemplate.isPresent()) {
defaultTemplate = internalTemplate.get();
}
}
if (defaultTemplate != null) {
defaultTemplate.setEnableDefault(true);
}
return templateDTOS;
}
/**

View File

@ -31,9 +31,7 @@ import org.springframework.test.context.jdbc.SqlConfig;
import org.springframework.test.web.servlet.MvcResult;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static io.metersphere.system.controller.handler.result.MsHttpResultCode.NOT_FOUND;
@ -768,12 +766,5 @@ public class ProjectApplicationControllerTests extends BaseTest {
// 获取同步机制
Assertions.assertTrue(projectApplicationService.isPlatformSyncMethodByIncrement("default-project-for-application"));
Assertions.assertFalse(projectApplicationService.isPlatformSyncMethodByIncrement("default-project-for-application-not-exist"));
// 过滤Local平台项目
projectApplicationService.filterNeedSyncProject(new ArrayList<>(new ArrayList<>(List.of("default-project-for-application"))));
projectApplicationService.filterNeedSyncProject(new ArrayList<>(new ArrayList<>(List.of("default-project-for-application-not-exist"))));
// 移除插件测试
basePluginTestService.deleteJiraPlugin();
projectApplicationService.filterNeedSyncProject(new ArrayList<>(new ArrayList<>(List.of("default-project-for-application"))));
}
}

View File

@ -0,0 +1,24 @@
package io.metersphere.system.service;
import io.metersphere.project.domain.ProjectApplication;
import java.util.List;
public interface BaseBugScheduleService {
/**
* 更新项目的缺陷同步定时任务
* @param bugSyncConfigs 配置
* @param projectId 项目ID
* @param currentUser 当前用户
*/
void updateBugSyncScheduleConfig(List<ProjectApplication> bugSyncConfigs, String projectId, String currentUser);
/**
* 启用或禁用缺陷同步定时任务
* @param projectId 项目ID
* @param currentUser 当前用户
* @param enable 开启或禁用
*/
void enableOrNotBugSyncSchedule(String projectId, String currentUser, Boolean enable);
}

View File

@ -162,6 +162,7 @@
<exclude>io/metersphere/sdk/**</exclude>
<exclude>io/metersphere/provider/**</exclude>
<exclude>io/metersphere/plugin/**</exclude>
<exclude>io/metersphere/*/job/**</exclude>
</excludes>
</configuration>
<executions>