diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/constants/DefaultRepositoryDir.java b/backend/framework/sdk/src/main/java/io/metersphere/sdk/constants/DefaultRepositoryDir.java new file mode 100644 index 0000000000..32b34bf5ae --- /dev/null +++ b/backend/framework/sdk/src/main/java/io/metersphere/sdk/constants/DefaultRepositoryDir.java @@ -0,0 +1,67 @@ +package io.metersphere.sdk.constants; + +/** + * @Author: jianxing + * @CreateTime: 2023-11-17 14:04 + */ +public class DefaultRepositoryDir { + /** + * 系统级别资源的根目录 + */ + private static final String SYSTEM_ROOT_DIR = "system"; + /** + * 组织级别资源的项目目录 + * organization/{organizationId} + */ + private static final String ORGANIZATION_DIR = "organization/%s"; + /** + * 项目级别资源的项目目录 + * project/{projectId} + */ + private static final String PROJECT_DIR = "project/%s"; + + /*------ start: 系统下资源目录 ------*/ + + /** + * 插件存储目录 + */ + private static final String SYSTEM_PLUGIN_DIR = SYSTEM_ROOT_DIR + "/plugin"; + + /*------ end: 系统下资源目录 --------*/ + + + + /*------ start: 项目下资源目录 --------*/ + + /** + * 接口用例相关文件的存储目录 + * project/{projectId}/apiCase/{apiCaseId} + */ + private static final String PROJECT_API_CASE_DIR = PROJECT_DIR + "/apiCase/%s"; + private static final String PROJECT_FUNCTIONAL_CASE_DIR = PROJECT_DIR + "/functionalCase/%s"; + private static final String PROJECT_FILE_MANAGEMENT_DIR = PROJECT_DIR + "/fileManagement"; + private static final String PROJECT_BUG_DIR = PROJECT_DIR + "/bug/%s"; + + /*------ end: 项目下资源目录 --------*/ + + + public static String getApiCaseDir(String projectId, String apiCaseId) { + return String.format(PROJECT_API_CASE_DIR, projectId, apiCaseId); + } + + public static String getPluginDir() { + return SYSTEM_PLUGIN_DIR; + } + + public static String getFunctionalCaseDir(String projectId, String functionalCaseId) { + return String.format(PROJECT_FUNCTIONAL_CASE_DIR, projectId, functionalCaseId); + } + + public static String getFileManagementDir(String projectId) { + return String.format(PROJECT_FILE_MANAGEMENT_DIR, projectId); + } + + public static String getBugDir(String projectId, String bugId) { + return String.format(PROJECT_BUG_DIR, projectId, bugId); + } +} diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/constants/LocalRepositoryDir.java b/backend/framework/sdk/src/main/java/io/metersphere/sdk/constants/LocalRepositoryDir.java new file mode 100644 index 0000000000..f0fad86fda --- /dev/null +++ b/backend/framework/sdk/src/main/java/io/metersphere/sdk/constants/LocalRepositoryDir.java @@ -0,0 +1,42 @@ +package io.metersphere.sdk.constants; + +/** + * @Author: jianxing + * @CreateTime: 2023-11-17 13:54 + */ +public class LocalRepositoryDir { + /** + * 本地存储文件的根目录 + */ + private static final String ROOT_DIR = "/opt/metersphere/data/app"; + /** + * 系统级别资源的根目录 + */ + private static final String SYSTEM_ROOT_DIR = ROOT_DIR + "/" + "system"; + /** + * 组织级别资源的项目目录 + * organization/{organizationId} + */ + private static final String ORGANIZATION_DIR = ROOT_DIR + "/organization/%s"; + /** + * 项目级别资源的项目目录 + * project/{projectId} + */ + private static final String PROJECT_DIR = ROOT_DIR + "/project/%s"; + + /*------ start: 系统下资源目录 ------*/ + /** + * 插件存储目录 + */ + private static final String SYSTEM_PLUGIN_DIR = SYSTEM_ROOT_DIR + "/plugin"; + private static final String SYSTEM_BODY_ENVIRONMENT_TEM_DIR = SYSTEM_ROOT_DIR + "/body/environment/tmp"; + /*------ end: 系统下资源目录 --------*/ + + public static String getPluginDir() { + return SYSTEM_PLUGIN_DIR; + } + + public static String getBodyEnvironmentTmpDir() { + return SYSTEM_BODY_ENVIRONMENT_TEM_DIR; + } +} diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/util/MsFileUtils.java b/backend/framework/sdk/src/main/java/io/metersphere/sdk/util/MsFileUtils.java index d1a74fd75b..b76ee893d2 100644 --- a/backend/framework/sdk/src/main/java/io/metersphere/sdk/util/MsFileUtils.java +++ b/backend/framework/sdk/src/main/java/io/metersphere/sdk/util/MsFileUtils.java @@ -6,13 +6,6 @@ import org.apache.commons.lang3.StringUtils; import java.io.File; public class MsFileUtils { - - public static final String DATA_ROOT_DIR = "/opt/metersphere/data/app"; - public static final String PLUGIN_DIR_NAME = "plugins"; - public static final String PLUGIN_DIR = DATA_ROOT_DIR + "/" + PLUGIN_DIR_NAME; - public static final String FUNCTIONAL_CASE_DIR_NAME = "functionalCase"; - public static final String BUG_MANAGEMENT_DIR = "bug"; - public static void validateFileName(String... fileNames) { if (fileNames != null) { for (String fileName : fileNames) { diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiTestCaseService.java b/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiTestCaseService.java index cd4588bbd9..1a1f527c7b 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiTestCaseService.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiTestCaseService.java @@ -11,6 +11,7 @@ import io.metersphere.plugin.api.spi.AbstractMsTestElement; import io.metersphere.project.domain.Project; import io.metersphere.project.mapper.ProjectMapper; import io.metersphere.sdk.constants.ApplicationNumScope; +import io.metersphere.sdk.constants.DefaultRepositoryDir; import io.metersphere.sdk.constants.StorageType; import io.metersphere.sdk.domain.Environment; import io.metersphere.sdk.domain.EnvironmentExample; @@ -42,9 +43,6 @@ public class ApiTestCaseService { public static final Long ORDER_STEP = 5000L; - - private static final String MAIN_FOLDER_PROJECT = "project"; - private static final String APP_NAME_API_CASE = "apiCase"; @Resource private ApiTestCaseMapper apiTestCaseMapper; @Resource @@ -135,8 +133,7 @@ public class ApiTestCaseService { files.forEach(file -> { FileRequest fileRequest = new FileRequest(); fileRequest.setFileName(file.getName()); - fileRequest.setFolder(minioPath(projectId)); - fileRequest.setResourceId(caseId); + fileRequest.setFolder(DefaultRepositoryDir.getApiCaseDir(projectId, caseId)); fileRequest.setStorage(StorageType.MINIO.name()); try { minioRepository.saveFile(file, fileRequest); @@ -226,8 +223,7 @@ public class ApiTestCaseService { apiTestCaseFollowerMapper.deleteByExample(example); try { FileRequest request = new FileRequest(); - request.setFolder(minioPath(apiCase.getProjectId())); - request.setResourceId(id); + request.setFolder(DefaultRepositoryDir.getApiCaseDir(apiCase.getProjectId(), id)); minioRepository.deleteFolder(request); } catch (Exception e) { LogUtils.info("删除body文件失败: 文件名称:" + id, e); @@ -294,8 +290,4 @@ public class ApiTestCaseService { }); } } - - private String minioPath(String projectId) { - return StringUtils.join(MAIN_FOLDER_PROJECT, "/", projectId, "/", APP_NAME_API_CASE); - } } diff --git a/backend/services/bug-management/src/main/java/io/metersphere/bug/service/BugService.java b/backend/services/bug-management/src/main/java/io/metersphere/bug/service/BugService.java index 8b071205c9..b7d8fab13b 100644 --- a/backend/services/bug-management/src/main/java/io/metersphere/bug/service/BugService.java +++ b/backend/services/bug-management/src/main/java/io/metersphere/bug/service/BugService.java @@ -16,10 +16,7 @@ import io.metersphere.project.dto.filemanagement.FileLogRecord; import io.metersphere.project.service.FileAssociationService; import io.metersphere.project.service.FileService; import io.metersphere.project.service.ProjectTemplateService; -import io.metersphere.sdk.constants.ApplicationNumScope; -import io.metersphere.sdk.constants.HttpMethodConstants; -import io.metersphere.sdk.constants.StorageType; -import io.metersphere.sdk.constants.TemplateScene; +import io.metersphere.sdk.constants.*; import io.metersphere.sdk.exception.MSException; import io.metersphere.sdk.util.BeanUtils; import io.metersphere.sdk.util.FileAssociationSourceUtil; @@ -93,8 +90,6 @@ public class BugService { public static final String ADD_BUG_FILE_LOG_URL = "/bug/add"; public static final String UPDATE_BUG_FILE_LOG_URL = "/bug/update"; - public static final String UPLOAD_SOURCE_DIR = "/project"; - public static final String UPLOAD_APP_DIR = "/bug"; /** * 缺陷列表查询 @@ -644,9 +639,7 @@ public class BugService { private FileRequest buildBugFileRequest(String projectId, String resourceId, String fileName) { FileRequest fileRequest = new FileRequest(); - fileRequest.setFolder(UPLOAD_SOURCE_DIR + "/" + projectId + UPLOAD_APP_DIR + "/" + resourceId); - fileRequest.setProjectId(projectId); - fileRequest.setResourceId(resourceId); + fileRequest.setFolder(DefaultRepositoryDir.getBugDir(projectId, resourceId)); fileRequest.setFileName(StringUtils.isEmpty(fileName) ? null : fileName); fileRequest.setStorage(StorageType.MINIO.name()); return fileRequest; diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/service/DeleteFunctionalCaseService.java b/backend/services/case-management/src/main/java/io/metersphere/functional/service/DeleteFunctionalCaseService.java index 670972e6b4..3bcc721547 100644 --- a/backend/services/case-management/src/main/java/io/metersphere/functional/service/DeleteFunctionalCaseService.java +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/service/DeleteFunctionalCaseService.java @@ -18,8 +18,6 @@ public class DeleteFunctionalCaseService { @Resource private FunctionalCaseTestMapper functionalCaseTestMapper; @Resource - private FunctionalCaseAttachmentService functionalCaseAttachmentService; - @Resource private FunctionalCaseCustomFieldMapper functionalCaseCustomFieldMapper; @Resource private FunctionalCaseBlobMapper functionalCaseBlobMapper; @@ -39,8 +37,7 @@ public class DeleteFunctionalCaseService { FunctionalCaseCommentExample functionalCaseCommentExample = new FunctionalCaseCommentExample(); functionalCaseCommentExample.createCriteria().andCaseIdIn(ids); functionalCaseCommentMapper.deleteByExample(functionalCaseCommentExample); - //9.附件 - functionalCaseAttachmentService.deleteAttachmentResource(ids, projectId); + //9.附件 todo 删除关联关系 //10.自定义字段 FunctionalCaseCustomFieldExample fieldExample = new FunctionalCaseCustomFieldExample(); fieldExample.createCriteria().andCaseIdIn(ids); diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseAttachmentService.java b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseAttachmentService.java index 354cd7eef4..081ba08ee2 100644 --- a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseAttachmentService.java +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseAttachmentService.java @@ -10,10 +10,10 @@ import io.metersphere.functional.mapper.FunctionalCaseAttachmentMapper; import io.metersphere.functional.request.FunctionalCaseAddRequest; import io.metersphere.project.domain.FileMetadata; import io.metersphere.project.mapper.FileMetadataMapper; +import io.metersphere.sdk.constants.DefaultRepositoryDir; import io.metersphere.sdk.constants.StorageType; import io.metersphere.sdk.exception.MSException; import io.metersphere.sdk.util.BeanUtils; -import io.metersphere.sdk.util.MsFileUtils; import io.metersphere.system.file.FileRequest; import io.metersphere.system.file.MinioRepository; import io.metersphere.system.uid.IDGenerator; @@ -52,8 +52,6 @@ public class FunctionalCaseAttachmentService { @Resource private MinioRepository minioRepository; - public static final String UPLOAD_SOURCE_DIR = "/project"; - /** * 保存本地上传文件和用例关联关系 * @@ -81,7 +79,7 @@ public class FunctionalCaseAttachmentService { String fileId = IDGenerator.nextStr(); FileRequest fileRequest = new FileRequest(); fileRequest.setFileName(file.getName()); - fileRequest.setResourceId(UPLOAD_SOURCE_DIR + "/" + request.getProjectId() + "/" + MsFileUtils.FUNCTIONAL_CASE_DIR_NAME + "/" + fileId); + fileRequest.setFolder(DefaultRepositoryDir.getFunctionalCaseDir(request.getProjectId(), caseId) + "/" + fileId); fileRequest.setStorage(StorageType.MINIO.name()); try { minioRepository.saveFile(file, fileRequest); @@ -167,16 +165,16 @@ public class FunctionalCaseAttachmentService { example.clear(); example.createCriteria().andFileIdIn(deleteFileMetaIds).andCaseIdEqualTo(caseId); functionalCaseAttachmentMapper.deleteByExample(example); - this.deleteMinioFile(delAttachment, projectId); + this.deleteMinioFile(delAttachment, projectId, caseId); } - private void deleteMinioFile(List files, String projectId) { + private void deleteMinioFile(List files, String caseId, String projectId) { if (CollectionUtils.isNotEmpty(files)) { files.forEach(file -> { FileRequest fileRequest = new FileRequest(); fileRequest.setFileName(file.getFileName()); - fileRequest.setResourceId(UPLOAD_SOURCE_DIR + "/" + projectId + "/" + MsFileUtils.FUNCTIONAL_CASE_DIR_NAME + "/" + file.getFileId()); + fileRequest.setFolder(DefaultRepositoryDir.getFunctionalCaseDir(projectId, caseId) + "/" + file.getFileId()); fileRequest.setStorage(StorageType.MINIO.name()); try { minioRepository.delete(fileRequest); @@ -187,23 +185,6 @@ public class FunctionalCaseAttachmentService { } } - - /** - * 清理附件资源 - * - * @param ids - */ - public void deleteAttachmentResource(List ids, String projectId) { - FunctionalCaseAttachmentExample example = new FunctionalCaseAttachmentExample(); - example.createCriteria().andCaseIdIn(ids).andLocalEqualTo(true); - List localAttachment = functionalCaseAttachmentMapper.selectByExample(example); - example.clear(); - example.createCriteria().andCaseIdIn(ids); - functionalCaseAttachmentMapper.deleteByExample(example); - deleteMinioFile(localAttachment, projectId); - } - - /** * 通过caseId获取附件信息 * diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/service/CommandService.java b/backend/services/project-management/src/main/java/io/metersphere/project/service/CommandService.java index 5732a15dc6..c9af8362ab 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/service/CommandService.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/service/CommandService.java @@ -2,6 +2,7 @@ package io.metersphere.project.service; import io.metersphere.project.dto.environment.ssl.KeyStoreEntry; + import io.metersphere.sdk.constants.LocalRepositoryDir; import io.metersphere.sdk.exception.MSException; import io.metersphere.sdk.util.JSON; import io.metersphere.sdk.util.LogUtils; @@ -24,7 +25,7 @@ public class CommandService { public static String createFile(MultipartFile bodyFile) { MsFileUtils.validateFileName(bodyFile.getOriginalFilename()); - String dir = MsFileUtils.DATA_ROOT_DIR + "/body/environment/tmp"; + String dir = LocalRepositoryDir.getBodyEnvironmentTmpDir(); File fileDir = new File(dir); if (!fileDir.exists()) { fileDir.mkdirs(); diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/service/FileMetadataService.java b/backend/services/project-management/src/main/java/io/metersphere/project/service/FileMetadataService.java index 5c02faa3d4..4a22d74471 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/service/FileMetadataService.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/service/FileMetadataService.java @@ -13,6 +13,7 @@ import io.metersphere.project.mapper.FileMetadataMapper; import io.metersphere.project.mapper.FileMetadataRepositoryMapper; import io.metersphere.project.mapper.FileModuleRepositoryMapper; import io.metersphere.project.utils.FileDownloadUtils; +import io.metersphere.sdk.constants.DefaultRepositoryDir; import io.metersphere.sdk.constants.ModuleConstants; import io.metersphere.sdk.constants.StorageType; import io.metersphere.sdk.exception.MSException; @@ -674,10 +675,7 @@ public class FileMetadataService { return fileVersionResponseList; } - private static final String MAIN_FOLDER_PROJECT = "project"; - private static final String APP_NAME_FILE_MANAGEMENT = "fileManagement"; - private String generateMinIOFilePath(String projectId) { - return StringUtils.join(MAIN_FOLDER_PROJECT, "/", projectId, "/", APP_NAME_FILE_MANAGEMENT); + return DefaultRepositoryDir.getFileManagementDir(projectId); } } \ No newline at end of file diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/file/FileRequest.java b/backend/services/system-setting/src/main/java/io/metersphere/system/file/FileRequest.java index 2974d7c2e3..a0dd1671ac 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/file/FileRequest.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/file/FileRequest.java @@ -10,13 +10,19 @@ public class FileRequest { private String folder; - //项目ID + /** + * @Deprecated 月底移除 + */ + @Deprecated(since="3.x", forRemoval=true) private String projectId; // 存储类型 private String storage; - // 资源id为空时存储在项目目录下 + /** + * @Deprecated 月底移除 + */ + @Deprecated(since="3.x", forRemoval=true) private String resourceId; // 文件名称 diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/file/LocalFileRepository.java b/backend/services/system-setting/src/main/java/io/metersphere/system/file/LocalFileRepository.java index 79eeadaf40..454b990cfd 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/file/LocalFileRepository.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/file/LocalFileRepository.java @@ -16,10 +16,10 @@ public class LocalFileRepository implements FileRepository { @Override public String saveFile(MultipartFile multipartFile, FileRequest request) throws IOException { - if (multipartFile == null || request == null || StringUtils.isEmpty(request.getFileName()) || StringUtils.isEmpty(request.getProjectId())) { + if (multipartFile == null || request == null || StringUtils.isEmpty(request.getFileName()) || StringUtils.isEmpty(request.getFolder())) { return null; } - MsFileUtils.validateFileName(request.getProjectId(), request.getFileName()); + MsFileUtils.validateFileName(request.getFolder(), request.getFileName()); createFileDir(request); File file = new File(getFilePath(request)); FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), file); @@ -62,7 +62,7 @@ public class LocalFileRepository implements FileRepository { @Override public void deleteFolder(FileRequest request) throws Exception { - MsFileUtils.validateFileName(request.getProjectId(), request.getFileName()); + MsFileUtils.validateFileName(request.getFolder(), request.getFileName()); this.delete(request); } @@ -88,12 +88,12 @@ public class LocalFileRepository implements FileRepository { } private String getFilePath(FileRequest request) { - MsFileUtils.validateFileName(request.getProjectId(), request.getFileName()); + MsFileUtils.validateFileName(request.getFolder(), request.getFileName()); return StringUtils.join(getFileDir(request), "/", request.getFileName()); } private String getFileDir(FileRequest request) { - MsFileUtils.validateFileName(request.getProjectId(), request.getFileName()); - return StringUtils.join(MsFileUtils.DATA_ROOT_DIR, "/", request.getProjectId()); + MsFileUtils.validateFileName(request.getFolder(), request.getFileName()); + return request.getFolder(); } } diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/service/PluginLoadService.java b/backend/services/system-setting/src/main/java/io/metersphere/system/service/PluginLoadService.java index a071594e1d..3f2c6067f6 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/service/PluginLoadService.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/service/PluginLoadService.java @@ -1,6 +1,8 @@ package io.metersphere.system.service; import io.metersphere.plugin.sdk.spi.MsPlugin; +import io.metersphere.sdk.constants.DefaultRepositoryDir; +import io.metersphere.sdk.constants.LocalRepositoryDir; import io.metersphere.sdk.constants.StorageType; import io.metersphere.system.controller.handler.result.CommonResultCode; import io.metersphere.sdk.exception.MSException; @@ -56,7 +58,7 @@ public class PluginLoadService { */ public String loadPlugin(String fileName) { MsFileUtils.validateFileName(fileName); - String filePath = MsFileUtils.PLUGIN_DIR + "/" + fileName; + String filePath = LocalRepositoryDir.getPluginDir() + "/" + fileName; File file = new File(filePath); if (!file.exists()) { // 文件不存在,则从对象存储重新下载 @@ -74,11 +76,12 @@ public class PluginLoadService { */ public void loadPluginFromRepository(String fileName) { MsFileUtils.validateFileName(fileName); - String filePath = MsFileUtils.PLUGIN_DIR + "/" + fileName; + String filePath = LocalRepositoryDir.getPluginDir() + "/" + fileName; File file = new File(filePath); try { if (!file.exists()) { - InputStream fileAsStream = FileCenter.getDefaultRepository().getFileAsStream(getFileRequest(fileName)); + InputStream fileAsStream = FileCenter.getDefaultRepository() + .getFileAsStream(getDefaultRepositoryFileRequest(fileName)); FileUtils.copyInputStreamToFile(fileAsStream, file); } msPluginManager.loadPlugin(Paths.get(filePath)); @@ -95,7 +98,8 @@ public class PluginLoadService { */ public String uploadPlugin2Local(MultipartFile file) { try { - return FileCenter.getRepository(StorageType.LOCAL).saveFile(file, getFileRequest(file.getOriginalFilename())); + return FileCenter.getRepository(StorageType.LOCAL) + .saveFile(file, getLocalRepositoryFileRequest(file.getOriginalFilename())); } catch (Exception e) { LogUtils.error(e); throw new MSException("文件上传异常", e); @@ -109,7 +113,8 @@ public class PluginLoadService { */ public void uploadPlugin2Repository(MultipartFile file) { try { - FileCenter.getDefaultRepository().saveFile(file, getFileRequest(file.getOriginalFilename())); + FileCenter.getDefaultRepository() + .saveFile(file, getDefaultRepositoryFileRequest(file.getOriginalFilename())); } catch (Exception e) { LogUtils.error(e); throw new MSException("文件上传异常", e); @@ -123,17 +128,26 @@ public class PluginLoadService { */ public void downloadPluginFromRepository(String fileName) { try { - InputStream inputStream = FileCenter.getDefaultRepository().getFileAsStream(getFileRequest(fileName)); - FileCenter.getRepository(StorageType.LOCAL).saveFile(inputStream, getFileRequest(fileName)); + InputStream inputStream = FileCenter.getDefaultRepository() + .getFileAsStream(getDefaultRepositoryFileRequest(fileName)); + FileCenter.getRepository(StorageType.LOCAL) + .saveFile(inputStream, getLocalRepositoryFileRequest(fileName)); } catch (Exception e) { LogUtils.error(e); throw new MSException("下载插件异常", e); } } - private FileRequest getFileRequest(String name) { + private FileRequest getDefaultRepositoryFileRequest(String name) { FileRequest request = new FileRequest(); - request.setProjectId(MsFileUtils.PLUGIN_DIR_NAME); + request.setFolder(DefaultRepositoryDir.getPluginDir()); + request.setFileName(name); + return request; + } + + private FileRequest getLocalRepositoryFileRequest(String name) { + FileRequest request = new FileRequest(); + request.setFolder(LocalRepositoryDir.getPluginDir()); request.setFileName(name); return request; } @@ -202,10 +216,10 @@ public class PluginLoadService { * 删除插件 */ public void deletePluginFile(String fileName) { - FileRequest fileRequest = getFileRequest(fileName); try { - FileCenter.getRepository(StorageType.LOCAL).delete(fileRequest); - FileCenter.getDefaultRepository().delete(fileRequest); + this.deleteLocalPluginFile(fileName); + FileCenter.getDefaultRepository() + .delete(getDefaultRepositoryFileRequest(fileName)); } catch (Exception e) { LogUtils.error(e); } @@ -216,9 +230,10 @@ public class PluginLoadService { * @param fileName */ public void deleteLocalPluginFile(String fileName) { - FileRequest fileRequest = getFileRequest(fileName); + FileRequest fileRequest = getLocalRepositoryFileRequest(fileName); try { - FileCenter.getRepository(StorageType.LOCAL).delete(fileRequest); + FileCenter.getRepository(StorageType.LOCAL) + .delete(fileRequest); } catch (Exception e) { LogUtils.error(e); } diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/FileCenterTests.java b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/FileCenterTests.java index 6a183f23ae..784e6852da 100644 --- a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/FileCenterTests.java +++ b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/FileCenterTests.java @@ -35,24 +35,25 @@ public class FileCenterTests { "Hello, World!".getBytes() ); // 创建一个FileRequest对象作为测试用的请求参数 - FileRequest request = new FileRequest(); - request.setFileName("test.txt"); - request.setProjectId("test-project"); - request.setResourceId("test-resource-id"); + FileRequest request = getFileRequest(); repository.saveFile(mockFile, request); Assertions.assertTrue(repository.saveFile(mockFile, request) != null); Assertions.assertTrue(repository.saveFile("Hello, World!".getBytes(), request) != null); } + private static FileRequest getFileRequest() { + FileRequest request = new FileRequest(); + request.setFileName("test.txt"); + request.setFolder("test-project/test-resource-id"); + return request; + } + @Test @Order(3) public void testGetFile() throws Exception { // 创建一个FileRequest对象作为测试用的请求参数 - FileRequest request = new FileRequest(); - request.setFileName("test.txt"); - request.setProjectId("test-project"); - request.setResourceId("test-resource-id"); + FileRequest request = getFileRequest(); repository.getFile(request); Assertions.assertTrue(repository.getFile(request) != null); } @@ -61,11 +62,7 @@ public class FileCenterTests { @Order(4) public void testDelFile() throws Exception { // 创建一个FileRequest对象作为测试用的请求参数 - FileRequest request = new FileRequest(); - request.setFileName("test.txt"); - request.setProjectId("test-project"); - request.setResourceId("test-resource-id"); - repository.delete(request); + repository.delete(getFileRequest()); } @Test @@ -80,7 +77,7 @@ public class FileCenterTests { // 创建一个FileRequest对象作为测试用的请求参数 FileRequest request = new FileRequest(); request.setFileName("test.txt"); - request.setProjectId("test-project"); + request.setFolder("test-project"); repository.saveFile(mockFile, request); Assertions.assertTrue(repository.saveFile(mockFile, request) != null); Assertions.assertTrue(repository.saveFile("Hello, World!".getBytes(), request) != null); diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/PluginControllerTests.java b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/PluginControllerTests.java index b957add4ca..66250e6070 100644 --- a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/PluginControllerTests.java +++ b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/PluginControllerTests.java @@ -1,5 +1,6 @@ package io.metersphere.system.controller; +import io.metersphere.plugin.platform.spi.Platform; import io.metersphere.sdk.constants.PermissionConstants; import io.metersphere.sdk.constants.PluginScenarioType; import io.metersphere.sdk.constants.SessionConstants; @@ -11,6 +12,8 @@ import io.metersphere.system.domain.*; import io.metersphere.system.dto.OrganizationDTO; import io.metersphere.system.dto.PluginDTO; import io.metersphere.system.dto.sdk.OptionDTO; +import io.metersphere.system.file.FileRequest; +import io.metersphere.system.file.LocalFileRepository; import io.metersphere.system.log.constants.OperationLogType; import io.metersphere.system.mapper.PluginMapper; import io.metersphere.system.mapper.PluginOrganizationMapper; @@ -27,11 +30,13 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; +import org.springframework.mock.web.MockMultipartFile; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.util.MultiValueMap; import java.io.File; +import java.io.FileInputStream; import java.util.*; import java.util.stream.Collectors; @@ -67,11 +72,13 @@ public class PluginControllerTests extends BaseTest { private JdbcDriverPluginService jdbcDriverPluginService; @Resource private PluginScriptService pluginScriptService; + @Resource + private LocalFileRepository localFileRepository; private static Plugin addPlugin; private static Plugin anotherAddPlugin; @Resource - private PluginService pluginService; + private PluginLoadService pluginLoadService; public static final String PLUGIN_OPTIONS_URL = "/plugin/options"; @Resource private MockServerClient mockServerClient; @@ -128,6 +135,19 @@ public class PluginControllerTests extends BaseTest { Assertions.assertEquals(Arrays.asList("connect", "disconnect", "pub", "sub"), getScriptIdsByPlugId(plugin.getId())); addPlugin = plugin; + // 模拟其他节点加载插件 + pluginLoadService.handlePluginDeleteNotified(plugin.getId(), jarFile.getName()); + pluginLoadService.handlePluginAddNotified(plugin.getId(), jarFile.getName()); + + // 增加覆盖率 + pluginLoadService.handlePluginDeleteNotified(plugin.getId(), jarFile.getName()); + pluginLoadService.loadPlugin(jarFile.getName()); + + pluginLoadService.handlePluginDeleteNotified(plugin.getId(), jarFile.getName()); + pluginLoadService.loadPlugins(); + + pluginLoadService.getExtensions(Platform.class); + // 增加覆盖率 this.requestGetWithOkAndReturn(DEFAULT_LIST); pluginScriptService.add(null, null); @@ -174,6 +194,14 @@ public class PluginControllerTests extends BaseTest { // 清理掉 this.requestGetWithOk(DEFAULT_DELETE, "cloud-quota-plugin"); + + try { + MockMultipartFile mockMultipartFile = + new MockMultipartFile(jarFile.getName(), jarFile.getName(), "jar", new FileInputStream("/d/d")); + pluginLoadService.uploadPlugin2Local(mockMultipartFile); + } catch (Exception e) { + } + // @@重名校验异常 // 校验插件名称重名 assertErrorCode(this.requestMultipart(DEFAULT_ADD, @@ -392,6 +420,22 @@ public class PluginControllerTests extends BaseTest { // 获取返回值 } + @Test + @Order(8) + public void testLocalFileRepository() throws Exception { + // 增加覆盖率 + MockMultipartFile mockMultipartFile = + new MockMultipartFile("test file", "test file", "jar", + new FileInputStream(this.getClass().getClassLoader().getResource("file/my-driver-1.0.jar").getPath())); + localFileRepository.saveFile(mockMultipartFile, null); + try { + localFileRepository.downloadFile(null, null); + } catch (UnsupportedOperationException e) { + } + localFileRepository.getFolderFileNames(new FileRequest()); + } + + private void requestPostTest(String url, Object param) throws Exception { mockMvc.perform(MockMvcRequestBuilders.post(url) .header(SessionConstants.HEADER_TOKEN, sessionId)