feat(项目设置): 增加需求同步测试

This commit is contained in:
guoyuqi 2024-09-02 18:25:05 +08:00 committed by Craftsman
parent 695c26d6d3
commit cb72ff6b96
6 changed files with 130 additions and 15 deletions

View File

@ -21,7 +21,7 @@
select functional_case_demand.id, functional_case_demand.demand_id, functional_case_demand.case_id
from functional_case_demand
left join functional_case on functional_case.id = functional_case_demand.case_id
where functional_case.project_id = #{caseId} and functional_case_demand.demand_platform=#{platform}
where functional_case.project_id = #{projectId} and functional_case_demand.demand_platform=#{platform}
</select>
</mapper>

View File

@ -4,18 +4,25 @@ import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.metersphere.functional.domain.FunctionalCaseDemand;
import io.metersphere.functional.mapper.ExtFunctionalCaseDemandMapper;
import io.metersphere.functional.mapper.FunctionalCaseDemandMapper;
import io.metersphere.plugin.platform.dto.request.DemandRelateQueryRequest;
import io.metersphere.plugin.platform.dto.response.PlatformDemandDTO;
import io.metersphere.plugin.platform.spi.Platform;
import io.metersphere.project.service.ProjectApplicationService;
import io.metersphere.sdk.util.LogUtils;
import io.metersphere.system.utils.PageUtils;
import io.metersphere.system.utils.Pager;
import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
/**
@ -28,6 +35,8 @@ public class DemandSyncService {
private ExtFunctionalCaseDemandMapper extFunctionalCaseDemandMapper;
@Resource
private ProjectApplicationService projectApplicationService;
@Resource
private SqlSessionFactory sqlSessionFactory;
public static int DEFAULT_BATCH_SIZE = 50;
@ -37,33 +46,89 @@ public class DemandSyncService {
* @param scheduleUser 任务触发用户
*/
public void syncPlatformDemandBySchedule(String projectId, String scheduleUser) {
String platformName = projectApplicationService.getPlatformName(projectId);
String platformId = projectApplicationService.getDemandPlatformId(projectId);
// 创建一个 List 来保存合并后的结果
Platform platform = projectApplicationService.getPlatform(projectId, false);
Map<String, List<FunctionalCaseDemand>> updateMap = new HashMap<>();
int pageNumber = 1;
boolean count = true;
Page<Object> page = PageHelper.startPage(pageNumber, DEFAULT_BATCH_SIZE, count);
Pager<List<FunctionalCaseDemand>> listPager = PageUtils.setPageInfo(page, extFunctionalCaseDemandMapper.selectDemandByProjectId(projectId,platformName));
Pager<List<FunctionalCaseDemand>> listPager = PageUtils.setPageInfo(page, extFunctionalCaseDemandMapper.selectDemandByProjectId(projectId, platformId));
long total = listPager.getTotal();
List<FunctionalCaseDemand> list = listPager.getList();
Map<String, List<FunctionalCaseDemand>> demandMap = list.stream().collect(Collectors.groupingBy(FunctionalCaseDemand::getDemandId));
Set<String> demandIds = demandMap.keySet();
//TODO: 调用三方接口获取最新需求, updateMap 缓存数据
buildUpdateMap(projectId, demandIds, platform, demandMap, platformId, updateMap);
count = false;
for (int i = 1; i < ((int)Math.ceil((double) total/DEFAULT_BATCH_SIZE)); i ++) {
Page<Object> pageCycle = PageHelper.startPage(i+1, DEFAULT_BATCH_SIZE, count);
Pager<List<FunctionalCaseDemand>> listPagerCycle = PageUtils.setPageInfo(pageCycle, extFunctionalCaseDemandMapper.selectDemandByProjectId(projectId,platformName));
Pager<List<FunctionalCaseDemand>> listPagerCycle = PageUtils.setPageInfo(pageCycle, extFunctionalCaseDemandMapper.selectDemandByProjectId(projectId,platformId));
List<FunctionalCaseDemand> pageResults = listPagerCycle.getList();
Map<String, List<FunctionalCaseDemand>> demandsMap = pageResults.stream().collect(Collectors.groupingBy(FunctionalCaseDemand::getDemandId));
Set<String> demandIdSet = demandsMap.keySet();
//TODO: 调用三方接口获取最新需求, updateMap 缓存数据
buildUpdateMap(projectId, demandIdSet, platform, demandsMap, platformId, updateMap);
}
//TODO: 循环updateMap更新需求
updateMap.forEach((k,v)->{
for (FunctionalCaseDemand functionalCaseDemand : v) {
try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
FunctionalCaseDemandMapper functionalCaseDemandMapper = sqlSession.getMapper(FunctionalCaseDemandMapper.class);
functionalCaseDemandMapper.updateByPrimaryKeySelective(functionalCaseDemand);
sqlSession.flushStatements();
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
}
}
});
LogUtils.info("End synchronizing demands");
}
private void buildUpdateMap(String projectId, Set<String> demandIds, Platform platform, Map<String, List<FunctionalCaseDemand>> demandMap, String platformId, Map<String, List<FunctionalCaseDemand>> updateMap) {
DemandRelateQueryRequest demandRelateQueryRequest = new DemandRelateQueryRequest();
demandRelateQueryRequest.setProjectConfig(projectApplicationService.getProjectDemandThirdPartConfig(projectId));
demandRelateQueryRequest.setRelateDemandIds(new ArrayList<>(demandIds));
PlatformDemandDTO demands = platform.getDemands(demandRelateQueryRequest);
List<PlatformDemandDTO.Demand> demandList = demands.getList();
for (PlatformDemandDTO.Demand demand : demandList) {
List<FunctionalCaseDemand> functionalCaseDemands = demandMap.get(demand.getDemandId());
List<FunctionalCaseDemand>updateList = new ArrayList<>();
if (CollectionUtils.isNotEmpty(functionalCaseDemands)) {
for (FunctionalCaseDemand functionalCaseDemand : functionalCaseDemands) {
FunctionalCaseDemand update = buildFunctionalCaseDemand(functionalCaseDemand.getId(), platformId, demand);
updateList.add(update);
}
}
updateMap.put(demand.getDemandId(), updateList);
}
}
private FunctionalCaseDemand buildFunctionalCaseDemand(String id, String demandPlatform, PlatformDemandDTO.Demand demand) {
FunctionalCaseDemand functionalCaseDemand = new FunctionalCaseDemand();
functionalCaseDemand.setId(id);
functionalCaseDemand.setDemandPlatform(demandPlatform);
functionalCaseDemand.setCreateTime(System.currentTimeMillis());
functionalCaseDemand.setUpdateTime(System.currentTimeMillis());
dealWithDemand(demand, functionalCaseDemand, demandPlatform);
return functionalCaseDemand;
}
private void dealWithDemand(PlatformDemandDTO.Demand demand, FunctionalCaseDemand functionalCaseDemand, String demandPlatform) {
if (StringUtils.isBlank(demand.getParent())) {
functionalCaseDemand.setParent("NONE");
} else {
functionalCaseDemand.setParent(demand.getParent());
}
if (StringUtils.isNotBlank(demand.getDemandName())) {
if (demand.getDemandName().length() > 255) {
demand.setDemandName(demand.getDemandName().substring(0, 255));
} else {
demand.setDemandName("ceshi"+demand.getDemandName());
}
}
functionalCaseDemand.setDemandName(demand.getDemandName());
functionalCaseDemand.setDemandUrl(demand.getDemandUrl());
}
}

View File

@ -6,9 +6,13 @@ import io.metersphere.functional.dto.DemandDTO;
import io.metersphere.functional.dto.FunctionalDemandDTO;
import io.metersphere.functional.mapper.FunctionalCaseDemandMapper;
import io.metersphere.functional.request.*;
import io.metersphere.functional.service.DemandSyncService;
import io.metersphere.functional.service.FunctionalCaseDemandService;
import io.metersphere.plugin.platform.dto.response.PlatformDemandDTO;
import io.metersphere.plugin.platform.utils.PluginPager;
import io.metersphere.project.domain.ProjectApplication;
import io.metersphere.project.mapper.ProjectApplicationMapper;
import io.metersphere.sdk.constants.ProjectApplicationType;
import io.metersphere.sdk.constants.SessionConstants;
import io.metersphere.sdk.domain.OperationLog;
import io.metersphere.sdk.domain.OperationLogExample;
@ -61,11 +65,15 @@ public class FunctionalCaseDemandControllerTests extends BaseTest {
@Resource
private BasePluginTestService basePluginTestService;
@Resource
private DemandSyncService demandSyncService;
@Resource
private MockServerClient mockServerClient;
@Value("${embedded.mockserver.host}")
private String mockServerHost;
@Value("${embedded.mockserver.port}")
private int mockServerHostPort;
@Resource
private ProjectApplicationMapper projectApplicationMapper;
private static final String URL_DEMAND_PAGE = "/functional/case/demand/page";
@ -93,7 +101,7 @@ public class FunctionalCaseDemandControllerTests extends BaseTest {
.withHeaders(
new Header("Content-Type", "application/json; charset=utf-8"),
new Header("Cache-Control", "public, max-age=86400"))
.withBody("{\"id\":\"123456\",\"name\":\"test\"}")
.withBody("{\"id\":\"123456\",\"name\":\"test\", \"issues\": [{\"key\": \"TES-1\",\"fields\": {\"summary\": \"Test\"}}], \"total\": 1}")
);
FunctionalDemandBatchRequest functionalDemandBatchRequest = new FunctionalDemandBatchRequest();
@ -662,4 +670,17 @@ public class FunctionalCaseDemandControllerTests extends BaseTest {
System.out.println(JSON.toJSONString(tableData));
}
@Test
@Order(16)
public void syncDemandSuccess() {
List<ProjectApplication> relatedConfigs = new ArrayList<>();
ProjectApplication projectApplication1 = new ProjectApplication("gyq_project-case-demand-test", ProjectApplicationType.CASE_RELATED_CONFIG.CASE_RELATED + "_cron_expression", "0 0 0 * * ?");
ProjectApplication projectApplication4 = new ProjectApplication("gyq_project-case-demand-test", ProjectApplicationType.CASE_RELATED_CONFIG.CASE_RELATED + "_sync_enable", "true");
relatedConfigs.add(projectApplication1);
relatedConfigs.add(projectApplication4);
projectApplicationMapper.batchInsert(relatedConfigs);
demandSyncService.syncPlatformDemandBySchedule("gyq_project-case-demand-test", "admin");
}
}

View File

@ -441,7 +441,7 @@ public class ProjectApplicationService {
* 用例关联需求配置
*
* @param projectId 项目ID
* @param configs 关联需求配置信息
* @param configs 关联需求配置信息
*/
public void updateRelated(String projectId, Map<String, String> configs, String currentUser) {
List<ProjectApplication> relatedConfigs = configs.entrySet().stream().map(config -> new ProjectApplication(projectId, ProjectApplicationType.CASE_RELATED_CONFIG.CASE_RELATED.name() + "_" + config.getKey().toUpperCase(), config.getValue())).collect(Collectors.toList());
@ -598,6 +598,34 @@ public class ProjectApplicationService {
return getPluginName(platformKeyConfig.getTypeValue());
}
/**
* 获取项目所属平台
*
* @param projectId 项目ID
* @return 项目所属平台
*/
public String getDemandPlatformId(String projectId) {
ProjectApplication platformEnableConfig = getByType(projectId, ProjectApplicationType.CASE_RELATED_CONFIG.CASE_RELATED.name() + "_" + ProjectApplicationType.CASE_RELATED_CONFIG.CASE_ENABLE.name());
ProjectApplication platformSyncConfig = getByType(projectId, ProjectApplicationType.CASE_RELATED_CONFIG.CASE_RELATED.name() + "_" + ProjectApplicationType.CASE_RELATED_CONFIG.SYNC_ENABLE.name());
ProjectApplication platformKeyConfig = getByType(projectId, ProjectApplicationType.CASE_RELATED_CONFIG.CASE_RELATED.name() + "_PLATFORM_KEY");
boolean isEnable = platformEnableConfig != null && Boolean.parseBoolean(platformEnableConfig.getTypeValue()) && platformSyncConfig != null && platformKeyConfig != null;
if (!isEnable) {
return "Metersphere";
} else {
ServiceIntegration serviceIntegration = getPlatformServiceIntegrationWithSyncOrDemand(projectId, false);
if (serviceIntegration == null) {
// 项目未配置第三方平台
return "Metersphere";
}
}
PluginWrapper pluginWrapper = pluginLoadService.getPluginWrapper(platformKeyConfig.getTypeValue());
if (pluginWrapper == null) {
// 插件未找到
return "Metersphere";
}
return pluginWrapper.getPluginId();
}
/**
* 获取项目同步机制
*

View File

@ -360,7 +360,7 @@ public class PluginControllerTests extends BaseTest {
@Order(5)
public void getPluginImg() throws Exception {
// @@请求成功
mockMvc.perform(getRequestBuilder(PLUGIN_IMAGE, anotherAddPlugin.getId(), "static/jira.jpg"))
mockMvc.perform(getRequestBuilder(PLUGIN_IMAGE, anotherAddPlugin.getId(), "static/jira.png"))
.andExpect(status().isOk());
assertErrorCode(this.requestGet(PLUGIN_IMAGE, anotherAddPlugin.getId(), "static/jira.doc"), FILE_NAME_ILLEGAL);
@ -428,7 +428,8 @@ public class PluginControllerTests extends BaseTest {
.withHeaders(
new Header("Content-Type", "application/json; charset=utf-8"),
new Header("Cache-Control", "public, max-age=86400"))
.withBody("{\"id\":\"123456\",\"name\":\"test\"}")
.withBody("{\"id\":\"123456\",\"name\":\"test\", \"issues\": [{\"key\": \"TES-1\",\"fields\": {\"summary\": \"Test\"}}], \"total\": 1}")
);
this.requestPostTest(PLUGIN_OPTIONS_URL, optionsRequest);
// 获取返回值