diff --git a/api-test/backend/src/main/java/io/metersphere/commons/utils/ApiFileUtil.java b/api-test/backend/src/main/java/io/metersphere/commons/utils/ApiFileUtil.java index ada5354b63..c6e3944511 100644 --- a/api-test/backend/src/main/java/io/metersphere/commons/utils/ApiFileUtil.java +++ b/api-test/backend/src/main/java/io/metersphere/commons/utils/ApiFileUtil.java @@ -120,11 +120,11 @@ public class ApiFileUtil extends FileUtils { temporaryFileUtil = CommonBeanFactory.getBean(TemporaryFileUtil.class); } List fileList = new ArrayList<>(); - formatFilePathForNode(tree, reportId, isLocal, fileList); + formatFilePath(tree, reportId, isLocal, fileList); return fileList; } - private static void formatFilePathForNode(HashTree tree, String reportId, boolean isLocal, List fileList) { + private static void formatFilePath(HashTree tree, String reportId, boolean isLocal, List fileList) { if (tree != null) { if (fileMetadataService == null) { fileMetadataService = CommonBeanFactory.getBean(FileMetadataService.class); @@ -143,7 +143,7 @@ public class ApiFileUtil extends FileUtils { getAttachmentBodyFileByKeystoreConfig(key, fileList); } if (node != null) { - formatFilePathForNode(node, reportId, isLocal, fileList); + formatFilePath(node, reportId, isLocal, fileList); } } } @@ -214,9 +214,6 @@ public class ApiFileUtil extends FileUtils { testElement.setProperty(JmxFileMetadataColumns.REF_FILE_NAME.name(), fileMetadata.getName()); testElement.setProperty(JmxFileMetadataColumns.REF_FILE_UPDATE_TIME.name(), fileMetadata.getUpdateTime()); testElement.setProperty(JmxFileMetadataColumns.REF_FILE_PROJECT_ID.name(), fileMetadata.getProjectId()); - if (StringUtils.isNotBlank(fileMetadata.getAttachInfo())) { - testElement.setProperty(JmxFileMetadataColumns.REF_FILE_ATTACH_INFO.name(), fileMetadata.getAttachInfo()); - } } else { path = temporaryFileUtil.generateFilePath(attachmentBodyFile.getProjectId(), attachmentBodyFile.getFileUpdateTime(), attachmentBodyFile.getName()); } diff --git a/api-test/backend/src/main/java/io/metersphere/service/ApiJMeterFileService.java b/api-test/backend/src/main/java/io/metersphere/service/ApiJMeterFileService.java index 24183ab528..a57755ee71 100644 --- a/api-test/backend/src/main/java/io/metersphere/service/ApiJMeterFileService.java +++ b/api-test/backend/src/main/java/io/metersphere/service/ApiJMeterFileService.java @@ -15,6 +15,7 @@ import io.metersphere.commons.constants.ApiRunMode; import io.metersphere.commons.constants.PluginScenario; import io.metersphere.commons.utils.*; import io.metersphere.dto.AttachmentBodyFile; +import io.metersphere.dto.FileInfoDTO; import io.metersphere.dto.JmeterRunRequestDTO; import io.metersphere.dto.ProjectJarConfig; import io.metersphere.environment.service.BaseEnvGroupProjectService; @@ -25,6 +26,7 @@ import io.metersphere.metadata.vo.RemoteFileAttachInfo; import io.metersphere.request.BodyFile; import io.metersphere.utils.JsonUtils; import io.metersphere.utils.LoggerUtil; +import io.metersphere.utils.TemporaryFileUtil; import io.metersphere.vo.BooleanPool; import jakarta.annotation.Resource; import org.apache.commons.collections.CollectionUtils; @@ -297,30 +299,56 @@ public class ApiJMeterFileService { * @return */ public byte[] zipLocalFilesToByteArray(BodyFileRequest request) { + + LogUtil.info("开始下载执行报告为[" + request.getReportId() + "]的文件。"); Map files = new LinkedHashMap<>(); if (CollectionUtils.isNotEmpty(request.getBodyFiles())) { //获取要下载的合法文件 - List bodyFiles = this.getLegalFiles(request); - HashTreeUtil.downFile(bodyFiles, files, fileMetadataService); - for (BodyFile bodyFile : bodyFiles) { - File file = new File(bodyFile.getName()); - if (file.exists() && StringUtils.startsWith(file.getPath(), FileUtils.ROOT_DIR)) { - byte[] fileByte = FileUtils.fileToByte(file); - if (fileByte != null) { - files.put(file.getAbsolutePath(), fileByte); + List legalFiles = this.getLegalFiles(request); + if (CollectionUtils.isNotEmpty(legalFiles)) { + //区分本地文件和文件库文件 + List localFile = new ArrayList<>(); + List remoteFileIdList = new ArrayList<>(); + legalFiles.forEach(file -> { + if (StringUtils.isNotEmpty(file.getRefResourceId())) { + remoteFileIdList.add(file.getRefResourceId()); + } else { + localFile.add(file); } + }); + + //下载本地文件 + if (CollectionUtils.isNotEmpty(localFile)) { + HashTreeUtil.downFile(localFile, files, fileMetadataService); + } + //下载文件库文件 + if (CollectionUtils.isNotEmpty(remoteFileIdList)) { + LogUtil.info("开始下载执行报告为[" + request.getReportId() + "]的文件库文件。"); + List gitFileList = fileMetadataService.downloadApiExecuteFilesByIds(remoteFileIdList); + gitFileList.forEach(fileInfoDTO -> + files.put(StringUtils.join( + fileInfoDTO.getProjectId(), + File.separator, + fileInfoDTO.getFileLastUpdateTime(), + File.separator, + fileInfoDTO.getFileName() + ), fileInfoDTO.getFileByte())); + LogUtil.info("下载到执行报告为[" + request.getReportId() + "]的文件库文件。共下载到【" + gitFileList.size() + "】个"); } } } + Map zipFiles = new LinkedHashMap<>(); for (Map.Entry entry : files.entrySet()) { - //去除文件路径前的body路径 String filePath = entry.getKey(); - if (StringUtils.startsWith(filePath, FileUtils.BODY_FILE_DIR + "/")) { + if (StringUtils.startsWith(filePath, FileUtils.BODY_FILE_DIR + File.separator)) { + //如果路径是以bodyFileDir开头的旧文件,需要去除文件路径前的body路径,并放入默认文件夹中。这样可以直接在/node根目录解压,不用再区分是git文件还是local文件。 filePath = StringUtils.substring(filePath, FileUtils.BODY_FILE_DIR.length() + 1); + filePath = TemporaryFileUtil.DEFAULT_FILE_FOLDER + File.separator + filePath; } zipFiles.put(filePath, entry.getValue()); } + LogUtil.info("下载执行报告为[" + request.getReportId() + "]的文件结束。"); return listBytesToZip(zipFiles); } diff --git a/framework/sdk-parent/jmeter/src/main/java/io/metersphere/enums/JmxFileMetadataColumns.java b/framework/sdk-parent/jmeter/src/main/java/io/metersphere/enums/JmxFileMetadataColumns.java index 5b6f0e6080..c2640c78e4 100644 --- a/framework/sdk-parent/jmeter/src/main/java/io/metersphere/enums/JmxFileMetadataColumns.java +++ b/framework/sdk-parent/jmeter/src/main/java/io/metersphere/enums/JmxFileMetadataColumns.java @@ -4,7 +4,6 @@ public enum JmxFileMetadataColumns { REF_FILE_STORAGE, REF_FILE_UPDATE_TIME, REF_FILE_PROJECT_ID, - REF_FILE_ATTACH_INFO, REF_FILE_NAME, JAR_PATH_CONFIG, } diff --git a/framework/sdk-parent/jmeter/src/main/java/io/metersphere/utils/TemporaryFileUtil.java b/framework/sdk-parent/jmeter/src/main/java/io/metersphere/utils/TemporaryFileUtil.java index 9dcc5a0f81..a6f8d5f42f 100644 --- a/framework/sdk-parent/jmeter/src/main/java/io/metersphere/utils/TemporaryFileUtil.java +++ b/framework/sdk-parent/jmeter/src/main/java/io/metersphere/utils/TemporaryFileUtil.java @@ -27,16 +27,20 @@ public class TemporaryFileUtil { + File.separator; } - public String generateFileDir(String folder) { + public String generateFileDir(String folder, long updateTime) { if (StringUtils.isBlank(folder)) { folder = DEFAULT_FILE_FOLDER; } - return fileFolder + folder + File.separator; + if (updateTime == 0) { + return fileFolder + folder + File.separator; + } else { + return fileFolder + folder + File.separator + updateTime + File.separator; + } + } public String generateFilePath(String folder, long updateTime, String fileName) { - String finalFileName = updateTime > 0 ? updateTime + "_" + fileName : fileName; - return generateFileDir(folder) + finalFileName; + return generateFileDir(folder, updateTime) + fileName; } public File getFile(String folder, long updateTime, String fileName) { @@ -50,7 +54,7 @@ public class TemporaryFileUtil { public void saveFile(String folder, long updateTime, String fileName, byte[] fileBytes) { //删除过期文件 - deleteOldFile(folder, fileName); + deleteOldFile(folder, updateTime, fileName); this.createFile(generateFilePath(folder, updateTime, fileName), fileBytes); } @@ -58,27 +62,49 @@ public class TemporaryFileUtil { if (fileBytes != null && StringUtils.isNotBlank(folder) && updateTime > 0 && StringUtils.isNotBlank(fileName) && fileBytes.length > 0) { //删除过期文件 - deleteOldFile(folder, fileName); + deleteOldFile(folder, updateTime, fileName); this.createFile(generateFilePath(folder, updateTime, fileName), fileBytes); } } - private void deleteOldFile(String folder, String deleteFileName) { - List deleteFileList = new ArrayList<>(); - File file = new File(generateFileDir(folder)); - if (file.exists() && file.isDirectory()) { - String[] fileNameArr = file.list(); - if (fileNameArr != null) { - for (String fileName : fileNameArr) { - if (fileName.endsWith("_" + deleteFileName)) { - deleteFileList.add(fileName); + //node也调用了该方法 + public void deleteOldFile(String folder, long lastUpdateTime, String deleteFileName) { + String newFileFolderName = String.valueOf(lastUpdateTime); + List deleteFileList = new ArrayList<>(); + File file = new File(generateFileDir(folder, 0)); + //当前目录下存放的是以时间戳命名的文件夹,文件夹里存放着具体的文件。所以要删除这个 + if (file.isDirectory()) { + File[] checkFileFolders = file.listFiles(); + if (checkFileFolders != null) { + for (File checkFileFolder : checkFileFolders) { + if (checkFileFolder.isDirectory()) { + File[] checkFiles = checkFileFolder.listFiles(); + if (checkFiles != null) { + for (File checkFile : checkFiles) { + if (StringUtils.equals(checkFile.getName(), deleteFileName) + && !StringUtils.equals(checkFileFolder.getName(), newFileFolderName)) { + //文件名称相同,但是所属的时间戳文件夹与本次不相同的文件,是过期文件。 + deleteFileList.add(checkFile); + } + } + } } } } } - deleteFileList.forEach(fileName -> this.deleteFile(generateFileDir(folder) + fileName)); + + deleteFileList.forEach(deleteFile -> { + if (deleteFile.exists()) { + deleteFile.delete(); + } + File deleteFileFolder = deleteFile.getParentFile(); + if (deleteFileFolder.isDirectory() && deleteFileFolder.listFiles().length == 0) { + deleteFileFolder.delete(); + } + }); } + //勿删。 这段代码在node中会用到。 public byte[] fileToByte(File tradeFile) { byte[] buffer = null; try (FileInputStream fis = new FileInputStream(tradeFile); @@ -98,7 +124,7 @@ public class TemporaryFileUtil { private void createFile(String filePath, byte[] fileBytes) { File file = new File(filePath); if (file.exists()) { - this.deleteFile(filePath); + file.delete(); } try { File dir = file.getParentFile(); @@ -120,11 +146,4 @@ public class TemporaryFileUtil { LoggerUtil.error(e); } } - - public void deleteFile(String path) { - File file = new File(path); - if (file.exists()) { - file.delete(); - } - } } diff --git a/framework/sdk-parent/sdk/src/main/java/io/metersphere/metadata/service/FileMetadataService.java b/framework/sdk-parent/sdk/src/main/java/io/metersphere/metadata/service/FileMetadataService.java index 8e01d483fc..76124402d6 100644 --- a/framework/sdk-parent/sdk/src/main/java/io/metersphere/metadata/service/FileMetadataService.java +++ b/framework/sdk-parent/sdk/src/main/java/io/metersphere/metadata/service/FileMetadataService.java @@ -680,4 +680,13 @@ public class FileMetadataService { return newMetadata; } + public List getFileMetadataByIdList(List fileMetadataIdList) { + if (CollectionUtils.isNotEmpty(fileMetadataIdList)) { + FileMetadataExample example = new FileMetadataExample(); + example.createCriteria().andIdIn(fileMetadataIdList); + return fileMetadataMapper.selectByExampleWithBLOBs(example); + } else { + return new ArrayList<>(); + } + } }