feat(项目设置): 文件库下载文件功能开发
This commit is contained in:
parent
a893e1293d
commit
72f1d1abd1
|
@ -76,7 +76,7 @@ public class FileManagementController {
|
|||
@GetMapping(value = "/download/{id}")
|
||||
@Operation(summary = "项目管理-文件管理-下载文件")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_FILE_MANAGEMENT_READ_DOWNLOAD)
|
||||
public ResponseEntity<byte[]> download(@PathVariable String id) {
|
||||
public ResponseEntity<byte[]> download(@PathVariable String id) throws Exception {
|
||||
return fileMetadataService.downloadById(id);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,32 +28,28 @@ public class FilePreviewController {
|
|||
|
||||
@GetMapping(value = "/original/{userId}/{fileId}")
|
||||
@Operation(summary = "预览原图")
|
||||
public ResponseEntity<byte[]> originalImg(@PathVariable String userId,@PathVariable String fileId) {
|
||||
public ResponseEntity<byte[]> originalImg(@PathVariable String userId, @PathVariable String fileId) throws Exception {
|
||||
FileInformationResponse fileInformationResponse = fileMetadataService.get(fileId);
|
||||
if (StringUtils.isEmpty(fileInformationResponse.getId())) {
|
||||
throw new MSException("file.not.exist");
|
||||
}
|
||||
//检查权限
|
||||
if (permissionCheckService.userHasProjectPermission(userId, fileInformationResponse.getProjectId(), PermissionConstants.PROJECT_FILE_MANAGEMENT_READ_DOWNLOAD)) {
|
||||
return fileMetadataService.downloadById(fileId);
|
||||
}else {
|
||||
if (!permissionCheckService.userHasProjectPermission(userId, fileInformationResponse.getProjectId(), PermissionConstants.PROJECT_FILE_MANAGEMENT_READ_DOWNLOAD)) {
|
||||
throw new MSException("http_result_forbidden");
|
||||
}
|
||||
|
||||
return fileMetadataService.downloadById(fileId);
|
||||
}
|
||||
@GetMapping(value = "/compressed/{userId}/{fileId}")
|
||||
@Operation(summary = "预览缩略图")
|
||||
public ResponseEntity<byte[]> compressedImg(@PathVariable String userId,@PathVariable String fileId) {
|
||||
public ResponseEntity<byte[]> compressedImg(@PathVariable String userId, @PathVariable String fileId) throws Exception {
|
||||
FileInformationResponse fileInformationResponse = fileMetadataService.get(fileId);
|
||||
if (StringUtils.isEmpty(fileInformationResponse.getId())) {
|
||||
throw new MSException("file.not.exist");
|
||||
}
|
||||
//检查权限
|
||||
if (permissionCheckService.userHasProjectPermission(userId, fileInformationResponse.getProjectId(), PermissionConstants.PROJECT_FILE_MANAGEMENT_READ)) {
|
||||
return fileMetadataService.downloadPreviewImgById(fileId);
|
||||
}else {
|
||||
if (!permissionCheckService.userHasProjectPermission(userId, fileInformationResponse.getProjectId(), PermissionConstants.PROJECT_FILE_MANAGEMENT_READ)) {
|
||||
throw new MSException("http_result_forbidden");
|
||||
}
|
||||
|
||||
return fileMetadataService.downloadPreviewImgById(fileId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,6 @@ public class FileRepositoryController {
|
|||
return fileRepositoryService.getTree(projectId);
|
||||
}
|
||||
|
||||
|
||||
@GetMapping(value = "/file-type/{projectId}")
|
||||
@Operation(summary = "项目管理-文件管理-存储库-获取已存在的存储库文件类型")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_FILE_MANAGEMENT_READ)
|
||||
|
|
|
@ -2,11 +2,13 @@ package io.metersphere.project.service;
|
|||
|
||||
import io.metersphere.project.domain.FileMetadata;
|
||||
import io.metersphere.project.domain.FileMetadataExample;
|
||||
import io.metersphere.project.domain.FileMetadataRepositoryExample;
|
||||
import io.metersphere.project.domain.FileModuleExample;
|
||||
import io.metersphere.project.dto.filemanagement.FileManagementQuery;
|
||||
import io.metersphere.project.dto.filemanagement.request.FileBatchProcessRequest;
|
||||
import io.metersphere.project.mapper.ExtFileMetadataMapper;
|
||||
import io.metersphere.project.mapper.FileMetadataMapper;
|
||||
import io.metersphere.project.mapper.FileMetadataRepositoryMapper;
|
||||
import io.metersphere.project.mapper.FileModuleMapper;
|
||||
import io.metersphere.sdk.constants.ModuleConstants;
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
|
@ -28,6 +30,8 @@ public class FileManagementService {
|
|||
@Resource
|
||||
private FileMetadataMapper fileMetadataMapper;
|
||||
@Resource
|
||||
private FileMetadataRepositoryMapper fileMetadataRepositoryMapper;
|
||||
@Resource
|
||||
private FileModuleMapper fileModuleMapper;
|
||||
@Resource
|
||||
private FileService fileService;
|
||||
|
@ -54,6 +58,10 @@ public class FileManagementService {
|
|||
example.createCriteria().andIdIn(deleteIds);
|
||||
fileMetadataMapper.deleteByExample(example);
|
||||
|
||||
FileMetadataRepositoryExample repositoryExample = new FileMetadataRepositoryExample();
|
||||
repositoryExample.createCriteria().andFileMetadataIdIn(deleteIds);
|
||||
fileMetadataRepositoryMapper.deleteByExample(repositoryExample);
|
||||
|
||||
//记录日志
|
||||
fileMetadataLogService.saveDeleteLog(deleteList, request.getProjectId(), operator);
|
||||
|
||||
|
|
|
@ -145,10 +145,9 @@ public class FileMetadataLogService {
|
|||
|
||||
public void saveRepositoryAddLog(FileMetadata fileMetadata, FileMetadataRepository repositoryFile, String operator) {
|
||||
Project project = projectMapper.selectByPrimaryKey(fileMetadata.getProjectId());
|
||||
Map<String, Object> logContent = new HashMap<>() {{
|
||||
this.put("fileMetadata", fileMetadata);
|
||||
this.put("repositoryFile", repositoryFile);
|
||||
}};
|
||||
Map<String, Object> logContent = new HashMap<>();
|
||||
logContent.put("fileMetadata", fileMetadata);
|
||||
logContent.put("repositoryFile", repositoryFile);
|
||||
LogDTO dto = LogDTOBuilder.builder()
|
||||
.projectId(fileMetadata.getProjectId())
|
||||
.organizationId(project.getOrganizationId())
|
||||
|
|
|
@ -4,12 +4,16 @@ import com.github.pagehelper.Page;
|
|||
import com.github.pagehelper.PageHelper;
|
||||
import io.metersphere.project.domain.FileMetadata;
|
||||
import io.metersphere.project.domain.FileMetadataExample;
|
||||
import io.metersphere.project.domain.FileMetadataRepository;
|
||||
import io.metersphere.project.domain.FileModuleRepository;
|
||||
import io.metersphere.project.dto.ModuleCountDTO;
|
||||
import io.metersphere.project.dto.filemanagement.FileManagementQuery;
|
||||
import io.metersphere.project.dto.filemanagement.request.*;
|
||||
import io.metersphere.project.dto.filemanagement.response.FileInformationResponse;
|
||||
import io.metersphere.project.mapper.ExtFileMetadataMapper;
|
||||
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.ModuleConstants;
|
||||
import io.metersphere.sdk.constants.StorageType;
|
||||
|
@ -50,6 +54,10 @@ public class FileMetadataService {
|
|||
@Resource
|
||||
private ExtFileMetadataMapper extFileMetadataMapper;
|
||||
@Resource
|
||||
private FileMetadataRepositoryMapper fileMetadataRepositoryMapper;
|
||||
@Resource
|
||||
private FileModuleRepositoryMapper fileModuleRepositoryMapper;
|
||||
@Resource
|
||||
private FileMetadataLogService fileMetadataLogService;
|
||||
@Resource
|
||||
private FileManagementService fileManagementService;
|
||||
|
@ -106,7 +114,7 @@ public class FileMetadataService {
|
|||
}
|
||||
}
|
||||
|
||||
public FileMetadata saveFileMetadata(String projectId, String moduleId, String filePath, String operator, long size, boolean enable) {
|
||||
public FileMetadata saveFileMetadata(String projectId, String moduleId, String filePath, String storage, String operator, long size, boolean enable) {
|
||||
String fileName = TempFileUtils.getFileNameByPath(filePath);
|
||||
FileMetadata fileMetadata = new FileMetadata();
|
||||
if (StringUtils.lastIndexOf(fileName, ".") > 0) {
|
||||
|
@ -125,7 +133,7 @@ public class FileMetadataService {
|
|||
this.checkFileName(null, fileMetadata.getName(), projectId);
|
||||
|
||||
fileMetadata.setId(IDGenerator.nextStr());
|
||||
fileMetadata.setStorage(StorageType.MINIO.name());
|
||||
fileMetadata.setStorage(storage);
|
||||
fileMetadata.setProjectId(projectId);
|
||||
fileMetadata.setModuleId(moduleId);
|
||||
long operationTime = System.currentTimeMillis();
|
||||
|
@ -148,7 +156,7 @@ public class FileMetadataService {
|
|||
|
||||
String fileName = StringUtils.trim(uploadFile.getOriginalFilename());
|
||||
|
||||
FileMetadata fileMetadata = this.saveFileMetadata(request.getProjectId(), request.getModuleId(), fileName, operator, uploadFile.getSize(), request.isEnable());
|
||||
FileMetadata fileMetadata = this.saveFileMetadata(request.getProjectId(), request.getModuleId(), fileName, StorageType.MINIO.name(), operator, uploadFile.getSize(), request.isEnable());
|
||||
|
||||
//记录日志
|
||||
fileMetadataLogService.saveUploadLog(fileMetadata, operator);
|
||||
|
@ -189,7 +197,7 @@ public class FileMetadataService {
|
|||
return fileService.upload(file, uploadFileRequest);
|
||||
}
|
||||
|
||||
public ResponseEntity<byte[]> downloadById(String id) {
|
||||
public ResponseEntity<byte[]> downloadById(String id) throws Exception {
|
||||
|
||||
FileMetadata fileMetadata = fileMetadataMapper.selectByPrimaryKey(id);
|
||||
byte[] bytes = this.getFile(fileMetadata);
|
||||
|
@ -206,7 +214,7 @@ public class FileMetadataService {
|
|||
return fileName + "." + type;
|
||||
}
|
||||
|
||||
private byte[] getFile(FileMetadata fileMetadata) {
|
||||
private byte[] getFile(FileMetadata fileMetadata) throws Exception {
|
||||
if (fileMetadata == null) {
|
||||
throw new MSException(Translator.get("file.not.exist"));
|
||||
}
|
||||
|
@ -214,12 +222,15 @@ public class FileMetadataService {
|
|||
fileRequest.setFileName(fileMetadata.getId());
|
||||
fileRequest.setProjectId(fileMetadata.getProjectId());
|
||||
fileRequest.setStorage(fileMetadata.getStorage());
|
||||
try {
|
||||
return fileService.download(fileRequest);
|
||||
} catch (Exception e) {
|
||||
LogUtils.error("获取文件失败", e);
|
||||
|
||||
//获取git文件下载
|
||||
if (StringUtils.equals(fileMetadata.getStorage(), StorageType.GIT.name())) {
|
||||
FileModuleRepository fileModuleRepository = fileModuleRepositoryMapper.selectByPrimaryKey(fileMetadata.getModuleId());
|
||||
FileMetadataRepository fileMetadataRepository = fileMetadataRepositoryMapper.selectByPrimaryKey(fileMetadata.getId());
|
||||
fileRequest.setGitFileRequest(fileModuleRepository, fileMetadataRepository);
|
||||
}
|
||||
return new byte[0];
|
||||
|
||||
return fileService.download(fileRequest);
|
||||
}
|
||||
|
||||
public void update(FileUpdateRequest request, String operator) {
|
||||
|
@ -281,9 +292,14 @@ public class FileMetadataService {
|
|||
public byte[] batchDownload(List<FileMetadata> fileMetadataList) {
|
||||
Map<String, byte[]> files = new LinkedHashMap<>();
|
||||
fileMetadataList.forEach(fileMetadata -> {
|
||||
byte[] bytes = this.getFile(fileMetadata);
|
||||
if (bytes != null) {
|
||||
files.put(this.getFileName(fileMetadata.getName(), fileMetadata.getType()), bytes);
|
||||
byte[] bytes;
|
||||
try {
|
||||
bytes = this.getFile(fileMetadata);
|
||||
if (bytes != null) {
|
||||
files.put(this.getFileName(fileMetadata.getName(), fileMetadata.getType()), bytes);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtils.error("下载文件失败", e);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -371,7 +387,7 @@ public class FileMetadataService {
|
|||
return moduleCountMap;
|
||||
}
|
||||
|
||||
public ResponseEntity<byte[]> downloadPreviewImgById(String id) {
|
||||
public ResponseEntity<byte[]> downloadPreviewImgById(String id) throws Exception {
|
||||
FileMetadata fileMetadata = fileMetadataMapper.selectByPrimaryKey(id);
|
||||
String previewImgPath = null;
|
||||
if (TempFileUtils.isImage(fileMetadata.getType())) {
|
||||
|
|
|
@ -2,12 +2,14 @@ package io.metersphere.project.service;
|
|||
|
||||
import io.metersphere.project.domain.FileModule;
|
||||
import io.metersphere.project.domain.FileModuleExample;
|
||||
import io.metersphere.project.domain.FileModuleRepositoryExample;
|
||||
import io.metersphere.project.dto.ModuleCountDTO;
|
||||
import io.metersphere.project.dto.NodeSortDTO;
|
||||
import io.metersphere.project.dto.filemanagement.request.FileModuleCreateRequest;
|
||||
import io.metersphere.project.dto.filemanagement.request.FileModuleUpdateRequest;
|
||||
import io.metersphere.project.mapper.ExtFileModuleMapper;
|
||||
import io.metersphere.project.mapper.FileModuleMapper;
|
||||
import io.metersphere.project.mapper.FileModuleRepositoryMapper;
|
||||
import io.metersphere.sdk.constants.ModuleConstants;
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.util.Translator;
|
||||
|
@ -37,6 +39,8 @@ public class FileModuleService extends ModuleTreeService implements CleanupProje
|
|||
@Resource
|
||||
protected FileModuleLogService fileModuleLogService;
|
||||
@Resource
|
||||
private FileModuleRepositoryMapper fileModuleRepositoryMapper;
|
||||
@Resource
|
||||
protected FileModuleMapper fileModuleMapper;
|
||||
@Resource
|
||||
protected ExtFileModuleMapper extFileModuleMapper;
|
||||
|
@ -139,12 +143,22 @@ public class FileModuleService extends ModuleTreeService implements CleanupProje
|
|||
//记录日志
|
||||
fileModuleLogService.saveDeleteLog(deleteModule, currentUser);
|
||||
}
|
||||
|
||||
FileModuleRepositoryExample repositoryExample = new FileModuleRepositoryExample();
|
||||
repositoryExample.createCriteria().andFileModuleIdEqualTo(deleteId);
|
||||
fileModuleRepositoryMapper.deleteByExample(repositoryExample);
|
||||
|
||||
}
|
||||
public void deleteModule(List<String> deleteIds) {
|
||||
if (CollectionUtils.isEmpty(deleteIds)) {
|
||||
return;
|
||||
}
|
||||
extFileModuleMapper.deleteByIds(deleteIds);
|
||||
|
||||
FileModuleRepositoryExample repositoryExample = new FileModuleRepositoryExample();
|
||||
repositoryExample.createCriteria().andFileModuleIdIn(deleteIds);
|
||||
fileModuleRepositoryMapper.deleteByExample(repositoryExample);
|
||||
|
||||
fileManagementService.deleteByModuleIds(deleteIds);
|
||||
|
||||
List<String> childrenIds = extFileModuleMapper.selectChildrenIdsByParentIds(deleteIds);
|
||||
|
|
|
@ -10,13 +10,14 @@ import io.metersphere.project.dto.filemanagement.request.FileRepositoryUpdateReq
|
|||
import io.metersphere.project.dto.filemanagement.request.RepositoryFileAddRequest;
|
||||
import io.metersphere.project.mapper.FileMetadataRepositoryMapper;
|
||||
import io.metersphere.project.mapper.FileModuleRepositoryMapper;
|
||||
import io.metersphere.project.utils.GitRepositoryUtil;
|
||||
import io.metersphere.sdk.constants.ModuleConstants;
|
||||
import io.metersphere.sdk.constants.StorageType;
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.util.Translator;
|
||||
import io.metersphere.system.dto.sdk.BaseTreeNode;
|
||||
import io.metersphere.system.dto.sdk.RemoteFileAttachInfo;
|
||||
import io.metersphere.system.uid.IDGenerator;
|
||||
import io.metersphere.system.utils.GitRepositoryUtil;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
|
@ -59,7 +60,7 @@ public class FileRepositoryService extends FileModuleService {
|
|||
fileModule.setPos(this.countPos(ModuleConstants.ROOT_NODE_PARENT_ID, ModuleConstants.NODE_TYPE_GIT));
|
||||
fileModule.setCreateUser(operator);
|
||||
fileModule.setUpdateUser(operator);
|
||||
fileModule.setModuleType(ModuleConstants.NODE_TYPE_DEFAULT);
|
||||
fileModule.setModuleType(ModuleConstants.NODE_TYPE_GIT);
|
||||
fileModuleMapper.insert(fileModule);
|
||||
|
||||
//记录模块仓库数据
|
||||
|
@ -137,7 +138,7 @@ public class FileRepositoryService extends FileModuleService {
|
|||
}
|
||||
|
||||
FileMetadata fileMetadata = fileMetadataService.saveFileMetadata(
|
||||
fileModule.getProjectId(), fileModule.getId(), request.getFilePath(), operator, fileAttachInfo.getSize(), request.isEnable());
|
||||
fileModule.getProjectId(), fileModule.getId(), request.getFilePath(), StorageType.GIT.name(), operator, fileAttachInfo.getSize(), request.isEnable());
|
||||
FileMetadataRepository fileMetadataRepository = new FileMetadataRepository();
|
||||
fileMetadataRepository.setFileMetadataId(fileMetadata.getId());
|
||||
fileMetadataRepository.setBranch(fileAttachInfo.getBranch());
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
package io.metersphere.project.controller.filemanagement;
|
||||
|
||||
import io.metersphere.project.domain.FileMetadata;
|
||||
import io.metersphere.project.domain.FileMetadataRepository;
|
||||
import io.metersphere.project.domain.FileModule;
|
||||
import io.metersphere.project.domain.FileModuleRepository;
|
||||
import io.metersphere.project.domain.*;
|
||||
import io.metersphere.project.dto.filemanagement.request.*;
|
||||
import io.metersphere.project.dto.filemanagement.response.FileInformationResponse;
|
||||
import io.metersphere.project.mapper.FileMetadataMapper;
|
||||
import io.metersphere.project.mapper.FileMetadataRepositoryMapper;
|
||||
import io.metersphere.project.mapper.FileModuleMapper;
|
||||
import io.metersphere.project.mapper.FileModuleRepositoryMapper;
|
||||
import io.metersphere.project.service.FileModuleService;
|
||||
import io.metersphere.project.utils.FileManagementRequestUtils;
|
||||
import io.metersphere.sdk.constants.ModuleConstants;
|
||||
import io.metersphere.sdk.constants.PermissionConstants;
|
||||
|
@ -27,15 +23,20 @@ import io.metersphere.system.service.CommonProjectService;
|
|||
import io.metersphere.system.uid.IDGenerator;
|
||||
import io.metersphere.system.utils.Pager;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.junit.jupiter.api.*;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.testcontainers.shaded.org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
|
@ -49,19 +50,11 @@ public class FileRepositoryControllerTest extends BaseTest {
|
|||
private static final String GITEE_USERNAME = "testformetersphere";
|
||||
private static final String GITEE_TOKEN = "4548d369bb595738d726512742e4478f";
|
||||
|
||||
private static List<BaseTreeNode> repositoryTreeNodes = new ArrayList<>();
|
||||
|
||||
private static final Map<String, String> FILE_ID_PATH = new LinkedHashMap<>();
|
||||
|
||||
private static final Map<String, String> FILE_VERSIONS_ID_MAP = new HashMap<>();
|
||||
|
||||
private static String reUploadFileId;
|
||||
private static final List<String> fileList = new ArrayList<>();
|
||||
|
||||
private static String repositoryId;
|
||||
private static String jarFileId;
|
||||
private static String picFileId;
|
||||
|
||||
@Resource
|
||||
private FileModuleService fileModuleService;
|
||||
@Resource
|
||||
private FileModuleMapper fileModuleMapper;
|
||||
@Resource
|
||||
|
@ -309,6 +302,43 @@ public class FileRepositoryControllerTest extends BaseTest {
|
|||
this.requestPost(FileManagementRequestUtils.URL_FILE_REPOSITORY_UPDATE, createRequest).andExpect(status().is5xxServerError());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(5)
|
||||
public void moduleDeleteTest() throws Exception {
|
||||
if (StringUtils.isEmpty(repositoryId)) {
|
||||
this.moduleAddTest();
|
||||
}
|
||||
|
||||
this.requestGetWithOk(String.format(FileManagementRequestUtils.URL_MODULE_DELETE, repositoryId));
|
||||
this.checkRepositoryDeleted(repositoryId);
|
||||
checkLog(repositoryId, OperationLogType.DELETE, FileManagementRequestUtils.URL_MODULE_DELETE);
|
||||
|
||||
|
||||
//重新添加
|
||||
this.moduleAddTest();
|
||||
|
||||
}
|
||||
|
||||
private void checkRepositoryDeleted(String repositoryId) {
|
||||
FileModuleRepositoryExample repositoryExample = new FileModuleRepositoryExample();
|
||||
repositoryExample.createCriteria().andFileModuleIdEqualTo(repositoryId);
|
||||
Assertions.assertEquals(fileModuleRepositoryMapper.countByExample(repositoryExample), 0);
|
||||
|
||||
FileModuleExample example = new FileModuleExample();
|
||||
example.createCriteria().andIdEqualTo(repositoryId);
|
||||
Assertions.assertEquals(fileModuleMapper.countByExample(example), 0);
|
||||
}
|
||||
|
||||
private void checkRepositoryFileDeleted(String fileId) {
|
||||
FileMetadataRepositoryExample repositoryExample = new FileMetadataRepositoryExample();
|
||||
repositoryExample.createCriteria().andFileMetadataIdEqualTo(fileId);
|
||||
Assertions.assertEquals(fileMetadataRepositoryMapper.countByExample(repositoryExample), 0);
|
||||
|
||||
FileMetadataExample example = new FileMetadataExample();
|
||||
example.createCriteria().andIdEqualTo(fileId);
|
||||
Assertions.assertEquals(fileMetadataMapper.countByExample(example), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(10)
|
||||
public void repositoryListTest() throws Exception {
|
||||
|
@ -333,6 +363,8 @@ public class FileRepositoryControllerTest extends BaseTest {
|
|||
MvcResult result = this.requestPostWithOkAndReturn(FileManagementRequestUtils.URL_FILE_REPOSITORY_FILE_ADD, request);
|
||||
String fileId = JSON.parseObject(result.getResponse().getContentAsString(), ResultHolder.class).getData().toString();
|
||||
this.checkFileRepositoryFile(fileId, request);
|
||||
this.checkLog(fileId, OperationLogType.ADD, FileManagementRequestUtils.URL_FILE_REPOSITORY_FILE_ADD);
|
||||
fileList.add(fileId);
|
||||
//测试其他分支的多层目录的文件
|
||||
String otherBranch = "develop";
|
||||
String folderFilePath1 = "test-folder/gitee/test.txt";
|
||||
|
@ -343,7 +375,7 @@ public class FileRepositoryControllerTest extends BaseTest {
|
|||
result = this.requestPostWithOkAndReturn(FileManagementRequestUtils.URL_FILE_REPOSITORY_FILE_ADD, request);
|
||||
fileId = JSON.parseObject(result.getResponse().getContentAsString(), ResultHolder.class).getData().toString();
|
||||
this.checkFileRepositoryFile(fileId, request);
|
||||
|
||||
fileList.add(fileId);
|
||||
//测试隐藏文件
|
||||
String folderFilePath2 = "test-folder/.keep";
|
||||
request = new RepositoryFileAddRequest();
|
||||
|
@ -353,7 +385,7 @@ public class FileRepositoryControllerTest extends BaseTest {
|
|||
result = this.requestPostWithOkAndReturn(FileManagementRequestUtils.URL_FILE_REPOSITORY_FILE_ADD, request);
|
||||
fileId = JSON.parseObject(result.getResponse().getContentAsString(), ResultHolder.class).getData().toString();
|
||||
this.checkFileRepositoryFile(fileId, request);
|
||||
|
||||
fileList.add(fileId);
|
||||
//测试添加jar包并且启用
|
||||
request = new RepositoryFileAddRequest();
|
||||
request.setBranch(branch);
|
||||
|
@ -363,7 +395,17 @@ public class FileRepositoryControllerTest extends BaseTest {
|
|||
result = this.requestPostWithOkAndReturn(FileManagementRequestUtils.URL_FILE_REPOSITORY_FILE_ADD, request);
|
||||
fileId = JSON.parseObject(result.getResponse().getContentAsString(), ResultHolder.class).getData().toString();
|
||||
this.checkFileRepositoryFile(fileId, request);
|
||||
|
||||
fileList.add(fileId);
|
||||
//获取图片信息
|
||||
request = new RepositoryFileAddRequest();
|
||||
request.setBranch(otherBranch);
|
||||
request.setFilePath("1095388459180046.jpg");
|
||||
request.setModuleId(repositoryId);
|
||||
result = this.requestPostWithOkAndReturn(FileManagementRequestUtils.URL_FILE_REPOSITORY_FILE_ADD, request);
|
||||
fileId = JSON.parseObject(result.getResponse().getContentAsString(), ResultHolder.class).getData().toString();
|
||||
this.checkFileRepositoryFile(fileId, request);
|
||||
this.picFileId = fileId;
|
||||
fileList.add(fileId);
|
||||
{
|
||||
//重复添加测试
|
||||
request = new RepositoryFileAddRequest();
|
||||
|
@ -418,11 +460,28 @@ public class FileRepositoryControllerTest extends BaseTest {
|
|||
request.setBranch(IDGenerator.nextStr());
|
||||
request.setFilePath(folderFilePath2);
|
||||
this.requestPost(FileManagementRequestUtils.URL_FILE_REPOSITORY_FILE_ADD, request).andExpect(status().isBadRequest());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(12)
|
||||
public void repositoryGetFileTest() throws Exception {
|
||||
if (StringUtils.isEmpty(picFileId)) {
|
||||
this.repositoryAddFileTest();
|
||||
}
|
||||
//下载文件
|
||||
MvcResult originalResult = this.downloadFile(String.format(FileManagementRequestUtils.URL_FILE_PREVIEW_ORIGINAL, "admin", picFileId));
|
||||
byte[] fileBytes = originalResult.getResponse().getContentAsByteArray();
|
||||
Assertions.assertTrue(fileBytes.length > 0);
|
||||
//预览文件
|
||||
originalResult = this.downloadFile(String.format(FileManagementRequestUtils.URL_FILE_PREVIEW_ORIGINAL, "admin", picFileId));
|
||||
Assertions.assertTrue(originalResult.getResponse().getContentAsByteArray().length > 0);
|
||||
MvcResult compressedResult = this.downloadFile(String.format(FileManagementRequestUtils.URL_FILE_PREVIEW_COMPRESSED, "admin", picFileId));
|
||||
Assertions.assertTrue(compressedResult.getResponse().getContentAsByteArray().length > 0);
|
||||
}
|
||||
|
||||
|
||||
private void checkFileRepositoryFile(String fileId, RepositoryFileAddRequest request) {
|
||||
FileMetadataRepository repository = fileMetadataRepositoryMapper.selectByPrimaryKey(fileId);
|
||||
Assertions.assertEquals(repository.getBranch(), request.getBranch());
|
||||
|
@ -430,6 +489,13 @@ public class FileRepositoryControllerTest extends BaseTest {
|
|||
Assertions.assertNotNull(repository.getCommitMessage());
|
||||
FileMetadata fileMetadata = fileMetadataMapper.selectByPrimaryKey(fileId);
|
||||
Assertions.assertEquals(fileMetadata.getPath(), request.getFilePath());
|
||||
Assertions.assertEquals(fileMetadata.getStorage(), StorageType.GIT.name());
|
||||
}
|
||||
|
||||
protected MvcResult downloadFile(String url, Object... uriVariables) throws Exception {
|
||||
return mockMvc.perform(getRequestBuilder(url, uriVariables))
|
||||
.andExpect(content().contentType(MediaType.APPLICATION_OCTET_STREAM_VALUE))
|
||||
.andExpect(status().isOk()).andReturn();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -440,9 +506,27 @@ public class FileRepositoryControllerTest extends BaseTest {
|
|||
this.requestGetPermissionTest(PermissionConstants.PROJECT_FILE_MANAGEMENT_READ, String.format(FileManagementRequestUtils.URL_FILE_REPOSITORY_FILE_TYPE, DEFAULT_PROJECT_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(99)
|
||||
public void repositoryFileDeleteTest() throws Exception {
|
||||
if (CollectionUtils.isEmpty(fileList)) {
|
||||
this.repositoryAddFileTest();
|
||||
}
|
||||
FileBatchProcessRequest fileBatchProcessRequest = new FileBatchProcessRequest();
|
||||
fileBatchProcessRequest.setProjectId(project.getId());
|
||||
fileBatchProcessRequest.setSelectIds(fileList);
|
||||
this.requestPostWithOk(FileManagementRequestUtils.URL_FILE_DELETE, fileBatchProcessRequest);
|
||||
for (String fileId : fileList) {
|
||||
this.checkLog(fileId, OperationLogType.DELETE, FileManagementRequestUtils.URL_FILE_DELETE);
|
||||
this.checkRepositoryFileDeleted(fileId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void checkFileRepository(String repositoryId, String projectId, String name, String platform, String url, String token, String userName) {
|
||||
FileModule module = fileModuleMapper.selectByPrimaryKey(repositoryId);
|
||||
FileModuleRepository repository = fileModuleRepositoryMapper.selectByPrimaryKey(repositoryId);
|
||||
Assertions.assertEquals(module.getModuleType(), ModuleConstants.NODE_TYPE_GIT);
|
||||
if (StringUtils.isNotEmpty(projectId)) {
|
||||
Assertions.assertEquals(module.getProjectId(), projectId);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package io.metersphere.project.dto.filemanagement;
|
||||
package io.metersphere.system.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
|
@ -12,6 +12,7 @@ public class FileCenter {
|
|||
Map<StorageType, FileRepository> repositoryMap = new HashMap<>() {{
|
||||
put(StorageType.MINIO, CommonBeanFactory.getBean(MinioRepository.class));
|
||||
put(StorageType.LOCAL, CommonBeanFactory.getBean(LocalFileRepository.class));
|
||||
put(StorageType.GIT, CommonBeanFactory.getBean(GitRepository.class));
|
||||
}};
|
||||
FileRepository fileRepository = repositoryMap.get(storageType);
|
||||
return fileRepository == null ? getDefaultRepository() : fileRepository;
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package io.metersphere.system.file;
|
||||
|
||||
import io.metersphere.project.domain.FileMetadataRepository;
|
||||
import io.metersphere.project.domain.FileModuleRepository;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
|
@ -15,4 +18,21 @@ public class FileRequest {
|
|||
|
||||
// 文件名称
|
||||
private String fileName;
|
||||
|
||||
//Git文件信息
|
||||
private GitFileRequest gitFileRequest;
|
||||
|
||||
public void setGitFileRequest(FileModuleRepository repository, FileMetadataRepository file) {
|
||||
gitFileRequest = new GitFileRequest(repository.getUrl(), repository.getToken(), repository.getUserName(), file.getBranch(), file.getCommitId());
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
class GitFileRequest {
|
||||
private String url;
|
||||
private String token;
|
||||
private String userName;
|
||||
private String branch;
|
||||
private String commitId;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
package io.metersphere.system.file;
|
||||
|
||||
import io.metersphere.system.utils.GitRepositoryUtil;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class GitRepository implements FileRepository {
|
||||
|
||||
@Override
|
||||
public String saveFile(MultipartFile file, FileRequest request) throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String saveFile(byte[] bytes, FileRequest request) throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String saveFile(InputStream inputStream, FileRequest request) throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(FileRequest request) throws Exception {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteFolder(FileRequest request) throws Exception {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getFile(FileRequest request) throws Exception {
|
||||
byte[] fileBytes = new byte[0];
|
||||
if (request.getGitFileRequest() != null) {
|
||||
GitFileRequest gitFileInfo = request.getGitFileRequest();
|
||||
GitRepositoryUtil repositoryUtils = new GitRepositoryUtil(
|
||||
gitFileInfo.getUrl(), gitFileInfo.getUserName(), gitFileInfo.getToken());
|
||||
fileBytes = repositoryUtils.getFile(gitFileInfo.getUrl(), gitFileInfo.getCommitId());
|
||||
}
|
||||
return fileBytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getFileAsStream(FileRequest request) throws Exception {
|
||||
return new ByteArrayInputStream(getFile(request));
|
||||
}
|
||||
|
||||
// 缓冲区大小
|
||||
private static final int BUFFER_SIZE = 8192;
|
||||
|
||||
@Override
|
||||
public void downloadFile(FileRequest request, String fullPath) throws Exception {
|
||||
// 下载对象到本地文件
|
||||
try (InputStream inputStream = getFileAsStream(request);
|
||||
BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(fullPath))) {
|
||||
byte[] buffer = new byte[BUFFER_SIZE];
|
||||
int bytesRead;
|
||||
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||
outputStream.write(buffer, 0, bytesRead);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getFolderFileNames(FileRequest request) throws Exception {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
package io.metersphere.project.utils;
|
||||
package io.metersphere.system.utils;
|
||||
|
||||
import io.metersphere.sdk.util.LogUtils;
|
||||
import io.metersphere.system.dto.RepositoryQuery;
|
||||
import io.metersphere.system.dto.sdk.RemoteFileAttachInfo;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
|
||||
|
@ -19,9 +21,8 @@ import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
|
|||
import org.eclipse.jgit.treewalk.TreeWalk;
|
||||
import org.eclipse.jgit.treewalk.filter.PathFilter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class GitRepositoryUtil {
|
||||
private final String REF_SPACE = "+refs/heads/*:refs/heads/*";
|
||||
|
@ -46,40 +47,40 @@ public class GitRepositoryUtil {
|
|||
|
||||
//以下方法先注释掉,用到了再打开
|
||||
|
||||
// public byte[] getSingleFile(String filePath, String commitId) throws Exception {
|
||||
// LogUtils.info("准备获取文件. repositoryUrl:" + repositoryUrl + "; filePath:" + filePath + "; commitId:" + commitId);
|
||||
// InMemoryRepository repo = this.getGitRepositoryInMemory(repositoryUrl, userName, token);
|
||||
// ObjectId fileCommitObjectId = repo.resolve(commitId);
|
||||
// ObjectId objectId = this.getTreeWork(repo, fileCommitObjectId, filePath).getObjectId(0);
|
||||
// ObjectLoader loader = repo.open(objectId);
|
||||
// byte[] returnBytes = loader.getBytes();
|
||||
// this.closeConnection(repo);
|
||||
// return returnBytes;
|
||||
// }
|
||||
public byte[] getFile(String filePath, String commitId) throws Exception {
|
||||
LogUtils.info("准备获取文件. repositoryUrl:" + repositoryUrl + "; filePath:" + filePath + "; commitId:" + commitId);
|
||||
InMemoryRepository repo = this.getGitRepositoryInMemory(repositoryUrl, userName, token);
|
||||
ObjectId fileCommitObjectId = repo.resolve(commitId);
|
||||
ObjectId objectId = this.getTreeWork(repo, fileCommitObjectId, filePath).getObjectId(0);
|
||||
ObjectLoader loader = repo.open(objectId);
|
||||
byte[] returnBytes = loader.getBytes();
|
||||
this.closeConnection(repo);
|
||||
return returnBytes;
|
||||
}
|
||||
|
||||
// public Map<String, byte[]> getFiles(List<RepositoryQuery> RepositoryQueryList) throws Exception {
|
||||
// Map<String, byte[]> returnMap = new HashMap<>();
|
||||
// if (CollectionUtils.isEmpty(RepositoryQueryList)) {
|
||||
// return returnMap;
|
||||
// }
|
||||
// Map<String, List<RepositoryQuery>> commitIdFilePathMap = RepositoryQueryList.stream().collect(Collectors.groupingBy(RepositoryQuery::getCommitId));
|
||||
// InMemoryRepository repo = this.getGitRepositoryInMemory(repositoryUrl, userName, token);
|
||||
// ObjectId fileCommitObjectId;
|
||||
// for (Map.Entry<String, List<RepositoryQuery>> commitFilePathEntry : commitIdFilePathMap.entrySet()) {
|
||||
// String commitId = commitFilePathEntry.getKey();
|
||||
// List<RepositoryQuery> itemRequestList = commitFilePathEntry.getValue();
|
||||
// for (RepositoryQuery RepositoryQuery : itemRequestList) {
|
||||
// String filePath = RepositoryQuery.getFilePath();
|
||||
// fileCommitObjectId = repo.resolve(commitId);
|
||||
// ObjectId objectId = this.getTreeWork(repo, fileCommitObjectId, filePath).getObjectId(0);
|
||||
// ObjectLoader loader = repo.open(objectId);
|
||||
// returnMap.put(RepositoryQuery.getFileMetadataId(), loader.getBytes());
|
||||
// }
|
||||
// this.closeConnection(repo);
|
||||
// }
|
||||
// LogUtils.info("准备批量获取文件结束. repositoryUrl:" + repositoryUrl);
|
||||
// return returnMap;
|
||||
// }
|
||||
public Map<String, byte[]> getFiles(List<RepositoryQuery> RepositoryQueryList) throws Exception {
|
||||
Map<String, byte[]> returnMap = new HashMap<>();
|
||||
if (CollectionUtils.isEmpty(RepositoryQueryList)) {
|
||||
return returnMap;
|
||||
}
|
||||
Map<String, List<RepositoryQuery>> commitIdFilePathMap = RepositoryQueryList.stream().collect(Collectors.groupingBy(RepositoryQuery::getCommitId));
|
||||
InMemoryRepository repo = this.getGitRepositoryInMemory(repositoryUrl, userName, token);
|
||||
ObjectId fileCommitObjectId;
|
||||
for (Map.Entry<String, List<RepositoryQuery>> commitFilePathEntry : commitIdFilePathMap.entrySet()) {
|
||||
String commitId = commitFilePathEntry.getKey();
|
||||
List<RepositoryQuery> itemRequestList = commitFilePathEntry.getValue();
|
||||
for (RepositoryQuery repositoryQuery : itemRequestList) {
|
||||
String filePath = repositoryQuery.getFilePath();
|
||||
fileCommitObjectId = repo.resolve(commitId);
|
||||
ObjectId objectId = this.getTreeWork(repo, fileCommitObjectId, filePath).getObjectId(0);
|
||||
ObjectLoader loader = repo.open(objectId);
|
||||
returnMap.put(repositoryQuery.getFileMetadataId(), loader.getBytes());
|
||||
}
|
||||
this.closeConnection(repo);
|
||||
}
|
||||
LogUtils.info("准备批量获取文件结束. repositoryUrl:" + repositoryUrl);
|
||||
return returnMap;
|
||||
}
|
||||
|
||||
public RemoteFileAttachInfo selectLastCommitIdByBranch(String branch, String filePath) {
|
||||
RemoteFileAttachInfo attachInfo;
|
||||
|
@ -143,16 +144,16 @@ public class GitRepositoryUtil {
|
|||
return repo;
|
||||
}
|
||||
|
||||
// private TreeWalk getTreeWork(InMemoryRepository repo, ObjectId fileCommitObjectId, String filePath) throws Exception {
|
||||
// RevWalk revWalk = new RevWalk(repo);
|
||||
// RevCommit commit = revWalk.parseCommit(fileCommitObjectId);
|
||||
// RevTree tree = commit.getTree();
|
||||
// TreeWalk treeWalk = new TreeWalk(repo);
|
||||
// treeWalk.addTree(tree);
|
||||
// treeWalk.setRecursive(true);
|
||||
// treeWalk.setFilter(PathFilter.create(filePath));
|
||||
// return treeWalk;
|
||||
// }
|
||||
private TreeWalk getTreeWork(InMemoryRepository repo, ObjectId fileCommitObjectId, String filePath) throws Exception {
|
||||
RevWalk revWalk = new RevWalk(repo);
|
||||
RevCommit commit = revWalk.parseCommit(fileCommitObjectId);
|
||||
RevTree tree = commit.getTree();
|
||||
TreeWalk treeWalk = new TreeWalk(repo);
|
||||
treeWalk.addTree(tree);
|
||||
treeWalk.setRecursive(true);
|
||||
treeWalk.setFilter(PathFilter.create(filePath));
|
||||
return treeWalk;
|
||||
}
|
||||
|
||||
private void closeConnection(Repository repo) {
|
||||
if (git != null) {
|
Loading…
Reference in New Issue