refactor(接口测试): 优化接口测试执行时附件管理的相关代码,增加可读性

优化接口测试执行时附件管理的相关代码,增加可读性
This commit is contained in:
song-tianyang 2023-02-16 14:33:30 +08:00 committed by 建国
parent 65e8661f6f
commit 4917bbb89d
4 changed files with 104 additions and 31 deletions

View File

@ -9,7 +9,6 @@ import io.metersphere.api.dto.scenario.environment.EnvironmentConfig;
import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs;
import io.metersphere.base.domain.FileMetadata;
import io.metersphere.commons.constants.ElementConstants;
import io.metersphere.commons.constants.StorageConstants;
import io.metersphere.dto.AttachmentBodyFile;
import io.metersphere.dto.FileInfoDTO;
import io.metersphere.dto.JmeterRunRequestDTO;
@ -243,22 +242,15 @@ public class HashTreeUtil {
if (runRequest.getPool().isPool() || runRequest.getPool().isK8s()) {
return;
}
List<AttachmentBodyFile> downloadFileList = ApiFileUtil.getExecuteFile(runRequest.getHashTree(), runRequest.getReportId(), true);
Map<String, String> repositoryFileMap = new HashMap<>();
for (AttachmentBodyFile bodyFile : downloadFileList) {
if (!StringUtils.equals(bodyFile.getFileStorage(), StorageConstants.LOCAL.name())
&& StringUtils.isNotBlank(bodyFile.getFileMetadataId())) {
repositoryFileMap.put(bodyFile.getFileMetadataId(), bodyFile.getName());
}
}
LoggerUtil.info("本次执行[" + runRequest.getReportId() + "]需要下载[" + repositoryFileMap.size() + "]个文件,开始下载......");
List<AttachmentBodyFile> executeFileList = ApiFileUtil.getExecuteFile(runRequest.getHashTree(), runRequest.getReportId(), true);
LoggerUtil.info("本次执行[" + runRequest.getReportId() + "]共需要[" + executeFileList.size() + "]个文件。");
FileMetadataService fileMetadataService = CommonBeanFactory.getBean(FileMetadataService.class);
if (fileMetadataService != null) {
fileMetadataService.downloadApiExecuteFilesByIds(repositoryFileMap.keySet());
List<AttachmentBodyFile> downloadFileList = fileMetadataService.filterDownloadFileList(executeFileList);
LoggerUtil.info("本次执行[" + runRequest.getReportId() + "]需要下载[" + downloadFileList.size() + "]个文件。开始下载。。。");
fileMetadataService.downloadByAttachmentBodyFileList(downloadFileList);
}
LoggerUtil.info("本次执行[" + runRequest.getReportId() + "]需要下载[" + repositoryFileMap.size() + "]个文件,下载结束。");
LoggerUtil.info("本次执行[" + runRequest.getReportId() + "]需要下载[" + executeFileList.size() + "]个文件,下载结束。");
}
public static void downFile(

View File

@ -1,5 +1,6 @@
package io.metersphere.service;
import groovy.lang.Lazy;
import io.metersphere.api.dto.BodyFileRequest;
import io.metersphere.api.dto.EnvironmentType;
import io.metersphere.api.dto.definition.request.ElementUtil;
@ -62,6 +63,9 @@ public class ApiJMeterFileService {
private PluginMapper pluginMapper;
@Resource
private RedisTemplateService redisTemplateService;
@Lazy
@Resource
private TemporaryFileUtil temporaryFileUtil;
// 接口测试 用例/接口
private static final List<String> CASE_MODES = new ArrayList<>() {{
@ -326,10 +330,9 @@ public class ApiJMeterFileService {
LogUtil.info("开始下载执行报告为[" + request.getReportId() + "]的文件库文件。");
List<FileInfoDTO> gitFileList = fileMetadataService.downloadApiExecuteFilesByIds(remoteFileIdList);
gitFileList.forEach(fileInfoDTO ->
files.put(StringUtils.join(
fileInfoDTO.getProjectId(),
File.separator,
fileInfoDTO.getFileLastUpdateTime(),
files.put(
StringUtils.join(
temporaryFileUtil.generateRelativeDir(fileInfoDTO.getProjectId(), fileInfoDTO.getId(), fileInfoDTO.getFileLastUpdateTime()),
File.separator,
fileInfoDTO.getFileName()
), fileInfoDTO.getFileByte()));

View File

@ -27,22 +27,42 @@ public class TemporaryFileUtil {
+ File.separator;
}
public String generateFileDir(String folder, String fileMetadataId, long updateTime) {
public String generateLocalFileDir() {
return fileFolder + DEFAULT_FILE_FOLDER + File.separator;
}
//生成执行文件的相对路径
public String generateRelativeDir(String folder, String fileMetadataId, long updateTime) {
if (StringUtils.isBlank(folder)) {
folder = DEFAULT_FILE_FOLDER;
}
if (StringUtils.isBlank(fileMetadataId)) {
return fileFolder + folder + File.separator;
return folder + File.separator;
} else {
String metadataIdFolder = fileFolder + folder + File.separator + fileMetadataId + File.separator;
String metadataIdFolder = folder + File.separator + fileMetadataId + File.separator;
return updateTime == 0 ? metadataIdFolder : metadataIdFolder + updateTime + File.separator;
}
}
//生成执行文件的绝对路径
public String generateFileDir(String folder, String fileMetadataId, long updateTime) {
return fileFolder + generateRelativeDir(folder, fileMetadataId, updateTime);
}
public String generateFilePath(String folder, String fileMetadataId, long updateTime, String fileName) {
return generateFileDir(folder, fileMetadataId, updateTime) + fileName;
}
public String generateLocalFilePath(String filePath) {
return generateLocalFileDir() + filePath;
}
//node使用 判断local文件
public File getLocalFile(String filePath) {
File file = new File(this.generateLocalFilePath(filePath));
return file.exists() ? file : null;
}
public File getFile(String folder, String fileMetadataId, long updateTime, String fileName) {
File file = new File(generateFilePath(folder, fileMetadataId, updateTime, fileName));
if (file.exists()) {

View File

@ -1,6 +1,7 @@
package io.metersphere.metadata.service;
import com.alibaba.nacos.common.utils.ByteUtils;
import groovy.lang.Lazy;
import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.FileAssociationMapper;
import io.metersphere.base.mapper.FileContentMapper;
@ -10,7 +11,11 @@ import io.metersphere.commons.constants.ApiTestConstants;
import io.metersphere.commons.constants.FileModuleTypeConstants;
import io.metersphere.commons.constants.StorageConstants;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.*;
import io.metersphere.commons.utils.FileUtils;
import io.metersphere.commons.utils.JSON;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.dto.AttachmentBodyFile;
import io.metersphere.dto.FileInfoDTO;
import io.metersphere.i18n.Translator;
import io.metersphere.log.utils.ReflexObjectUtil;
@ -53,6 +58,8 @@ public class FileMetadataService {
@Resource
private FileAssociationMapper fileAssociationMapper;
@Lazy
@Resource
private TemporaryFileUtil temporaryFileUtil;
public List<FileMetadata> create(FileMetadataCreateRequest fileMetadata, List<MultipartFile> files) {
@ -549,18 +556,31 @@ public class FileMetadataService {
return fileMetadataList.stream().map(FileMetadata::getId).collect(Collectors.toList());
}
public List<AttachmentBodyFile> filterDownloadFileList(List<AttachmentBodyFile> attachmentBodyFileList) {
List<AttachmentBodyFile> downloadFileList = new ArrayList<>();
if (!CollectionUtils.isEmpty(attachmentBodyFileList)) {
//检查是否存在已下载的文件
attachmentBodyFileList.forEach(fileMetadata -> {
if (!StringUtils.equals(fileMetadata.getFileStorage(), StorageConstants.LOCAL.name())) {
File file = temporaryFileUtil.getFile(fileMetadata.getProjectId(), fileMetadata.getFileMetadataId(), fileMetadata.getFileUpdateTime(), fileMetadata.getName());
if (file == null) {
downloadFileList.add(fileMetadata);
LoggerUtil.info("文件【" + fileMetadata.getFileUpdateTime() + "_" + fileMetadata.getName() + "】在执行目录【" + fileMetadata.getProjectId() + "】未找到,需要下载");
}
}
});
}
return downloadFileList;
}
/**
* 接口测试执行时下载附件的方法
* 提供给Node下载附件时的方法
* 该方法会优先判断是否存在已下载好的文件避免多次执行造成多次下载的情况
*
* @param fileIdList
* @param fileIdList 要下载的文件ID集合
* @return
*/
public List<FileInfoDTO> downloadApiExecuteFilesByIds(Collection<String> fileIdList) {
if (temporaryFileUtil == null) {
temporaryFileUtil = CommonBeanFactory.getBean(TemporaryFileUtil.class);
}
List<FileInfoDTO> fileInfoDTOList = new ArrayList<>();
if (CollectionUtils.isEmpty(fileIdList)) {
return fileInfoDTOList;
@ -591,6 +611,23 @@ public class FileMetadataService {
return fileInfoDTOList;
}
public void downloadByAttachmentBodyFileList(List<AttachmentBodyFile> downloadFileList) {
LogUtil.info(JSON.toJSONString(downloadFileList) + " 获取执行文件开始");
List<FileRequest> downloadFileRequest = new ArrayList<>();
downloadFileList.forEach(attachmentBodyFile -> {
FileRequest request = this.genFileRequest(attachmentBodyFile);
downloadFileRequest.add(request);
});
List<FileInfoDTO> repositoryFileDTOList = fileManagerService.downloadFileBatch(downloadFileRequest);
//将文件存储到执行文件目录中避免多次执行时触发多次下载
if (CollectionUtils.isNotEmpty(repositoryFileDTOList)) {
repositoryFileDTOList.forEach(repositoryFile -> temporaryFileUtil.saveFileByParamCheck(repositoryFile.getProjectId(), repositoryFile.getId(), repositoryFile.getFileLastUpdateTime(), repositoryFile.getFileName(), repositoryFile.getFileByte()));
}
LogUtil.info(JSON.toJSONString(downloadFileList) + " 获取执行文件结束");
}
public List<FileInfoDTO> downloadFileByIds(Collection<String> fileIdList) {
if (CollectionUtils.isEmpty(fileIdList)) {
return new ArrayList<>(0);
@ -610,6 +647,27 @@ public class FileMetadataService {
return repositoryFileDTOList;
}
private FileRequest genFileRequest(AttachmentBodyFile attachmentBodyFile) {
if (attachmentBodyFile != null) {
FileRequest request = new FileRequest(attachmentBodyFile.getProjectId(), attachmentBodyFile.getName(), null);
request.setResourceId(attachmentBodyFile.getFileMetadataId());
request.setPath(attachmentBodyFile.getFilePath());
request.setStorage(attachmentBodyFile.getFileStorage());
request.setUpdateTime(attachmentBodyFile.getFileUpdateTime());
if (StringUtils.equals(attachmentBodyFile.getFileStorage(), StorageConstants.GIT.name())) {
try {
RemoteFileAttachInfo gitFileInfo = JSON.parseObject(attachmentBodyFile.getFileAttachInfoJson(), RemoteFileAttachInfo.class);
request.setFileAttachInfo(gitFileInfo);
} catch (Exception e) {
LogUtil.error("解析Git附加信息【" + attachmentBodyFile.getFileAttachInfoJson() + "】失败!", e);
}
}
return request;
} else {
return new FileRequest();
}
}
private FileRequest genFileRequest(FileMetadataWithBLOBs fileMetadata) {
if (fileMetadata != null) {
FileRequest request = new FileRequest(fileMetadata.getProjectId(), fileMetadata.getName(), fileMetadata.getType());