parent
9ca3c0ba75
commit
f21a4a5c5d
|
@ -11,5 +11,6 @@ import java.util.List;
|
|||
@Setter
|
||||
public class UpdateScenarioModuleDTO {
|
||||
private List<ApiScenarioModule> moduleList;
|
||||
private List<ApiScenarioWithBLOBs> needUpdateList;
|
||||
private List<ApiScenarioWithBLOBs> apiScenarioWithBLOBsList;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import java.util.List;
|
|||
@Setter
|
||||
public class UpdateApiModuleDTO {
|
||||
private List<ApiModule> moduleList;
|
||||
private List<ApiDefinitionWithBLOBs> apiDefinitionWithBLOBsList;
|
||||
private List<ApiDefinitionWithBLOBs> needUpdateList;
|
||||
private List<ApiDefinitionWithBLOBs> definitionWithBLOBs;
|
||||
|
||||
}
|
||||
|
|
|
@ -76,6 +76,8 @@ import java.nio.charset.StandardCharsets;
|
|||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class ApiAutomationService {
|
||||
|
@ -1336,17 +1338,21 @@ public class ApiAutomationService {
|
|||
ApiDefinitionMapper apiDefinitionMapper = sqlSession.getMapper(ApiDefinitionMapper.class);
|
||||
ApiScenarioModuleMapper apiScenarioModuleMapper = sqlSession.getMapper(ApiScenarioModuleMapper.class);
|
||||
|
||||
List<ApiScenarioWithBLOBs> data = apiImport.getData();
|
||||
List<ApiScenarioWithBLOBs> initData = apiImport.getData();
|
||||
currentScenarioOrder.remove();
|
||||
|
||||
UpdateScenarioModuleDTO updateScenarioModuleDTO = apiScenarioModuleService.checkScenarioModule(request.getModuleId(), request.getProjectId(), data, StringUtils.equals("fullCoverage", request.getModeId()), request.getCoverModule());
|
||||
UpdateScenarioModuleDTO updateScenarioModuleDTO = apiScenarioModuleService.checkScenarioModule(request, initData, StringUtils.equals("fullCoverage", request.getModeId()), request.getCoverModule());
|
||||
List<ApiScenarioModule> moduleList = updateScenarioModuleDTO.getModuleList();
|
||||
List<ApiScenarioWithBLOBs> apiScenarioWithBLOBsList = updateScenarioModuleDTO.getApiScenarioWithBLOBsList();
|
||||
List<ApiScenarioWithBLOBs> data = updateScenarioModuleDTO.getApiScenarioWithBLOBsList();
|
||||
List<ApiScenarioWithBLOBs> needUpdateList = updateScenarioModuleDTO.getNeedUpdateList();
|
||||
|
||||
if (moduleList != null) {
|
||||
for (ApiScenarioModule apiScenarioModule : moduleList) {
|
||||
apiScenarioModuleMapper.insert(apiScenarioModule);
|
||||
}
|
||||
}
|
||||
int num = 0;
|
||||
Project project = new Project();
|
||||
Project project;
|
||||
if (!CollectionUtils.isEmpty(data) && data.get(0) != null && data.get(0).getProjectId() != null) {
|
||||
project = projectMapper.selectByPrimaryKey(data.get(0).getProjectId());
|
||||
ProjectConfig config = projectApplicationService.getSpecificTypeValue(project.getId(), ProjectApplicationType.SCENARIO_CUSTOM_NUM.name());
|
||||
|
@ -1358,7 +1364,7 @@ public class ApiAutomationService {
|
|||
for (int i = 0; i < data.size(); i++) {
|
||||
|
||||
ApiScenarioWithBLOBs item = data.get(i);
|
||||
List<ApiScenarioWithBLOBs> sameList = apiScenarioWithBLOBsList.stream().filter(t -> t.getName().equals(item.getName())).collect(Collectors.toList());
|
||||
List<ApiScenarioWithBLOBs> sameList = needUpdateList.stream().filter(t -> t.getId().equals(item.getId())).collect(toList());
|
||||
if (StringUtils.isBlank(item.getCreateUser())) {
|
||||
item.setCreateUser(SessionUtils.getUserId());
|
||||
}
|
||||
|
|
|
@ -1376,25 +1376,29 @@ public class ApiDefinitionService {
|
|||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
currentApiCaseOrder.remove();
|
||||
currentApiOrder.remove();
|
||||
List<ApiDefinitionWithBLOBs> data = apiImport.getData();
|
||||
String defaultVersion = extProjectVersionMapper.getDefaultVersion(request.getProjectId());
|
||||
request.setDefaultVersion(defaultVersion);
|
||||
List<ApiDefinitionWithBLOBs> initData = apiImport.getData();
|
||||
|
||||
Project project = projectMapper.selectByPrimaryKey(request.getProjectId());
|
||||
ProjectConfig config = projectApplicationService.getSpecificTypeValue(project.getId(), ProjectApplicationType.URL_REPEATABLE.name());
|
||||
boolean urlRepeat = config.getUrlRepeatable();
|
||||
|
||||
UpdateApiModuleDTO updateApiModuleDTO = apiModuleService.checkApiModule(request.getModuleId(), request.getProjectId(), apiImport.getProtocol(), data, StringUtils.equals("fullCoverage", request.getModeId()), request.getCoverModule(), urlRepeat);
|
||||
List<ApiDefinitionWithBLOBs> updateList = updateApiModuleDTO.getApiDefinitionWithBLOBsList();
|
||||
UpdateApiModuleDTO updateApiModuleDTO = apiModuleService.checkApiModule(request, apiImport, initData, StringUtils.equals("fullCoverage", request.getModeId()), urlRepeat);
|
||||
List<ApiDefinitionWithBLOBs> updateList = updateApiModuleDTO.getNeedUpdateList();
|
||||
List<ApiDefinitionWithBLOBs> data = updateApiModuleDTO.getDefinitionWithBLOBs();
|
||||
List<ApiModule> moduleList = updateApiModuleDTO.getModuleList();
|
||||
|
||||
ApiDefinitionMapper batchMapper = sqlSession.getMapper(ApiDefinitionMapper.class);
|
||||
ApiTestCaseMapper apiTestCaseMapper = sqlSession.getMapper(ApiTestCaseMapper.class);
|
||||
ExtApiDefinitionMapper extApiDefinitionMapper = sqlSession.getMapper(ExtApiDefinitionMapper.class);
|
||||
ApiModuleMapper apiModuleMapper = sqlSession.getMapper(ApiModuleMapper.class);
|
||||
|
||||
int num = 0;
|
||||
if (!CollectionUtils.isEmpty(data) && data.get(0) != null && data.get(0).getProjectId() != null) {
|
||||
num = getNextNum(data.get(0).getProjectId());
|
||||
}
|
||||
String defaultVersion = extProjectVersionMapper.getDefaultVersion(request.getProjectId());
|
||||
request.setDefaultVersion(defaultVersion);
|
||||
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
ApiDefinitionWithBLOBs item = data.get(i);
|
||||
this.setModule(item);
|
||||
|
@ -1416,9 +1420,11 @@ public class ApiDefinitionService {
|
|||
} else {
|
||||
importCreate(item, batchMapper, apiTestCaseMapper, extApiDefinitionMapper, request, apiImport.getCases(), apiImport.getMocks(), updateList);
|
||||
}
|
||||
for (ApiModule apiModule : updateApiModuleDTO.getModuleList()) {
|
||||
if (moduleList != null) {
|
||||
for (ApiModule apiModule : moduleList) {
|
||||
apiModuleMapper.insert(apiModule);
|
||||
}
|
||||
}
|
||||
if (i % 300 == 0) {
|
||||
sqlSession.flushStatements();
|
||||
}
|
||||
|
|
|
@ -2,7 +2,9 @@ package io.metersphere.api.service;
|
|||
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.metersphere.api.dto.ApiTestImportRequest;
|
||||
import io.metersphere.api.dto.definition.*;
|
||||
import io.metersphere.api.dto.definition.parse.ApiDefinitionImport;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.ApiDefinitionMapper;
|
||||
import io.metersphere.base.mapper.ApiModuleMapper;
|
||||
|
@ -10,6 +12,7 @@ import io.metersphere.base.mapper.ext.ExtApiDefinitionMapper;
|
|||
import io.metersphere.base.mapper.ext.ExtApiModuleMapper;
|
||||
import io.metersphere.commons.constants.TestCaseConstants;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.BeanUtils;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.i18n.Translator;
|
||||
|
@ -600,137 +603,280 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
|
|||
/**
|
||||
* 上传文件时对文件的模块进行检测
|
||||
*
|
||||
* @param moduleId 上传文件时选的模块ID
|
||||
* @param projectId
|
||||
* @param protocol
|
||||
* @param data
|
||||
* @param fullCoverage 是否覆盖接口
|
||||
* @param fullCoverageApi 是否更新当前接口所在模块 (如果开启url重复,可重复的是某一模块下的接口,注:只在这个模块下,不包含其子模块)
|
||||
* @return Return to the newly added module list and api list
|
||||
*/
|
||||
public UpdateApiModuleDTO checkApiModule(String moduleId, String projectId, String protocol, List<ApiDefinitionWithBLOBs> data, Boolean fullCoverage, Boolean fullCoverageApi, boolean urlRepeat) {
|
||||
Map<String, ApiModule> map = new HashMap<>();
|
||||
Map<String, ApiDefinitionWithBLOBs> updateApiMap = new HashMap<>();
|
||||
public UpdateApiModuleDTO checkApiModule(ApiTestImportRequest request, ApiDefinitionImport apiImport, List<ApiDefinitionWithBLOBs> data, Boolean fullCoverage, boolean urlRepeat) {
|
||||
Boolean fullCoverageApi = request.getCoverModule();
|
||||
String projectId = request.getProjectId();
|
||||
String protocol = request.getProtocol();
|
||||
//上传文件时选的模块ID
|
||||
String chooseModuleId = request.getModuleId();
|
||||
//标准版ESB数据导入不区分是否覆盖,默认都为覆盖
|
||||
if (apiImport.getEsbApiParamsMap() != null) {
|
||||
fullCoverage = true;
|
||||
}
|
||||
String updateVersionId = getUpdateVersionId(request, fullCoverage);
|
||||
|
||||
//需要新增的模块,key 为模块路径
|
||||
Map<String, ApiModule> moduleMap = new HashMap<>();
|
||||
//系统原有的需要更新的list,
|
||||
List<ApiDefinitionWithBLOBs> toUpdateList = new ArrayList<>();
|
||||
//获取当前项目的当前协议下的所有模块的Tree
|
||||
List<ApiModuleDTO> apiModules = this.getApiModulesByProjectAndPro(projectId, protocol);
|
||||
List<ApiModuleDTO> nodeTreeByProjectId = this.getNodeTrees(apiModules);
|
||||
|
||||
Map<String, List<ApiModule>> pidChildrenMap = new HashMap<>();
|
||||
Map<String, String> idPathMap = new HashMap<>();
|
||||
//所有模块的ID 及其自身 的map
|
||||
Map<String, ApiModuleDTO> idModuleMap = apiModules.stream().collect(Collectors.toMap(ApiModuleDTO::getId, apiModuleDTO -> apiModuleDTO));
|
||||
buildProcessData(nodeTreeByProjectId, pidChildrenMap, idPathMap);
|
||||
|
||||
Map<String, ApiDefinitionWithBLOBs> methodPathMap = data.stream().collect(Collectors.toMap(t -> t.getMethod() + t.getPath(), apiDefinition -> apiDefinition));
|
||||
//父级ID与其子模块集合的map
|
||||
Map<String, List<ApiModule>> pidChildrenMap = new HashMap<>();
|
||||
//所有模块的ID 及其全路径的map
|
||||
Map<String, String> idPathMap = new HashMap<>();
|
||||
|
||||
String initParentModulePath = "/root";
|
||||
Map<String, String> initParentModulePathMap = new HashMap<>();
|
||||
initParentModulePathMap.put("root", initParentModulePath);
|
||||
buildProcessData(nodeTreeByProjectId, pidChildrenMap, idPathMap, initParentModulePathMap);
|
||||
|
||||
|
||||
//获取选中的模块
|
||||
ApiModuleDTO chooseModule = null;
|
||||
if (moduleId != null) {
|
||||
chooseModule = idModuleMap.get(moduleId);
|
||||
if (chooseModuleId != null) {
|
||||
chooseModule = idModuleMap.get(chooseModuleId);
|
||||
}
|
||||
|
||||
List<ApiDefinitionWithBLOBs> optionData = new ArrayList<>();
|
||||
|
||||
//去重 如果url可重复 则模块+名称+请求方式+路径 唯一,否则 请求方式+路径唯一,
|
||||
//覆盖模式留重复的最后一个,不覆盖留第一个
|
||||
removeRepeat(data, fullCoverage, urlRepeat, optionData);
|
||||
|
||||
//处理模块
|
||||
setModule(moduleMap, pidChildrenMap, idPathMap, idModuleMap, optionData, chooseModule);
|
||||
|
||||
//系统内重复的数据
|
||||
List<ApiDefinitionWithBLOBs> repeatApiDefinitionWithBLOBs;
|
||||
|
||||
if (chooseModule != null) {
|
||||
repeatApiDefinitionWithBLOBs = extApiDefinitionMapper.selectRepeatByBLOBsSameUrl(data, chooseModule.getId());
|
||||
repeatApiDefinitionWithBLOBs = extApiDefinitionMapper.selectRepeatByBLOBsSameUrl(data, projectId, chooseModule.getId(), updateVersionId);
|
||||
} else {
|
||||
repeatApiDefinitionWithBLOBs = extApiDefinitionMapper.selectRepeatByBLOBs(data);
|
||||
repeatApiDefinitionWithBLOBs = extApiDefinitionMapper.selectRepeatByBLOBs(data, projectId, updateVersionId);
|
||||
}
|
||||
|
||||
//允许接口重复
|
||||
//处理数据
|
||||
if (urlRepeat) {
|
||||
//允许覆盖接口
|
||||
//按照原来的顺序
|
||||
Map<String, ApiDefinitionWithBLOBs> methodPathMap = data.stream().collect(Collectors.toMap(t -> t.getName() + t.getMethod() + t.getPath() + (t.getModulePath() == null ? "" : t.getModulePath()), api -> api));
|
||||
//覆盖接口
|
||||
if (fullCoverage) {
|
||||
//允许覆盖模块
|
||||
//允许覆盖模块,用导入的重复数据的最后一条覆盖查询的所有重复数据
|
||||
if (fullCoverageApi) {
|
||||
coverApiModule(map, updateApiMap, pidChildrenMap, idPathMap, idModuleMap, methodPathMap, chooseModule, repeatApiDefinitionWithBLOBs);
|
||||
} else {
|
||||
//覆盖但不覆盖模块
|
||||
justCoverApi(map, updateApiMap, pidChildrenMap, idPathMap, idModuleMap, methodPathMap, chooseModule, repeatApiDefinitionWithBLOBs);
|
||||
}
|
||||
} else {
|
||||
//不覆盖接口,直接新增
|
||||
setModule(map, pidChildrenMap, idPathMap, idModuleMap, methodPathMap, chooseModule);
|
||||
}
|
||||
} else {
|
||||
//不允许接口重复
|
||||
if (fullCoverage) {
|
||||
if (fullCoverageApi) {
|
||||
coverApiModule(map, updateApiMap, pidChildrenMap, idPathMap, idModuleMap, methodPathMap, chooseModule, repeatApiDefinitionWithBLOBs);
|
||||
} else {
|
||||
//覆盖但不覆盖模块
|
||||
justCoverApi(map, updateApiMap, pidChildrenMap, idPathMap, idModuleMap, methodPathMap, chooseModule, repeatApiDefinitionWithBLOBs);
|
||||
}
|
||||
|
||||
} else {
|
||||
//不覆盖接口
|
||||
if (!repeatApiDefinitionWithBLOBs.isEmpty()) {
|
||||
Map<String, ApiDefinitionWithBLOBs> collect = repeatApiDefinitionWithBLOBs.stream().collect(Collectors.toMap(t -> t.getMethod() + t.getPath(), apiDefinition -> apiDefinition));
|
||||
collect.forEach((k, v) -> {
|
||||
if (methodPathMap.get(k) != null) {
|
||||
methodPathMap.remove(k);
|
||||
Map<String, List<ApiDefinitionWithBLOBs>> repeatDataMap = repeatApiDefinitionWithBLOBs.stream().collect(Collectors.groupingBy(t -> t.getName() + t.getMethod() + t.getPath() + t.getModulePath()));
|
||||
startCoverModule(toUpdateList, optionData, methodPathMap, repeatDataMap);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
//覆盖但不覆盖模块
|
||||
if (!repeatApiDefinitionWithBLOBs.isEmpty()) {
|
||||
Map<String, List<ApiDefinitionWithBLOBs>> repeatDataMap = repeatApiDefinitionWithBLOBs.stream().collect(Collectors.groupingBy(t -> t.getName() + t.getMethod() + t.getPath() + t.getModulePath()));
|
||||
moduleMap = judgeModuleMap(moduleMap, methodPathMap, repeatDataMap);
|
||||
startCover(toUpdateList, optionData, methodPathMap, repeatDataMap);
|
||||
}
|
||||
setModule(map, pidChildrenMap, idPathMap, idModuleMap, methodPathMap, chooseModule);
|
||||
}
|
||||
} else {
|
||||
//不覆盖,同一接口不做更新
|
||||
if (!repeatApiDefinitionWithBLOBs.isEmpty()) {
|
||||
Map<String, List<ApiDefinitionWithBLOBs>> repeatDataMap = repeatApiDefinitionWithBLOBs.stream().collect(Collectors.groupingBy(t -> t.getName() + t.getMethod() + t.getPath() + t.getModulePath()));
|
||||
removeSameData(repeatDataMap, methodPathMap, optionData);
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
Map<String, ApiDefinitionWithBLOBs> methodPathMap = optionData.stream().collect(Collectors.toMap(t -> t.getMethod() + t.getPath(), api -> api));
|
||||
if (fullCoverage) {
|
||||
if (fullCoverageApi) {
|
||||
if (!repeatApiDefinitionWithBLOBs.isEmpty()) {
|
||||
Map<String, List<ApiDefinitionWithBLOBs>> repeatDataMap = repeatApiDefinitionWithBLOBs.stream().collect(Collectors.groupingBy(t -> t.getMethod() + t.getPath()));
|
||||
startCoverModule(toUpdateList, optionData, methodPathMap, repeatDataMap);
|
||||
}
|
||||
} else {
|
||||
//不覆盖模块
|
||||
if (!repeatApiDefinitionWithBLOBs.isEmpty()) {
|
||||
Map<String, List<ApiDefinitionWithBLOBs>> repeatDataMap = repeatApiDefinitionWithBLOBs.stream().collect(Collectors.groupingBy(t -> t.getMethod() + t.getPath()));
|
||||
if (repeatDataMap.size() >= methodPathMap.size()) {
|
||||
//导入文件没有新增接口无需创建接口模块
|
||||
moduleMap = new HashMap<>();
|
||||
}
|
||||
startCover(toUpdateList, optionData, methodPathMap, repeatDataMap);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//不覆盖,同一接口不做更新
|
||||
if (!repeatApiDefinitionWithBLOBs.isEmpty()) {
|
||||
Map<String, List<ApiDefinitionWithBLOBs>> repeatDataMap = repeatApiDefinitionWithBLOBs.stream().collect(Collectors.groupingBy(t -> t.getMethod() + t.getPath()));
|
||||
removeSameData(repeatDataMap, methodPathMap, optionData);
|
||||
}
|
||||
}
|
||||
}
|
||||
UpdateApiModuleDTO updateApiModuleDTO = new UpdateApiModuleDTO();
|
||||
updateApiModuleDTO.setModuleList((List<ApiModule>) map.values());
|
||||
updateApiModuleDTO.setApiDefinitionWithBLOBsList((List<ApiDefinitionWithBLOBs>) updateApiMap.values());
|
||||
updateApiModuleDTO.setModuleList(new ArrayList<>(moduleMap.values()));
|
||||
updateApiModuleDTO.setNeedUpdateList(toUpdateList);
|
||||
updateApiModuleDTO.setDefinitionWithBLOBs(optionData);
|
||||
return updateApiModuleDTO;
|
||||
}
|
||||
|
||||
private void coverApiModule(Map<String, ApiModule> map, Map<String, ApiDefinitionWithBLOBs> updateApiMap, Map<String, List<ApiModule>> pidChildrenMap, Map<String, String> idPathMap, Map<String, ApiModuleDTO> idModuleMap, Map<String, ApiDefinitionWithBLOBs> methodPathMap, ApiModuleDTO chooseModule, List<ApiDefinitionWithBLOBs> repeatApiDefinitionWithBLOBs) {
|
||||
if (!repeatApiDefinitionWithBLOBs.isEmpty()) {
|
||||
Map<String, ApiDefinitionWithBLOBs> collect = repeatApiDefinitionWithBLOBs.stream().collect(Collectors.toMap(t -> t.getMethod() + t.getPath(), apiDefinition -> apiDefinition));
|
||||
collect.forEach((k, v) -> {
|
||||
ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = methodPathMap.get(k);
|
||||
if (apiDefinitionWithBLOBs != null) {
|
||||
//Check whether the content has changed, if not, do not change the creatoCover
|
||||
Boolean toCover = apiDefinitionService.checkIsSynchronize(v, apiDefinitionWithBLOBs);
|
||||
//需要更新
|
||||
if (toCover) {
|
||||
if (updateApiMap.get(k) != null) {
|
||||
apiDefinitionWithBLOBs.setId(v.getId());
|
||||
updateApiMap.put(k, apiDefinitionWithBLOBs);
|
||||
private void removeRepeat(List<ApiDefinitionWithBLOBs> data, Boolean fullCoverage, boolean urlRepeat, List<ApiDefinitionWithBLOBs> optionData) {
|
||||
if (urlRepeat) {
|
||||
LinkedHashMap<String, List<ApiDefinitionWithBLOBs>> methodPathMap = data.stream().collect(Collectors.groupingBy(t -> t.getName() + t.getMethod() + t.getPath() + (t.getModulePath() == null ? "" : t.getModulePath()), LinkedHashMap::new, Collectors.toList()));
|
||||
if (fullCoverage) {
|
||||
methodPathMap.forEach((k, v) -> {
|
||||
optionData.add(v.get(v.size() - 1));
|
||||
});
|
||||
} else {
|
||||
methodPathMap.forEach((k, v) -> {
|
||||
optionData.add(v.get(0));
|
||||
});
|
||||
}
|
||||
} else {
|
||||
methodPathMap.remove(k);
|
||||
}
|
||||
}
|
||||
LinkedHashMap<String, List<ApiDefinitionWithBLOBs>> methodPathMap = data.stream().collect(Collectors.groupingBy(t -> t.getMethod() + t.getPath(), LinkedHashMap::new, Collectors.toList()));
|
||||
if (fullCoverage) {
|
||||
methodPathMap.forEach((k, v) -> {
|
||||
optionData.add(v.get(v.size() - 1));
|
||||
});
|
||||
} else {
|
||||
methodPathMap.forEach((k, v) -> {
|
||||
optionData.add(v.get(0));
|
||||
});
|
||||
}
|
||||
setModule(map, pidChildrenMap, idPathMap, idModuleMap, methodPathMap, chooseModule);
|
||||
}
|
||||
}
|
||||
|
||||
private void justCoverApi(Map<String, ApiModule> map, Map<String, ApiDefinitionWithBLOBs> updateApiMap, Map<String, List<ApiModule>> pidChildrenMap, Map<String, String> idPathMap, Map<String, ApiModuleDTO> idModuleMap, Map<String, ApiDefinitionWithBLOBs> methodPathMap, ApiModuleDTO chooseModule, List<ApiDefinitionWithBLOBs> repeatApiDefinitionWithBLOBs) {
|
||||
if (!repeatApiDefinitionWithBLOBs.isEmpty()) {
|
||||
Map<String, ApiDefinitionWithBLOBs> collect = repeatApiDefinitionWithBLOBs.stream().collect(Collectors.toMap(t -> t.getMethod() + t.getPath(), apiDefinition -> apiDefinition));
|
||||
collect.forEach((k, v) -> {
|
||||
private String getUpdateVersionId(ApiTestImportRequest request, Boolean fullCoverage) {
|
||||
String updateVersionId;
|
||||
if (!fullCoverage) {
|
||||
if (request.getVersionId() == null) {
|
||||
updateVersionId = request.getDefaultVersion();
|
||||
} else {
|
||||
updateVersionId = request.getVersionId();
|
||||
}
|
||||
} else {
|
||||
if (request.getUpdateVersionId() == null) {
|
||||
updateVersionId = request.getDefaultVersion();
|
||||
} else {
|
||||
updateVersionId = request.getUpdateVersionId();
|
||||
}
|
||||
}
|
||||
return updateVersionId;
|
||||
}
|
||||
|
||||
private void removeSameData(Map<String, List<ApiDefinitionWithBLOBs>> repeatDataMap, Map<String, ApiDefinitionWithBLOBs> methodPathMap, List<ApiDefinitionWithBLOBs> optionData) {
|
||||
repeatDataMap.forEach((k, v) -> {
|
||||
ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = methodPathMap.get(k);
|
||||
if (apiDefinitionWithBLOBs != null) {
|
||||
//Check whether the content has changed, if not, do not change the creatoCover
|
||||
Boolean toCover = apiDefinitionService.checkIsSynchronize(v, apiDefinitionWithBLOBs);
|
||||
//需要更新
|
||||
if (toCover) {
|
||||
if (updateApiMap.get(k) != null) {
|
||||
apiDefinitionWithBLOBs.setId(v.getId());
|
||||
updateApiMap.put(k, apiDefinitionWithBLOBs);
|
||||
}
|
||||
}
|
||||
methodPathMap.remove(k);
|
||||
optionData.remove(apiDefinitionWithBLOBs);
|
||||
}
|
||||
});
|
||||
}
|
||||
setModule(map, pidChildrenMap, idPathMap, idModuleMap, methodPathMap, chooseModule);
|
||||
|
||||
private void startCoverModule(List<ApiDefinitionWithBLOBs> toUpdateList, List<ApiDefinitionWithBLOBs> optionData, Map<String, ApiDefinitionWithBLOBs> methodPathMap, Map<String, List<ApiDefinitionWithBLOBs>> repeatDataMap) {
|
||||
List<ApiDefinitionWithBLOBs> coverApiList = new ArrayList<>();
|
||||
repeatDataMap.forEach((k, v) -> {
|
||||
ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = methodPathMap.get(k);
|
||||
if (apiDefinitionWithBLOBs != null) {
|
||||
for (ApiDefinitionWithBLOBs definitionWithBLOBs : v) {
|
||||
ApiDefinitionWithBLOBs api = new ApiDefinitionWithBLOBs();
|
||||
BeanUtils.copyBean(api, apiDefinitionWithBLOBs);
|
||||
api.setId(definitionWithBLOBs.getId());
|
||||
coverApiList.add(api);
|
||||
}
|
||||
optionData.remove(apiDefinitionWithBLOBs);
|
||||
}
|
||||
});
|
||||
buildOtherParam(toUpdateList, optionData, coverApiList);
|
||||
}
|
||||
|
||||
private void setModule(Map<String, ApiModule> map, Map<String, List<ApiModule>> pidChildrenMap, Map<String, String> idPathMap, Map<String, ApiModuleDTO> idModuleMap, Map<String, ApiDefinitionWithBLOBs> methodPathMap, ApiModuleDTO chooseModule) {
|
||||
methodPathMap.forEach((methodPath, datum) -> {
|
||||
String[] pathTree;
|
||||
private void startCover(List<ApiDefinitionWithBLOBs> toUpdateList, List<ApiDefinitionWithBLOBs> optionData, Map<String, ApiDefinitionWithBLOBs> methodPathMap, Map<String, List<ApiDefinitionWithBLOBs>> repeatDataMap) {
|
||||
List<ApiDefinitionWithBLOBs> coverApiList = new ArrayList<>();
|
||||
repeatDataMap.forEach((k, v) -> {
|
||||
ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = methodPathMap.get(k);
|
||||
if (apiDefinitionWithBLOBs != null) {
|
||||
for (ApiDefinitionWithBLOBs definitionWithBLOBs : v) {
|
||||
ApiDefinitionWithBLOBs api = new ApiDefinitionWithBLOBs();
|
||||
BeanUtils.copyBean(api, apiDefinitionWithBLOBs);
|
||||
api.setId(definitionWithBLOBs.getId());
|
||||
api.setModuleId(definitionWithBLOBs.getModuleId());
|
||||
api.setModulePath(definitionWithBLOBs.getModulePath());
|
||||
coverApiList.add(api);
|
||||
}
|
||||
optionData.remove(apiDefinitionWithBLOBs);
|
||||
}
|
||||
});
|
||||
buildOtherParam(toUpdateList, optionData, coverApiList);
|
||||
}
|
||||
|
||||
private Map<String, ApiModule> judgeModuleMap(Map<String, ApiModule> moduleMap, Map<String, ApiDefinitionWithBLOBs> methodPathMap, Map<String, List<ApiDefinitionWithBLOBs>> repeatDataMap) {
|
||||
Set<String> repeatKeys = repeatDataMap.keySet();
|
||||
Set<String> importKeys = methodPathMap.keySet();
|
||||
List<String> repeatKeyList = new ArrayList<>(repeatKeys);
|
||||
List<String> importKeysList = new ArrayList<>(importKeys);
|
||||
List<String> intersection = repeatKeyList.stream().filter(item -> importKeysList.contains(item)).collect(Collectors.toList());
|
||||
if (intersection.size() == importKeysList.size()) {
|
||||
//导入文件没有新增接口无需创建接口模块
|
||||
moduleMap = new HashMap<>();
|
||||
}
|
||||
return moduleMap;
|
||||
}
|
||||
|
||||
private void buildOtherParam(List<ApiDefinitionWithBLOBs> toUpdateList, List<ApiDefinitionWithBLOBs> optionData, List<ApiDefinitionWithBLOBs> coverApiList) {
|
||||
optionData.addAll(coverApiList);
|
||||
toUpdateList.addAll(coverApiList);
|
||||
}
|
||||
|
||||
private List<ApiDefinitionWithBLOBs> setModule(Map<String, ApiModule> moduleMap, Map<String, List<ApiModule>> pidChildrenMap,
|
||||
Map<String, String> idPathMap, Map<String, ApiModuleDTO> idModuleMap, List<ApiDefinitionWithBLOBs> data, ApiModuleDTO chooseModule) {
|
||||
for (ApiDefinitionWithBLOBs datum : data) {
|
||||
String modulePath = datum.getModulePath();
|
||||
ApiModule apiModule = map.get(modulePath);
|
||||
ApiModule apiModule = moduleMap.get(modulePath);
|
||||
if (chooseModule != null) {
|
||||
dealChooseModuleData(moduleMap, pidChildrenMap, idPathMap, idModuleMap, chooseModule, datum, modulePath);
|
||||
} else {
|
||||
dealNoModuleData(moduleMap, pidChildrenMap, idPathMap, idModuleMap, datum, modulePath, apiModule);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
private void dealNoModuleData(Map<String, ApiModule> moduleMap, Map<String, List<ApiModule>> pidChildrenMap, Map<String, String> idPathMap, Map<String, ApiModuleDTO> idModuleMap, ApiDefinitionWithBLOBs datum, String modulePath, ApiModule apiModule) {
|
||||
String[] pathTree;
|
||||
if (StringUtils.isNotBlank(modulePath)) {
|
||||
//导入时没选模块但接口有模块的,根据modulePath,和当前协议查询当前项目里是否有同名称模块,如果有,就在该模块下建立接口,否则新建模块
|
||||
pathTree = getPathTree(modulePath);
|
||||
if (apiModule != null) {
|
||||
datum.setModuleId(apiModule.getId());
|
||||
datum.setModulePath(modulePath);
|
||||
} else {
|
||||
List<ApiModule> moduleList = pidChildrenMap.get("root");
|
||||
ApiModule minModule = getMinModule(pathTree, moduleList, null, pidChildrenMap, moduleMap, idPathMap, idModuleMap);
|
||||
String id = minModule.getId();
|
||||
datum.setModuleId(id);
|
||||
datum.setModulePath(idPathMap.get(id));
|
||||
}
|
||||
} else {
|
||||
//导入时即没选中模块,接口自身也没模块的,直接返会当前项目,当前协议下的默认模块
|
||||
List<ApiModule> moduleList = pidChildrenMap.get("root");
|
||||
for (ApiModule module : moduleList) {
|
||||
if (module.getName().equals("未规划接口")) {
|
||||
datum.setModuleId(module.getId());
|
||||
datum.setModulePath("/" + module.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void dealChooseModuleData(Map<String, ApiModule> moduleMap, Map<String, List<ApiModule>> pidChildrenMap, Map<String, String> idPathMap, Map<String, ApiModuleDTO> idModuleMap, ApiModuleDTO chooseModule, ApiDefinitionWithBLOBs datum, String modulePath) {
|
||||
String[] pathTree;
|
||||
if (chooseModule.getParentId() == null) {
|
||||
chooseModule.setParentId("root");
|
||||
}
|
||||
|
@ -747,7 +893,7 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
|
|||
pathTree = getPathTree(s + modulePath);
|
||||
|
||||
ApiModule chooseModuleOne = JSON.parseObject(JSON.toJSONString(chooseModule), ApiModule.class);
|
||||
ApiModule minModule = getMinModule(pathTree, moduleList, chooseModuleOne, pidChildrenMap, map, idPathMap, idModuleMap);
|
||||
ApiModule minModule = getMinModule(pathTree, moduleList, chooseModuleOne, pidChildrenMap, moduleMap, idPathMap, idModuleMap);
|
||||
String id = minModule.getId();
|
||||
datum.setModuleId(id);
|
||||
datum.setModulePath(idPathMap.get(id));
|
||||
|
@ -756,32 +902,6 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
|
|||
datum.setModuleId(chooseModule.getId());
|
||||
datum.setModulePath(idPathMap.get(chooseModule.getId()));
|
||||
}
|
||||
} else {
|
||||
if (StringUtils.isNotBlank(modulePath)) {
|
||||
//导入时没选模块但接口有模块的,根据modulePath,和当前协议查询当前项目里是否有同名称模块,如果有,就在该模块下建立接口,否则新建模块
|
||||
pathTree = getPathTree(modulePath);
|
||||
if (apiModule != null) {
|
||||
datum.setModuleId(apiModule.getId());
|
||||
datum.setModulePath(modulePath);
|
||||
} else {
|
||||
List<ApiModule> moduleList = pidChildrenMap.get("root");
|
||||
ApiModule minModule = getMinModule(pathTree, moduleList, null, pidChildrenMap, map, idPathMap, idModuleMap);
|
||||
String id = minModule.getId();
|
||||
datum.setModuleId(id);
|
||||
datum.setModulePath(idPathMap.get(id));
|
||||
}
|
||||
} else {
|
||||
//导入时即没选中模块,接口自身也没模块的,直接返会当前项目,当前协议下的默认模块
|
||||
List<ApiModule> moduleList = pidChildrenMap.get("root");
|
||||
for (ApiModule module : moduleList) {
|
||||
if (module.getName().equals("未规划接口")) {
|
||||
datum.setModuleId(module.getId());
|
||||
datum.setModulePath("/" + module.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private String[] getPathTree(String modulePath) {
|
||||
|
@ -797,7 +917,8 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
|
|||
}
|
||||
}
|
||||
|
||||
private ApiModule getMinModule(String[] tagTree, List<ApiModule> moduleList, ApiModule parentModule, Map<String, List<ApiModule>> pidChildrenMap, Map<String, ApiModule> map, Map<String, String> idPathMap, Map<String, ApiModuleDTO> idModuleMap) {
|
||||
private ApiModule getMinModule(String[] tagTree, List<ApiModule> moduleList, ApiModule parentModule, Map<String, List<ApiModule>> pidChildrenMap, Map<String, ApiModule> moduleMap
|
||||
, Map<String, String> idPathMap, Map<String, ApiModuleDTO> idModuleMap) {
|
||||
//如果parentModule==null 则证明需要创建根目录同级的模块
|
||||
ApiModule returnModule = null;
|
||||
for (int i = 0; i < tagTree.length; i++) {
|
||||
|
@ -817,7 +938,7 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
|
|||
parentModule = JSON.parseObject(JSON.toJSONString(apiModuleDTO), ApiModule.class);
|
||||
}
|
||||
}
|
||||
return createModule(tagTree, i, parentModule, map, pidChildrenMap, idPathMap);
|
||||
return createModule(tagTree, i, parentModule, moduleMap, pidChildrenMap, idPathMap);
|
||||
} else {
|
||||
returnModule = collect.get(0);
|
||||
moduleList = pidChildrenMap.get(collect.get(0).getId());
|
||||
|
@ -826,8 +947,7 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
|
|||
return returnModule;
|
||||
}
|
||||
|
||||
|
||||
private ApiModule createModule(String[] tagTree, int i, ApiModule parentModule, Map<String, ApiModule> map, Map<String, List<ApiModule>> pidChildrenMap, Map<String, String> idPathMap) {
|
||||
private ApiModule createModule(String[] tagTree, int i, ApiModule parentModule, Map<String, ApiModule> moduleMap, Map<String, List<ApiModule>> pidChildrenMap, Map<String, String> idPathMap) {
|
||||
ApiModule returnModule = null;
|
||||
for (int i1 = i; i1 < tagTree.length; i1++) {
|
||||
String pathName = tagTree[i1];
|
||||
|
@ -859,27 +979,30 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
|
|||
path = "/" + pathName;
|
||||
}
|
||||
idPathMap.put(newModule.getId(), path);
|
||||
map.putIfAbsent(path, newModule);
|
||||
moduleMap.putIfAbsent(path, newModule);
|
||||
parentModule = newModule;
|
||||
returnModule = newModule;
|
||||
}
|
||||
return returnModule;
|
||||
}
|
||||
|
||||
private void buildProcessData(List<ApiModuleDTO> nodeTreeByProjectId, Map<String, List<ApiModule>> pidChildrenMap, Map<String, String> idPathMap) {
|
||||
private void buildProcessData(List<ApiModuleDTO> nodeTreeByProjectId, Map<String, List<ApiModule>> pidChildrenMap, Map<String, String> idPathMap, Map<String, String> parentModulePathMap) {
|
||||
//当前层级的模块的所有子模块的集合
|
||||
List<ApiModuleDTO> childrenList = new ArrayList<>();
|
||||
int i = 0;
|
||||
List<ApiModule> moduleList = new ArrayList<>();
|
||||
for (ApiModuleDTO apiModuleDTO : nodeTreeByProjectId) {
|
||||
if (apiModuleDTO.getPath() != null) {
|
||||
apiModuleDTO.setPath(apiModuleDTO.getPath() + "/" + apiModuleDTO.getName());
|
||||
if (StringUtils.isBlank(apiModuleDTO.getParentId())) {
|
||||
apiModuleDTO.setParentId("root");
|
||||
}
|
||||
String parentModulePath = parentModulePathMap.get(apiModuleDTO.getParentId());
|
||||
if (parentModulePath != null) {
|
||||
apiModuleDTO.setPath(parentModulePath + "/" + apiModuleDTO.getName());
|
||||
} else {
|
||||
apiModuleDTO.setPath("/" + apiModuleDTO.getName());
|
||||
}
|
||||
idPathMap.put(apiModuleDTO.getId(), apiModuleDTO.getPath());
|
||||
if (StringUtils.isBlank(apiModuleDTO.getParentId())) {
|
||||
apiModuleDTO.setParentId("root");
|
||||
}
|
||||
|
||||
ApiModule apiModule = buildModule(moduleList, apiModuleDTO);
|
||||
if (pidChildrenMap.get(apiModuleDTO.getParentId()) != null) {
|
||||
pidChildrenMap.get(apiModuleDTO.getParentId()).add(apiModule);
|
||||
|
@ -895,9 +1018,10 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
|
|||
pidChildrenMap.put(apiModuleDTO.getId(), new ArrayList<>());
|
||||
}
|
||||
}
|
||||
parentModulePathMap.put(apiModuleDTO.getId(), apiModuleDTO.getPath());
|
||||
}
|
||||
if (i == nodeTreeByProjectId.size() && nodeTreeByProjectId.size() > 0) {
|
||||
buildProcessData(childrenList, pidChildrenMap, idPathMap);
|
||||
buildProcessData(childrenList, pidChildrenMap, idPathMap, parentModulePathMap);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -913,5 +1037,4 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
|
|||
return apiModule;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package io.metersphere.api.service;
|
|||
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.metersphere.api.dto.ApiTestImportRequest;
|
||||
import io.metersphere.api.dto.automation.*;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.ApiScenarioMapper;
|
||||
|
@ -472,111 +473,161 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD
|
|||
/**
|
||||
* 上传文件时对文件的模块进行检测
|
||||
*
|
||||
* @param moduleId 上传文件时选的模块ID
|
||||
* @param projectId
|
||||
* @param data
|
||||
* @param fullCoverage 是否覆盖接口
|
||||
* @param fullCoverageApi 是否更新当前接口所在模块
|
||||
* @return Return to the newly added module map
|
||||
*/
|
||||
public UpdateScenarioModuleDTO checkScenarioModule(String moduleId, String projectId, List<ApiScenarioWithBLOBs> data, Boolean fullCoverage, Boolean fullCoverageApi) {
|
||||
Map<String, ApiScenarioModule> map = new HashMap<>();
|
||||
Map<String, ApiScenarioWithBLOBs> updateMap = new HashMap<>();
|
||||
public UpdateScenarioModuleDTO checkScenarioModule(ApiTestImportRequest request, List<ApiScenarioWithBLOBs> data, Boolean fullCoverage, Boolean fullCoverageApi) {
|
||||
//需要新增的模块,key 为模块路径
|
||||
Map<String, ApiScenarioModule> moduleMap = new HashMap<>();
|
||||
List<ApiScenarioWithBLOBs> toUpdateList = new ArrayList<>();
|
||||
|
||||
//上传文件时选的模块ID
|
||||
String chooseModuleId = request.getModuleId();
|
||||
String projectId = request.getProjectId();
|
||||
|
||||
//获取当前项目的当前协议下的所有模块的Tree
|
||||
List<ApiScenarioModuleDTO> scenarioModules = extApiScenarioModuleMapper.getNodeTreeByProjectId(projectId);
|
||||
List<ApiScenarioModuleDTO> nodeTreeByProjectId = this.getNodeTrees(scenarioModules);
|
||||
|
||||
Map<String, ApiScenarioModuleDTO> idModuleMap = scenarioModules.stream().collect(Collectors.toMap(ApiScenarioModuleDTO::getId, scenarioModuleDTO -> scenarioModuleDTO));
|
||||
|
||||
Map<String, List<ApiScenarioModule>> pidChildrenMap = new HashMap<>();
|
||||
Map<String, String> idPathMap = new HashMap<>();
|
||||
Map<String, ApiScenarioModuleDTO> idModuleMap = scenarioModules.stream().collect(Collectors.toMap(ApiScenarioModuleDTO::getId, scenarioModuleDTO -> scenarioModuleDTO));
|
||||
buildProcessData(nodeTreeByProjectId, pidChildrenMap, idPathMap);
|
||||
|
||||
Map<String, ApiScenarioWithBLOBs> nameMap = data.stream().collect(Collectors.toMap(ApiScenario::getName, apiScenario -> apiScenario));
|
||||
|
||||
//构建以上两种数据
|
||||
String initParentModulePath = "/root";
|
||||
Map<String, String> initParentModulePathMap = new HashMap<>();
|
||||
initParentModulePathMap.put("root", initParentModulePath);
|
||||
buildProcessData(nodeTreeByProjectId, pidChildrenMap, idPathMap, initParentModulePathMap);
|
||||
|
||||
ApiScenarioModuleDTO chooseModule = null;
|
||||
if (moduleId != null) {
|
||||
chooseModule = idModuleMap.get(moduleId);
|
||||
if (chooseModuleId != null) {
|
||||
chooseModule = idModuleMap.get(chooseModuleId);
|
||||
}
|
||||
|
||||
String updateVersionId = getUpdateVersionId(request, fullCoverage);
|
||||
|
||||
List<ApiScenarioWithBLOBs> optionData = new ArrayList<>();
|
||||
|
||||
//覆盖模式留重复的最后一个,不覆盖留第一个
|
||||
LinkedHashMap<String, List<ApiScenarioWithBLOBs>> nameModuleMapList = data.stream().collect(Collectors.groupingBy(t -> t.getName() + (t.getModulePath() == null ? "" : t.getModulePath()), LinkedHashMap::new, Collectors.toList()));
|
||||
removeRepeat(fullCoverage, optionData, nameModuleMapList);
|
||||
|
||||
//处理模块
|
||||
setModule(optionData, moduleMap, pidChildrenMap, idPathMap, idModuleMap, chooseModule);
|
||||
|
||||
//系统内重复的数据
|
||||
List<ApiScenarioWithBLOBs> repeatApiScenarioWithBLOBs;
|
||||
|
||||
if (chooseModule != null) {
|
||||
repeatApiScenarioWithBLOBs = extApiScenarioMapper.selectRepeatByBLOBsSameUrl(data, chooseModule.getId());
|
||||
repeatApiScenarioWithBLOBs = extApiScenarioMapper.selectRepeatByBLOBsSameUrl(data, projectId, chooseModule.getId(), updateVersionId);
|
||||
} else {
|
||||
repeatApiScenarioWithBLOBs = extApiScenarioMapper.selectRepeatByBLOBs(data);
|
||||
repeatApiScenarioWithBLOBs = extApiScenarioMapper.selectRepeatByBLOBs(data, projectId, updateVersionId);
|
||||
}
|
||||
|
||||
Map<String, ApiScenarioWithBLOBs> nameModuleMap = optionData.stream().collect(Collectors.toMap(t -> t.getName() + (t.getModulePath() == null ? "" : t.getModulePath()), scenario -> scenario));
|
||||
Map<String, ApiScenarioWithBLOBs> repeatDataMap = null;
|
||||
if (!repeatApiScenarioWithBLOBs.isEmpty()) {
|
||||
repeatDataMap = repeatApiScenarioWithBLOBs.stream().collect(Collectors.toMap(t -> t.getName() + t.getModulePath(), scenario -> scenario));
|
||||
}
|
||||
//处理数据
|
||||
if (fullCoverage) {
|
||||
if (fullCoverageApi) {
|
||||
coverScenarioModule(updateMap, nameMap, repeatApiScenarioWithBLOBs);
|
||||
startCoverModule(toUpdateList, nameModuleMap, repeatDataMap);
|
||||
} else {
|
||||
//只覆盖场景
|
||||
justCoverScenario(updateMap, nameMap, repeatApiScenarioWithBLOBs);
|
||||
//覆盖但不覆盖模块
|
||||
if (repeatDataMap != null) {
|
||||
//导入文件没有新增场景无需创建接口模块
|
||||
moduleMap = judgeModuleMap(moduleMap, nameModuleMap, repeatDataMap);
|
||||
startCover(toUpdateList, nameModuleMap, repeatDataMap);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//不覆盖
|
||||
if (!repeatApiScenarioWithBLOBs.isEmpty()) {
|
||||
Map<String, ApiScenarioWithBLOBs> collect = repeatApiScenarioWithBLOBs.stream().collect(Collectors.toMap(ApiScenario::getName, scenario -> scenario));
|
||||
collect.forEach((k, v) -> {
|
||||
if (nameMap.get(k) != null) {
|
||||
nameMap.remove(k);
|
||||
}
|
||||
});
|
||||
}
|
||||
setModule(nameMap, map, pidChildrenMap, idPathMap, idModuleMap, chooseModule);
|
||||
removeRepeat(optionData, nameModuleMap, repeatDataMap);
|
||||
}
|
||||
|
||||
UpdateScenarioModuleDTO updateScenarioModuleDTO = new UpdateScenarioModuleDTO();
|
||||
updateScenarioModuleDTO.setModuleList((List<ApiScenarioModule>) map.values());
|
||||
updateScenarioModuleDTO.setApiScenarioWithBLOBsList((List<ApiScenarioWithBLOBs>) nameMap.values());
|
||||
|
||||
updateScenarioModuleDTO.setModuleList(new ArrayList<>(moduleMap.values()));
|
||||
updateScenarioModuleDTO.setNeedUpdateList(toUpdateList);
|
||||
updateScenarioModuleDTO.setApiScenarioWithBLOBsList(optionData);
|
||||
return updateScenarioModuleDTO;
|
||||
}
|
||||
|
||||
private void coverScenarioModule(Map<String, ApiScenarioWithBLOBs> updateMap, Map<String, ApiScenarioWithBLOBs> nameMap, List<ApiScenarioWithBLOBs> repeatApiScenarioWithBLOBs) {
|
||||
if (!repeatApiScenarioWithBLOBs.isEmpty()) {
|
||||
Map<String, ApiScenarioWithBLOBs> collect = repeatApiScenarioWithBLOBs.stream().collect(Collectors.toMap(ApiScenario::getName, apiScenario -> apiScenario));
|
||||
collect.forEach((name, scenario) -> {
|
||||
ApiScenarioWithBLOBs apiScenarioWithBLOBs = nameMap.get(name);
|
||||
private void removeRepeat(List<ApiScenarioWithBLOBs> optionData, Map<String, ApiScenarioWithBLOBs> nameModuleMap, Map<String, ApiScenarioWithBLOBs> repeatDataMap) {
|
||||
if (repeatDataMap != null) {
|
||||
repeatDataMap.forEach((k, v) -> {
|
||||
ApiScenarioWithBLOBs apiScenarioWithBLOBs = nameModuleMap.get(k);
|
||||
if (apiScenarioWithBLOBs != null) {
|
||||
//Check whether the content has changed, if not, do not change the creatoCover
|
||||
Boolean toCover = apiAutomationService.checkIsSynchronize(scenario, apiScenarioWithBLOBs);
|
||||
//需要更新
|
||||
if (toCover) {
|
||||
if (updateMap.get(name) != null) {
|
||||
apiScenarioWithBLOBs.setId(scenario.getId());
|
||||
updateMap.put(name, apiScenarioWithBLOBs);
|
||||
optionData.remove(apiScenarioWithBLOBs);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void startCover(List<ApiScenarioWithBLOBs> toUpdateList, Map<String, ApiScenarioWithBLOBs> nameModuleMap, Map<String, ApiScenarioWithBLOBs> repeatDataMap) {
|
||||
repeatDataMap.forEach((k, v) -> {
|
||||
ApiScenarioWithBLOBs apiScenarioWithBLOBs = nameModuleMap.get(k);
|
||||
if (apiScenarioWithBLOBs != null) {
|
||||
apiScenarioWithBLOBs.setId(v.getId());
|
||||
apiScenarioWithBLOBs.setApiScenarioModuleId(v.getApiScenarioModuleId());
|
||||
apiScenarioWithBLOBs.setModulePath(v.getModulePath());
|
||||
toUpdateList.add(apiScenarioWithBLOBs);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private Map<String, ApiScenarioModule> judgeModuleMap(Map<String, ApiScenarioModule> moduleMap, Map<String, ApiScenarioWithBLOBs> nameModuleMap, Map<String, ApiScenarioWithBLOBs> repeatDataMap) {
|
||||
if (repeatDataMap.size() >= nameModuleMap.size()) {
|
||||
moduleMap = new HashMap<>();
|
||||
}
|
||||
return moduleMap;
|
||||
}
|
||||
|
||||
private void startCoverModule(List<ApiScenarioWithBLOBs> toUpdateList, Map<String, ApiScenarioWithBLOBs> nameModuleMap, Map<String, ApiScenarioWithBLOBs> repeatDataMap) {
|
||||
if (repeatDataMap != null) {
|
||||
repeatDataMap.forEach((k, v) -> {
|
||||
ApiScenarioWithBLOBs apiScenarioWithBLOBs = nameModuleMap.get(k);
|
||||
if (apiScenarioWithBLOBs != null) {
|
||||
apiScenarioWithBLOBs.setId(v.getId());
|
||||
toUpdateList.add(apiScenarioWithBLOBs);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void removeRepeat(Boolean fullCoverage, List<ApiScenarioWithBLOBs> optionData, LinkedHashMap<String, List<ApiScenarioWithBLOBs>> nameModuleMapList) {
|
||||
if (fullCoverage) {
|
||||
nameModuleMapList.forEach((k, v) -> {
|
||||
optionData.add(v.get(v.size() - 1));
|
||||
});
|
||||
} else {
|
||||
nameModuleMapList.forEach((k, v) -> {
|
||||
optionData.add(v.get(0));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private String getUpdateVersionId(ApiTestImportRequest request, Boolean fullCoverage) {
|
||||
String updateVersionId;
|
||||
if (!fullCoverage) {
|
||||
if (request.getVersionId() == null) {
|
||||
updateVersionId = request.getDefaultVersion();
|
||||
} else {
|
||||
updateVersionId = request.getVersionId();
|
||||
}
|
||||
} else {
|
||||
nameMap.remove(name);
|
||||
if (request.getUpdateVersionId() == null) {
|
||||
updateVersionId = request.getDefaultVersion();
|
||||
} else {
|
||||
updateVersionId = request.getUpdateVersionId();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return updateVersionId;
|
||||
}
|
||||
|
||||
private void justCoverScenario(Map<String, ApiScenarioWithBLOBs> updateMap, Map<String, ApiScenarioWithBLOBs> nameMap, List<ApiScenarioWithBLOBs> repeatApiScenarioWithBLOBs) {
|
||||
if (!repeatApiScenarioWithBLOBs.isEmpty()) {
|
||||
Map<String, ApiScenarioWithBLOBs> collect = repeatApiScenarioWithBLOBs.stream().collect(Collectors.toMap(ApiScenario::getName, apiScenario -> apiScenario));
|
||||
collect.forEach((name, scenario) -> {
|
||||
ApiScenarioWithBLOBs apiScenarioWithBLOBs = nameMap.get(name);
|
||||
if (apiScenarioWithBLOBs != null) {
|
||||
//Check whether the content has changed, if not, do not change the creatoCover
|
||||
Boolean toCover = apiAutomationService.checkIsSynchronize(scenario, apiScenarioWithBLOBs);
|
||||
//需要更新
|
||||
if (toCover) {
|
||||
if (updateMap.get(name) != null) {
|
||||
apiScenarioWithBLOBs.setId(scenario.getId());
|
||||
updateMap.put(name, apiScenarioWithBLOBs);
|
||||
}
|
||||
}
|
||||
nameMap.remove(name);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void setModule(Map<String, ApiScenarioWithBLOBs> nameMap, Map<String, ApiScenarioModule> map, Map<String, List<ApiScenarioModule>> pidChildrenMap, Map<String, String> idPathMap, Map<String, ApiScenarioModuleDTO> idModuleMap, ApiScenarioModuleDTO chooseModule) {
|
||||
nameMap.forEach((k, datum) -> {
|
||||
private void setModule(List<ApiScenarioWithBLOBs> data, Map<String, ApiScenarioModule> map, Map<String, List<ApiScenarioModule>> pidChildrenMap, Map<String, String> idPathMap, Map<String, ApiScenarioModuleDTO> idModuleMap, ApiScenarioModuleDTO chooseModule) {
|
||||
for (ApiScenarioWithBLOBs datum : data) {
|
||||
StringBuilder path = new StringBuilder();
|
||||
path.append("/");
|
||||
String[] tagTree;
|
||||
|
@ -589,17 +640,19 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD
|
|||
String chooseModuleParentId = chooseModule.getParentId();
|
||||
//导入时选了模块,且接口有模块的
|
||||
if (StringUtils.isNotBlank(modulePath)) {
|
||||
List<ApiScenarioModule> moduleList = pidChildrenMap.get(chooseModuleParentId);
|
||||
//选中模块的同级模块集合,用于和场景的全路径做对比
|
||||
List<ApiScenarioModule> parentModuleList = pidChildrenMap.get(chooseModuleParentId);
|
||||
String s;
|
||||
if (chooseModuleParentId.equals("root")) {
|
||||
s = "/" + chooseModule.getName();
|
||||
} else {
|
||||
s = idPathMap.get(chooseModuleParentId);
|
||||
}
|
||||
//场景的全部路径的集合
|
||||
tagTree = getTagTree(s + modulePath);
|
||||
|
||||
ApiScenarioModule chooseModuleOne = JSON.parseObject(JSON.toJSONString(chooseModule), ApiScenarioModule.class);
|
||||
ApiScenarioModule minModule = getMinModule(tagTree, moduleList, chooseModuleOne, pidChildrenMap, map, idPathMap, idModuleMap);
|
||||
ApiScenarioModule minModule = getMinModule(tagTree, parentModuleList, chooseModuleOne, pidChildrenMap, map, idPathMap, idModuleMap);
|
||||
String id = minModule.getId();
|
||||
datum.setApiScenarioModuleId(id);
|
||||
datum.setModulePath(idPathMap.get(id));
|
||||
|
@ -616,8 +669,9 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD
|
|||
datum.setApiScenarioModuleId(scenarioModule.getId());
|
||||
datum.setModulePath(modulePath);
|
||||
} else {
|
||||
List<ApiScenarioModule> moduleList = pidChildrenMap.get("root");
|
||||
ApiScenarioModule minModule = getMinModule(tagTree, moduleList, null, pidChildrenMap, map, idPathMap, idModuleMap);
|
||||
//父级同级的模块list
|
||||
List<ApiScenarioModule> parentModuleList = pidChildrenMap.get("root");
|
||||
ApiScenarioModule minModule = getMinModule(tagTree, parentModuleList, null, pidChildrenMap, map, idPathMap, idModuleMap);
|
||||
String id = minModule.getId();
|
||||
datum.setApiScenarioModuleId(id);
|
||||
datum.setModulePath(idPathMap.get(id));
|
||||
|
@ -633,7 +687,7 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD
|
|||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private String[] getTagTree(String modulePath) {
|
||||
|
@ -649,13 +703,15 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD
|
|||
}
|
||||
}
|
||||
|
||||
private ApiScenarioModule getMinModule(String[] tagTree, List<ApiScenarioModule> moduleList, ApiScenarioModule parentModule, Map<String, List<ApiScenarioModule>> pidChildrenMap, Map<String, ApiScenarioModule> map, Map<String, String> idPathMap, Map<String, ApiScenarioModuleDTO> idModuleMap) {
|
||||
private ApiScenarioModule getMinModule(String[] tagTree, List<ApiScenarioModule> parentModuleList, ApiScenarioModule parentModule, Map<String, List<ApiScenarioModule>> pidChildrenMap, Map<String, ApiScenarioModule> map, Map<String, String> idPathMap, Map<String, ApiScenarioModuleDTO> idModuleMap) {
|
||||
//如果parentModule==null 则证明需要创建根目录同级的模块
|
||||
ApiScenarioModule returnModule = null;
|
||||
for (int i = 0; i < tagTree.length; i++) {
|
||||
int finalI = i;
|
||||
List<ApiScenarioModule> collect = moduleList.stream().filter(t -> t.getName().equals(tagTree[finalI])).collect(Collectors.toList());
|
||||
//查找上一级里面是否有当前全路径的第一级,没有则需要创建
|
||||
List<ApiScenarioModule> collect = parentModuleList.stream().filter(t -> t.getName().equals(tagTree[finalI])).collect(Collectors.toList());
|
||||
if (collect.isEmpty()) {
|
||||
//如果找不到,而且父级模块也为空,证明当前的父级模块应为root
|
||||
if (parentModule == null) {
|
||||
List<ApiScenarioModule> moduleList1 = pidChildrenMap.get("root");
|
||||
ApiScenarioModule apiModule = moduleList1.get(0);
|
||||
|
@ -663,16 +719,18 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD
|
|||
apiModule.setLevel(0);
|
||||
parentModule = apiModule;
|
||||
} else if (i > 0) {
|
||||
if (!moduleList.isEmpty()) {
|
||||
String parentId = moduleList.get(0).getParentId();
|
||||
//如果已经循环第二次级以上,如果父模块不为空, parentModuleList不为空,tagTree[finalI] 找不到,那就从上一级开始创建
|
||||
if (!parentModuleList.isEmpty()) {
|
||||
String parentId = parentModuleList.get(0).getParentId();
|
||||
ApiScenarioModuleDTO apiScenarioModuleDTO = idModuleMap.get(parentId);
|
||||
parentModule = JSON.parseObject(JSON.toJSONString(apiScenarioModuleDTO), ApiScenarioModule.class);
|
||||
}
|
||||
}
|
||||
//开始创建tagTree[finalI]这个模块
|
||||
return createModule(tagTree, i, parentModule, map, pidChildrenMap, idPathMap);
|
||||
} else {
|
||||
returnModule = collect.get(0);
|
||||
moduleList = pidChildrenMap.get(collect.get(0).getId());
|
||||
parentModuleList = pidChildrenMap.get(collect.get(0).getId());
|
||||
}
|
||||
}
|
||||
return returnModule;
|
||||
|
@ -684,6 +742,8 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD
|
|||
ApiScenarioModule returnModule = null;
|
||||
for (int i1 = i; i1 < tagTree.length; i1++) {
|
||||
String pathName = tagTree[i1];
|
||||
|
||||
//创建模块
|
||||
ApiScenarioModule newModule = this.getNewModule(pathName, parentModule.getProjectId(), parentModule.getLevel() + 1);
|
||||
String parentId;
|
||||
if (parentModule.getId().equals("root")) {
|
||||
|
@ -718,20 +778,22 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD
|
|||
return returnModule;
|
||||
}
|
||||
|
||||
private void buildProcessData(List<ApiScenarioModuleDTO> nodeTreeByProjectId, Map<String, List<ApiScenarioModule>> pidChildrenMap, Map<String, String> idPathMap) {
|
||||
private void buildProcessData(List<ApiScenarioModuleDTO> nodeTreeByProjectId, Map<String, List<ApiScenarioModule>> pidChildrenMap, Map<String, String> idPathMap, Map<String, String> parentModulePathMap) {
|
||||
List<ApiScenarioModuleDTO> childrenList = new ArrayList<>();
|
||||
int i = 0;
|
||||
List<ApiScenarioModule> moduleList = new ArrayList<>();
|
||||
for (ApiScenarioModuleDTO scenarioModuleDTO : nodeTreeByProjectId) {
|
||||
if (scenarioModuleDTO.getPath() != null) {
|
||||
scenarioModuleDTO.setPath(scenarioModuleDTO.getPath() + "/" + scenarioModuleDTO.getName());
|
||||
if (StringUtils.isBlank(scenarioModuleDTO.getParentId())) {
|
||||
scenarioModuleDTO.setParentId("root");
|
||||
}
|
||||
String parentModulePath = parentModulePathMap.get(scenarioModuleDTO.getParentId());
|
||||
if (parentModulePath != null) {
|
||||
scenarioModuleDTO.setPath(parentModulePath + "/" + scenarioModuleDTO.getName());
|
||||
} else {
|
||||
scenarioModuleDTO.setPath("/" + scenarioModuleDTO.getName());
|
||||
}
|
||||
idPathMap.put(scenarioModuleDTO.getId(), scenarioModuleDTO.getPath());
|
||||
if (StringUtils.isBlank(scenarioModuleDTO.getParentId())) {
|
||||
scenarioModuleDTO.setParentId("root");
|
||||
}
|
||||
|
||||
ApiScenarioModule scenarioModule = buildModule(moduleList, scenarioModuleDTO);
|
||||
if (pidChildrenMap.get(scenarioModuleDTO.getParentId()) != null) {
|
||||
pidChildrenMap.get(scenarioModuleDTO.getParentId()).add(scenarioModule);
|
||||
|
@ -747,9 +809,10 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD
|
|||
pidChildrenMap.put(scenarioModuleDTO.getId(), new ArrayList<>());
|
||||
}
|
||||
}
|
||||
parentModulePathMap.put(scenarioModuleDTO.getId(), scenarioModuleDTO.getPath());
|
||||
}
|
||||
if (i == nodeTreeByProjectId.size() && nodeTreeByProjectId.size() > 0) {
|
||||
buildProcessData(childrenList, pidChildrenMap, idPathMap);
|
||||
buildProcessData(childrenList, pidChildrenMap, idPathMap, parentModulePathMap);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -93,9 +93,9 @@ public interface ExtApiDefinitionMapper {
|
|||
|
||||
int toBeUpdateApi(@Param("ids") List<String> ids, @Param("toBeUpdate") Boolean toBeUpdate);
|
||||
|
||||
List<ApiDefinitionWithBLOBs> selectRepeatByBLOBs(@Param("blobs") List<ApiDefinitionWithBLOBs> blobs);
|
||||
List<ApiDefinitionWithBLOBs> selectRepeatByBLOBs(@Param("blobs") List<ApiDefinitionWithBLOBs> blobs, @Param("projectId") String projectId, @Param("versionId") String versionId);
|
||||
|
||||
List<ApiDefinitionWithBLOBs> selectRepeatByBLOBsSameUrl(@Param("blobs") List<ApiDefinitionWithBLOBs> blobs, @Param("moduleId") String moduleId);
|
||||
List<ApiDefinitionWithBLOBs> selectRepeatByBLOBsSameUrl(@Param("blobs") List<ApiDefinitionWithBLOBs> blobs, @Param("projectId") String projectId, @Param("moduleId") String moduleId, @Param("versionId") String versionId);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1010,13 +1010,17 @@
|
|||
<select id="selectRepeatByBLOBs" resultType="io.metersphere.base.domain.ApiDefinitionWithBLOBs">
|
||||
SELECT * from api_definition
|
||||
<include refid="Same_Where_Clause"/>
|
||||
and status != 'TRASH'
|
||||
and status != 'Trash'
|
||||
and project_id = #{projectId}
|
||||
and version_id = #{versionId}
|
||||
</select>
|
||||
<select id="selectRepeatByBLOBsSameUrl" resultType="io.metersphere.base.domain.ApiDefinitionWithBLOBs">
|
||||
SELECT * from api_definition
|
||||
<include refid="Same_Where_Clause"/>
|
||||
and status != 'TRASH'
|
||||
and project_id = #{projectId}
|
||||
and module_id = #{moduleId}
|
||||
and version_id = #{versionId}
|
||||
</select>
|
||||
<sql id="Same_Where_Clause">
|
||||
<where>
|
||||
|
@ -1030,11 +1034,7 @@
|
|||
<if test="blob.path">
|
||||
and api_definition.path = #{blob.path}
|
||||
</if>
|
||||
<if test="blob.projectId">
|
||||
and api_definition.project_id = #{blob.projectId}
|
||||
</if>
|
||||
</trim>
|
||||
|
||||
</foreach>
|
||||
</trim>
|
||||
</if>
|
||||
|
|
|
@ -91,9 +91,9 @@ public interface ExtApiScenarioMapper {
|
|||
|
||||
List<ApiScenarioWithBLOBs> selectByStatusIsNotTrash();
|
||||
|
||||
List<ApiScenarioWithBLOBs> selectRepeatByBLOBs(@Param("blobs") List<ApiScenarioWithBLOBs> blobs);
|
||||
List<ApiScenarioWithBLOBs> selectRepeatByBLOBs(@Param("blobs") List<ApiScenarioWithBLOBs> blobs, @Param("projectId") String projectId, @Param("versionId") String versionId);
|
||||
|
||||
List<ApiScenarioWithBLOBs> selectRepeatByBLOBsSameUrl(@Param("blobs") List<ApiScenarioWithBLOBs> blobs, @Param("moduleId") String moduleId);
|
||||
List<ApiScenarioWithBLOBs> selectRepeatByBLOBsSameUrl(@Param("blobs") List<ApiScenarioWithBLOBs> blobs, @Param("projectId") String projectId, @Param("moduleId") String moduleId, @Param("versionId") String versionId);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -774,7 +774,9 @@
|
|||
<select id="selectRepeatByBLOBs" resultType="io.metersphere.base.domain.ApiScenarioWithBLOBs">
|
||||
SELECT * from api_scenario
|
||||
<include refid="Same_Where_Clause"/>
|
||||
and status != 'TRASH'
|
||||
and status != 'Trash'
|
||||
and project_id = #{projectId}
|
||||
and version_id = #{versionId}
|
||||
</select>
|
||||
|
||||
<select id="selectRepeatByBLOBsSameUrl" resultType="io.metersphere.base.domain.ApiScenarioWithBLOBs">
|
||||
|
@ -782,6 +784,8 @@
|
|||
<include refid="Same_Where_Clause"/>
|
||||
and status != 'TRASH'
|
||||
and api_scenario_module_id = #{moduleId}
|
||||
and project_id = #{projectId}
|
||||
and version_id = #{versionId}
|
||||
</select>
|
||||
|
||||
<sql id="Same_Where_Clause">
|
||||
|
@ -793,9 +797,6 @@
|
|||
<if test="blob.name">
|
||||
and api_scenario.name = #{blob.name}
|
||||
</if>
|
||||
<if test="blob.projectId">
|
||||
and api_scenario.project_id = #{blob.projectId}
|
||||
</if>
|
||||
</trim>
|
||||
|
||||
</foreach>
|
||||
|
|
Loading…
Reference in New Issue