diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java index 113ccb6bd1..9dc12d9ba0 100644 --- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java +++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java @@ -323,6 +323,8 @@ public enum Status { REMOVE_TASK_INSTANCE_CACHE_ERROR(20019, "remove task instance cache error", "删除任务实例缓存错误"), + ILLEGAL_RESOURCE_PATH(20020, "Resource file [{0}] is illegal", "非法的资源路径[{0}]"), + USER_NO_OPERATION_PERM(30001, "user has no operation privilege", "当前用户没有操作权限"), USER_NO_OPERATION_PROJECT_PERM(30002, "user {0} is not has project {1} permission", "当前用户[{0}]没有[{1}]项目的操作权限"), USER_NO_WRITE_PROJECT_PERM(30003, "user [{0}] does not have write permission for project [{1}]", diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ResourcesService.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ResourcesService.java index 24d1ba8727..54023baad9 100644 --- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ResourcesService.java +++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ResourcesService.java @@ -194,13 +194,13 @@ public interface ResourcesService { org.springframework.core.io.Resource downloadResource(User loginUser, String fullName) throws IOException; /** - * Get resource by given resource type and full name. + * Get resource by given resource type and file name. * Useful in Python API create task which need processDefinition information. * * @param userName user who query resource - * @param fullName full name of the resource + * @param fileName file name of the resource */ - StorageEntity queryFileStatus(String userName, String fullName) throws Exception; + StorageEntity queryFileStatus(String userName, String fileName) throws Exception; /** * delete DATA_TRANSFER data in resource center diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ResourcesServiceImpl.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ResourcesServiceImpl.java index e6341f021d..6a15da17a8 100644 --- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ResourcesServiceImpl.java +++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ResourcesServiceImpl.java @@ -126,6 +126,7 @@ public class ResourcesServiceImpl extends BaseServiceImpl implements ResourcesSe } String tenantCode = getTenantCode(user); + checkFullName(tenantCode, currentDir); String userResRootPath = ResourceType.UDF.equals(type) ? storageOperate.getUdfDir(tenantCode) : storageOperate.getResDir(tenantCode); @@ -171,6 +172,7 @@ public class ResourcesServiceImpl extends BaseServiceImpl implements ResourcesSe } String tenantCode = getTenantCode(user); + checkFullName(tenantCode, currentDir); result = verifyFile(name, type, file); if (!result.getCode().equals(Status.SUCCESS.getCode())) { @@ -257,6 +259,7 @@ public class ResourcesServiceImpl extends BaseServiceImpl implements ResourcesSe } String tenantCode = getTenantCode(user); + checkFullName(tenantCode, resourceFullName); if (!isUserTenantValid(isAdmin(loginUser), tenantCode, resTenantCode)) { log.error("current user does not have permission"); @@ -264,7 +267,7 @@ public class ResourcesServiceImpl extends BaseServiceImpl implements ResourcesSe return result; } - String defaultPath = storageOperate.getResDir(tenantCode); + String defaultPath = storageOperate.getDir(type, tenantCode); StorageEntity resource; try { @@ -949,6 +952,7 @@ public class ResourcesServiceImpl extends BaseServiceImpl implements ResourcesSe } String tenantCode = getTenantCode(user); + checkFullName(tenantCode, currentDir); if (FileUtils.directoryTraversal(fileName)) { log.warn("File name verify failed, fileName:{}.", RegexUtils.escapeNRT(fileName)); @@ -1280,9 +1284,19 @@ public class ResourcesServiceImpl extends BaseServiceImpl implements ResourcesSe } private void checkFullName(String userTenantCode, String fullName) { + if (StringUtils.isEmpty(fullName)) { + return; + } + if (FOLDER_SEPARATOR.equalsIgnoreCase(fullName)) { + return; + } + // Avoid returning to the parent directory + if (fullName.contains("../")) { + throw new ServiceException(Status.ILLEGAL_RESOURCE_PATH, fullName); + } String baseDir = storageOperate.getDir(ResourceType.ALL, userTenantCode); - if (StringUtils.isNotBlank(fullName) && !StringUtils.startsWith(fullName, baseDir)) { - throw new ServiceException("Resource file: " + fullName + " is illegal"); + if (!StringUtils.startsWith(fullName, baseDir)) { + throw new ServiceException(Status.ILLEGAL_RESOURCE_PATH, fullName); } } } diff --git a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ResourcesServiceTest.java b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ResourcesServiceTest.java index 0679b8892d..6e94a25861 100644 --- a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ResourcesServiceTest.java +++ b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ResourcesServiceTest.java @@ -18,7 +18,6 @@ package org.apache.dolphinscheduler.api.service; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; @@ -70,8 +69,6 @@ import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.mock.web.MockMultipartFile; import com.google.common.io.Files; @@ -83,9 +80,10 @@ import com.google.common.io.Files; @MockitoSettings(strictness = Strictness.LENIENT) public class ResourcesServiceTest { - private static final Logger logger = LoggerFactory.getLogger(ResourcesServiceTest.class); - + private static final String basePath = "/dolphinscheduler"; private static final String tenantCode = "123"; + private static final String tenantFileResourceDir = "/dolphinscheduler/123/resources/"; + private static final String tenantUdfResourceDir = "/dolphinscheduler/123/udfs/"; @InjectMocks private ResourcesServiceImpl resourcesService; @@ -153,18 +151,30 @@ public class ResourcesServiceTest { // CURRENT_LOGIN_USER_TENANT_NOT_EXIST when(userMapper.selectById(user.getId())).thenReturn(getUser()); when(tenantMapper.queryById(1)).thenReturn(null); - Assertions.assertThrows(ServiceException.class, + ServiceException serviceException = Assertions.assertThrows(ServiceException.class, () -> resourcesService.uploadResource(user, "ResourcesServiceTest", ResourceType.FILE, new MockMultipartFile("test.pdf", "test.pdf", "pdf", "test".getBytes()), "/")); + assertEquals(Status.CURRENT_LOGIN_USER_TENANT_NOT_EXIST.getMsg(), serviceException.getMessage()); + // set tenant for user user.setTenantId(1); when(tenantMapper.queryById(1)).thenReturn(getTenant()); + when(storageOperate.getDir(ResourceType.ALL, tenantCode)).thenReturn(basePath); + + // ILLEGAL_RESOURCE_FILE + String illegal_path = "/dolphinscheduler/123/../"; + serviceException = Assertions.assertThrows(ServiceException.class, + () -> { + MockMultipartFile mockMultipartFile = new MockMultipartFile("test.pdf", "".getBytes()); + resourcesService.uploadResource(user, "ResourcesServiceTest", ResourceType.FILE, + mockMultipartFile, illegal_path); + }); + assertEquals(new ServiceException(Status.ILLEGAL_RESOURCE_PATH, illegal_path), serviceException); // RESOURCE_FILE_IS_EMPTY MockMultipartFile mockMultipartFile = new MockMultipartFile("test.pdf", "".getBytes()); Result result = resourcesService.uploadResource(user, "ResourcesServiceTest", ResourceType.FILE, - mockMultipartFile, "/"); - logger.info(result.toString()); + mockMultipartFile, tenantFileResourceDir); assertEquals(Status.RESOURCE_FILE_IS_EMPTY.getMsg(), result.getMsg()); // RESOURCE_SUFFIX_FORBID_CHANGE @@ -172,8 +182,7 @@ public class ResourcesServiceTest { when(Files.getFileExtension("test.pdf")).thenReturn("pdf"); when(Files.getFileExtension("ResourcesServiceTest.jar")).thenReturn("jar"); result = resourcesService.uploadResource(user, "ResourcesServiceTest.jar", ResourceType.FILE, mockMultipartFile, - "/"); - logger.info(result.toString()); + tenantFileResourceDir); assertEquals(Status.RESOURCE_SUFFIX_FORBID_CHANGE.getMsg(), result.getMsg()); // UDF_RESOURCE_SUFFIX_NOT_JAR @@ -181,45 +190,42 @@ public class ResourcesServiceTest { new MockMultipartFile("ResourcesServiceTest.pdf", "ResourcesServiceTest.pdf", "pdf", "test".getBytes()); when(Files.getFileExtension("ResourcesServiceTest.pdf")).thenReturn("pdf"); result = resourcesService.uploadResource(user, "ResourcesServiceTest.pdf", ResourceType.UDF, mockMultipartFile, - "/"); - logger.info(result.toString()); + tenantUdfResourceDir); assertEquals(Status.UDF_RESOURCE_SUFFIX_NOT_JAR.getMsg(), result.getMsg()); // FULL_FILE_NAME_TOO_LONG String tooLongFileName = getRandomStringWithLength(Constants.RESOURCE_FULL_NAME_MAX_LENGTH) + ".pdf"; mockMultipartFile = new MockMultipartFile(tooLongFileName, tooLongFileName, "pdf", "test".getBytes()); when(Files.getFileExtension(tooLongFileName)).thenReturn("pdf"); + // '/databasePath/tenantCode/RESOURCE/' - when(storageOperate.getResDir(tenantCode)).thenReturn("/dolphinscheduler/123/resources/"); - result = resourcesService.uploadResource(user, tooLongFileName, ResourceType.FILE, mockMultipartFile, "/"); - logger.info(result.toString()); + when(storageOperate.getResDir(tenantCode)).thenReturn(tenantFileResourceDir); + result = resourcesService.uploadResource(user, tooLongFileName, ResourceType.FILE, mockMultipartFile, + tenantFileResourceDir); assertEquals(Status.RESOURCE_FULL_NAME_TOO_LONG_ERROR.getMsg(), result.getMsg()); } @Test - public void testCreateDirecotry() { + public void testCreateDirecotry() throws IOException { User user = new User(); user.setId(1); user.setUserType(UserType.GENERAL_USER); + String fileName = "directoryTest"; // RESOURCE_EXIST user.setId(1); user.setTenantId(1); when(tenantMapper.queryById(1)).thenReturn(getTenant()); when(userMapper.selectById(user.getId())).thenReturn(getUser()); - when(storageOperate.getResDir(tenantCode)).thenReturn("/dolphinscheduler/123/resources/"); - try { - when(storageOperate.exists("/dolphinscheduler/123/resources/directoryTest")).thenReturn(true); - } catch (IOException e) { - logger.error(e.getMessage(), e); - } - Result result = resourcesService.createDirectory(user, "directoryTest", ResourceType.FILE, -1, "/"); - logger.info(result.toString()); + when(storageOperate.getDir(ResourceType.ALL, tenantCode)).thenReturn(basePath); + when(storageOperate.getResDir(tenantCode)).thenReturn(tenantFileResourceDir); + when(storageOperate.exists(tenantFileResourceDir + fileName)).thenReturn(true); + Result result = resourcesService.createDirectory(user, fileName, ResourceType.FILE, -1, tenantFileResourceDir); assertEquals(Status.RESOURCE_EXIST.getMsg(), result.getMsg()); } @Test - public void testUpdateResource() { + public void testUpdateResource() throws Exception { User user = new User(); user.setId(1); user.setUserType(UserType.GENERAL_USER); @@ -227,7 +233,13 @@ public class ResourcesServiceTest { when(userMapper.selectById(user.getId())).thenReturn(getUser()); when(tenantMapper.queryById(1)).thenReturn(getTenant()); - when(storageOperate.getResDir(tenantCode)).thenReturn("/dolphinscheduler/123/resources/"); + when(storageOperate.getDir(ResourceType.ALL, tenantCode)).thenReturn(basePath); + when(storageOperate.getResDir(tenantCode)).thenReturn(tenantFileResourceDir); + + // TENANT_NOT_EXIST + when(tenantMapper.queryById(Mockito.anyInt())).thenReturn(null); + Assertions.assertThrows(ServiceException.class, () -> resourcesService.updateResource(user, + "ResourcesServiceTest1.jar", "", "ResourcesServiceTest", ResourceType.UDF, null)); // USER_NO_OPERATION_PERM user.setUserType(UserType.GENERAL_USER); @@ -235,92 +247,58 @@ public class ResourcesServiceTest { Tenant tenantWNoPermission = new Tenant(); tenantWNoPermission.setTenantCode("321"); when(tenantMapper.queryById(1)).thenReturn(tenantWNoPermission); - Result result = resourcesService.updateResource(user, "/dolphinscheduler/123/resources/ResourcesServiceTest", - tenantCode, "ResourcesServiceTest", ResourceType.FILE, null); - logger.info(result.toString()); + when(storageOperate.getDir(ResourceType.ALL, "321")).thenReturn(basePath); + + String fileName = "ResourcesServiceTest"; + Result result = resourcesService.updateResource(user, tenantFileResourceDir + fileName, + tenantCode, fileName, ResourceType.FILE, null); assertEquals(Status.NO_CURRENT_OPERATING_PERMISSION.getMsg(), result.getMsg()); // SUCCESS when(tenantMapper.queryById(1)).thenReturn(getTenant()); - try { - when(storageOperate.exists(Mockito.any())).thenReturn(false); - } catch (IOException e) { - logger.error(e.getMessage(), e); - } - - try { - when(storageOperate.getFileStatus("/dolphinscheduler/123/resources/ResourcesServiceTest", - "/dolphinscheduler/123/resources/", tenantCode, ResourceType.FILE)) - .thenReturn(getStorageEntityResource()); - result = resourcesService.updateResource(user, "/dolphinscheduler/123/resources/ResourcesServiceTest", - tenantCode, "ResourcesServiceTest", ResourceType.FILE, null); - logger.info(result.toString()); - assertEquals(Status.SUCCESS.getMsg(), result.getMsg()); - } catch (Exception e) { - logger.error(e.getMessage() + " Resource path: {}", "/dolphinscheduler/123/resources/ResourcesServiceTest", - e); - } + when(storageOperate.exists(Mockito.any())).thenReturn(false); + + when(storageOperate.getDir(ResourceType.FILE, tenantCode)).thenReturn(tenantFileResourceDir); + when(storageOperate.getFileStatus(tenantFileResourceDir + fileName, + tenantFileResourceDir, tenantCode, ResourceType.FILE)) + .thenReturn(getStorageEntityResource(fileName)); + result = resourcesService.updateResource(user, tenantFileResourceDir + fileName, + tenantCode, fileName, ResourceType.FILE, null); + assertEquals(Status.SUCCESS.getMsg(), result.getMsg()); // Tests for udf resources. - // RESOURCE_EXIST - try { - when(storageOperate.exists("/dolphinscheduler/123/resources/ResourcesServiceTest2.jar")).thenReturn(true); - } catch (IOException e) { - logger.error("error occurred when checking resource: " - + "/dolphinscheduler/123/resources/ResourcesServiceTest2.jar"); - } - - try { - when(storageOperate.getFileStatus("/dolphinscheduler/123/resources/ResourcesServiceTest1.jar", - "/dolphinscheduler/123/resources/", tenantCode, ResourceType.UDF)) - .thenReturn(getStorageEntityUdfResource()); - } catch (Exception e) { - logger.error(e.getMessage() + " Resource path: {}", - "/dolphinscheduler/123/resources/ResourcesServiceTest1.jar", e); - } - result = resourcesService.updateResource(user, "/dolphinscheduler/123/resources/ResourcesServiceTest1.jar", - tenantCode, "ResourcesServiceTest2.jar", ResourceType.UDF, null); - logger.info(result.toString()); - assertEquals(Status.RESOURCE_EXIST.getMsg(), result.getMsg()); - - // TENANT_NOT_EXIST - when(tenantMapper.queryById(Mockito.anyInt())).thenReturn(null); - Assertions.assertThrows(ServiceException.class, () -> resourcesService.updateResource(user, - "ResourcesServiceTest1.jar", "", "ResourcesServiceTest", ResourceType.UDF, null)); - - // SUCCESS - when(tenantMapper.queryById(1)).thenReturn(getTenant()); - - result = resourcesService.updateResource(user, "/dolphinscheduler/123/resources/ResourcesServiceTest1.jar", - tenantCode, "ResourcesServiceTest1.jar", ResourceType.UDF, null); - logger.info(result.toString()); + fileName = "ResourcesServiceTest.jar"; + when(storageOperate.getDir(ResourceType.UDF, tenantCode)).thenReturn(tenantUdfResourceDir); + when(storageOperate.exists(tenantUdfResourceDir + fileName)).thenReturn(true); + when(storageOperate.getFileStatus(tenantUdfResourceDir + fileName, tenantUdfResourceDir, tenantCode, + ResourceType.UDF)) + .thenReturn(getStorageEntityUdfResource(fileName)); + result = resourcesService.updateResource(user, tenantUdfResourceDir + fileName, + tenantCode, fileName, ResourceType.UDF, null); assertEquals(Status.SUCCESS.getMsg(), result.getMsg()); } @Test - public void testQueryResourceListPaging() { + public void testQueryResourceListPaging() throws Exception { User loginUser = new User(); loginUser.setId(1); loginUser.setTenantId(1); loginUser.setTenantCode("tenant1"); loginUser.setUserType(UserType.ADMIN_USER); - List mockResList = new ArrayList(); - mockResList.add(getStorageEntityResource()); - List mockUserList = new ArrayList(); + + String fileName = "ResourcesServiceTest"; + List mockResList = new ArrayList<>(); + mockResList.add(getStorageEntityResource(fileName)); + List mockUserList = new ArrayList<>(); mockUserList.add(getUser()); when(userMapper.selectList(null)).thenReturn(mockUserList); when(userMapper.selectById(getUser().getId())).thenReturn(getUser()); when(tenantMapper.queryById(getUser().getTenantId())).thenReturn(getTenant()); - when(storageOperate.getResDir(tenantCode)).thenReturn("/dolphinscheduler/123/resources/"); + when(storageOperate.getResDir(tenantCode)).thenReturn(tenantFileResourceDir); + when(storageOperate.listFilesStatus(tenantFileResourceDir, tenantFileResourceDir, + tenantCode, ResourceType.FILE)).thenReturn(mockResList); - try { - when(storageOperate.listFilesStatus("/dolphinscheduler/123/resources/", "/dolphinscheduler/123/resources/", - tenantCode, ResourceType.FILE)).thenReturn(mockResList); - } catch (Exception e) { - logger.error("QueryResourceListPaging Error"); - } Result result = resourcesService.queryResourceListPaging(loginUser, "", "", ResourceType.FILE, "Test", 1, 10); - logger.info(result.toString()); assertEquals(Status.SUCCESS.getCode(), (int) result.getCode()); PageInfo pageInfo = (PageInfo) result.getData(); Assertions.assertTrue(CollectionUtils.isNotEmpty(pageInfo.getTotalList())); @@ -330,29 +308,30 @@ public class ResourcesServiceTest { @Test public void testQueryResourceList() { User loginUser = getUser(); + String fileName = "ResourcesServiceTest"; when(userMapper.selectList(null)).thenReturn(Collections.singletonList(loginUser)); when(userMapper.selectById(loginUser.getId())).thenReturn(loginUser); when(tenantMapper.queryById(Mockito.anyInt())).thenReturn(getTenant()); - when(storageOperate.getDir(ResourceType.ALL, tenantCode)).thenReturn("/dolphinscheduler"); - when(storageOperate.getDir(ResourceType.FILE, tenantCode)).thenReturn("/dolphinscheduler/123/resources/"); - when(storageOperate.getResDir(tenantCode)).thenReturn("/dolphinscheduler/123/resources/"); - when(storageOperate.listFilesStatusRecursively("/dolphinscheduler/123/resources/", - "/dolphinscheduler/123/resources/", tenantCode, ResourceType.FILE)) - .thenReturn(Collections.singletonList(getStorageEntityResource())); + when(storageOperate.getDir(ResourceType.ALL, tenantCode)).thenReturn(basePath); + when(storageOperate.getDir(ResourceType.FILE, tenantCode)).thenReturn(tenantFileResourceDir); + when(storageOperate.getResDir(tenantCode)).thenReturn(tenantFileResourceDir); + when(storageOperate.listFilesStatusRecursively(tenantFileResourceDir, + tenantFileResourceDir, tenantCode, ResourceType.FILE)) + .thenReturn(Collections.singletonList(getStorageEntityResource(fileName))); Map result = - resourcesService.queryResourceList(loginUser, ResourceType.FILE, "/dolphinscheduler/123/resources/"); + resourcesService.queryResourceList(loginUser, ResourceType.FILE, tenantFileResourceDir); assertEquals(Status.SUCCESS, result.get(Constants.STATUS)); List resourceList = (List) result.get(Constants.DATA_LIST); Assertions.assertTrue(CollectionUtils.isNotEmpty(resourceList)); // test udf - when(storageOperate.getDir(ResourceType.UDF, tenantCode)).thenReturn("/dolphinscheduler/123/udfs/"); - when(storageOperate.getUdfDir(tenantCode)).thenReturn("/dolphinscheduler/123/udfs/"); - when(storageOperate.listFilesStatusRecursively("/dolphinscheduler/123/udfs/", "/dolphinscheduler/123/udfs/", - tenantCode, ResourceType.UDF)).thenReturn(Arrays.asList(getStorageEntityUdfResource())); + when(storageOperate.getDir(ResourceType.UDF, tenantCode)).thenReturn(tenantUdfResourceDir); + when(storageOperate.getUdfDir(tenantCode)).thenReturn(tenantUdfResourceDir); + when(storageOperate.listFilesStatusRecursively(tenantUdfResourceDir, tenantUdfResourceDir, + tenantCode, ResourceType.UDF)).thenReturn(Arrays.asList(getStorageEntityUdfResource("test.jar"))); loginUser.setUserType(UserType.GENERAL_USER); - result = resourcesService.queryResourceList(loginUser, ResourceType.UDF, "/dolphinscheduler/123/udfs/"); + result = resourcesService.queryResourceList(loginUser, ResourceType.UDF, tenantUdfResourceDir); assertEquals(Status.SUCCESS, result.get(Constants.STATUS)); resourceList = (List) result.get(Constants.DATA_LIST); Assertions.assertTrue(CollectionUtils.isNotEmpty(resourceList)); @@ -360,7 +339,6 @@ public class ResourcesServiceTest { @Test public void testDelete() throws Exception { - User loginUser = new User(); loginUser.setId(0); loginUser.setUserType(UserType.GENERAL_USER); @@ -372,46 +350,40 @@ public class ResourcesServiceTest { Assertions.assertThrows(ServiceException.class, () -> resourcesService.delete(loginUser, "", "")); // RESOURCE_NOT_EXIST + String fileName = "ResourcesServiceTest"; when(tenantMapper.queryById(Mockito.anyInt())).thenReturn(getTenant()); - when(storageOperate.getDir(ResourceType.ALL, tenantCode)).thenReturn("/dolphinscheduler"); - when(storageOperate.getResDir(getTenant().getTenantCode())).thenReturn("/dolphinscheduler/123/resources/"); - when(storageOperate.getFileStatus("/dolphinscheduler/123/resources/ResourcesServiceTest", - "/dolphinscheduler/123/resources/", tenantCode, null)) - .thenReturn(getStorageEntityResource()); - Result result = resourcesService.delete(loginUser, "/dolphinscheduler/123/resources/ResNotExist", tenantCode); + when(storageOperate.getDir(ResourceType.ALL, tenantCode)).thenReturn(basePath); + when(storageOperate.getResDir(getTenant().getTenantCode())).thenReturn(tenantFileResourceDir); + when(storageOperate.getFileStatus(tenantFileResourceDir + fileName, tenantFileResourceDir, tenantCode, null)) + .thenReturn(getStorageEntityResource(fileName)); + Result result = resourcesService.delete(loginUser, tenantFileResourceDir + "ResNotExist", tenantCode); assertEquals(Status.RESOURCE_NOT_EXIST.getMsg(), result.getMsg()); // SUCCESS loginUser.setTenantId(1); - result = resourcesService.delete(loginUser, "/dolphinscheduler/123/resources/ResourcesServiceTest", tenantCode); + result = resourcesService.delete(loginUser, tenantFileResourceDir + fileName, tenantCode); assertEquals(Status.SUCCESS.getMsg(), result.getMsg()); } @Test - public void testVerifyResourceName() { - + public void testVerifyResourceName() throws IOException { User user = new User(); user.setId(1); user.setUserType(UserType.GENERAL_USER); - try { - when(storageOperate.exists("/ResourcesServiceTest.jar")).thenReturn(true); - } catch (IOException e) { - logger.error("error occurred when checking resource: /ResourcesServiceTest.jar\""); - } - Result result = resourcesService.verifyResourceName("/ResourcesServiceTest.jar", ResourceType.FILE, user); - logger.info(result.toString()); + + String fileName = "ResourcesServiceTest"; + when(storageOperate.exists(tenantFileResourceDir + fileName)).thenReturn(true); + + Result result = resourcesService.verifyResourceName(tenantFileResourceDir + fileName, ResourceType.FILE, user); assertEquals(Status.RESOURCE_EXIST.getMsg(), result.getMsg()); // RESOURCE_FILE_EXIST - result = resourcesService.verifyResourceName("/ResourcesServiceTest.jar", ResourceType.FILE, user); - logger.info(result.toString()); + result = resourcesService.verifyResourceName(tenantFileResourceDir + fileName, ResourceType.FILE, user); Assertions.assertTrue(Status.RESOURCE_EXIST.getCode() == result.getCode()); // SUCCESS result = resourcesService.verifyResourceName("test2", ResourceType.FILE, user); - logger.info(result.toString()); assertEquals(Status.SUCCESS.getMsg(), result.getMsg()); - } @Test @@ -441,8 +413,8 @@ public class ResourcesServiceTest { // SUCCESS when(FileUtils.getResourceViewSuffixes()).thenReturn("jar,sh"); - when(storageOperate.getDir(ResourceType.ALL, tenantCode)).thenReturn("/dolphinscheduler"); - when(storageOperate.getResDir(getTenant().getTenantCode())).thenReturn("/dolphinscheduler/123/resources/"); + when(storageOperate.getDir(ResourceType.ALL, tenantCode)).thenReturn(basePath); + when(storageOperate.getResDir(getTenant().getTenantCode())).thenReturn(tenantFileResourceDir); when(userMapper.selectById(getUser().getId())).thenReturn(getUser()); when(tenantMapper.queryById(getUser().getTenantId())).thenReturn(getTenant()); when(storageOperate.exists(Mockito.any())).thenReturn(true); @@ -465,15 +437,16 @@ public class ResourcesServiceTest { exception.getMessage().contains("Not allow create or update resources without extension name")); // SUCCESS - when(storageOperate.getResDir(user.getTenantCode())).thenReturn("/dolphinscheduler/123/resources/"); + String fileName = "ResourcesServiceTest"; + when(storageOperate.getResDir(user.getTenantCode())).thenReturn(tenantFileResourceDir); when(FileUtils.getUploadFilename(Mockito.anyString(), Mockito.anyString())).thenReturn("test"); when(FileUtils.writeContent2File(Mockito.anyString(), Mockito.anyString())).thenReturn(true); when(storageOperate.getFileStatus(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.any())) - .thenReturn(getStorageEntityResource()); + .thenReturn(getStorageEntityResource(fileName)); StorageEntity storageEntity = resourcesService.createOrUpdateResource(user.getUserName(), "filename.txt", "my-content"); Assertions.assertNotNull(storageEntity); - assertEquals("/dolphinscheduler/123/resources/ResourcesServiceTest", storageEntity.getFullName()); + assertEquals(tenantFileResourceDir + fileName, storageEntity.getFullName()); } @Test @@ -482,33 +455,35 @@ public class ResourcesServiceTest { when(userMapper.selectById(getUser().getId())).thenReturn(getUser()); when(tenantMapper.queryById(1)).thenReturn(getTenant()); when(storageOperate.getResDir(Mockito.anyString())).thenReturn("/tmp"); + + String fileName = "ResourcesServiceTest.jar"; ServiceException serviceException = Assertions.assertThrows(ServiceException.class, () -> resourcesService.updateResourceContent(getUser(), - "/dolphinscheduler/123/resources/ResourcesServiceTest.jar", tenantCode, "content")); - assertTrue(serviceException.getMessage() - .contains("Resource file: /dolphinscheduler/123/resources/ResourcesServiceTest.jar is illegal")); + tenantFileResourceDir + fileName, tenantCode, "content")); + assertEquals(new ServiceException(Status.ILLEGAL_RESOURCE_PATH, tenantFileResourceDir + fileName), + serviceException); // RESOURCE_NOT_EXIST - when(storageOperate.getDir(ResourceType.ALL, tenantCode)).thenReturn("/dolphinscheduler"); - when(storageOperate.getResDir(Mockito.anyString())).thenReturn("/dolphinscheduler/123/resources"); - when(storageOperate.getFileStatus("/dolphinscheduler/123/resources/ResourcesServiceTest.jar", "", tenantCode, - ResourceType.FILE)).thenReturn(null); - Result result = resourcesService.updateResourceContent(getUser(), - "/dolphinscheduler/123/resources/ResourcesServiceTest.jar", tenantCode, "content"); + when(storageOperate.getDir(ResourceType.ALL, tenantCode)).thenReturn(basePath); + when(storageOperate.getResDir(Mockito.anyString())).thenReturn(tenantFileResourceDir); + when(storageOperate.getFileStatus(tenantFileResourceDir + fileName, "", tenantCode, ResourceType.FILE)) + .thenReturn(null); + Result result = resourcesService.updateResourceContent(getUser(), tenantFileResourceDir + fileName, tenantCode, + "content"); assertEquals(Status.RESOURCE_NOT_EXIST.getMsg(), result.getMsg()); // RESOURCE_SUFFIX_NOT_SUPPORT_VIEW when(FileUtils.getResourceViewSuffixes()).thenReturn("class"); - when(storageOperate.getFileStatus("/dolphinscheduler/123/resources", "", tenantCode, ResourceType.FILE)) - .thenReturn(getStorageEntityResource()); + when(storageOperate.getFileStatus(tenantFileResourceDir, "", tenantCode, ResourceType.FILE)) + .thenReturn(getStorageEntityResource(fileName)); - result = resourcesService.updateResourceContent(getUser(), "/dolphinscheduler/123/resources", tenantCode, + result = resourcesService.updateResourceContent(getUser(), tenantFileResourceDir, tenantCode, "content"); assertEquals(Status.RESOURCE_SUFFIX_NOT_SUPPORT_VIEW.getMsg(), result.getMsg()); // USER_NOT_EXIST when(userMapper.selectById(getUser().getId())).thenReturn(null); - result = resourcesService.updateResourceContent(getUser(), "/dolphinscheduler/123/resources/123.class", + result = resourcesService.updateResourceContent(getUser(), tenantFileResourceDir + "123.class", tenantCode, "content"); Assertions.assertTrue(Status.USER_NOT_EXIST.getCode() == result.getCode()); @@ -517,11 +492,11 @@ public class ResourcesServiceTest { when(userMapper.selectById(getUser().getId())).thenReturn(getUser()); when(tenantMapper.queryById(1)).thenReturn(null); Assertions.assertThrows(ServiceException.class, () -> resourcesService.updateResourceContent(getUser(), - "/dolphinscheduler/123/resources/ResourcesServiceTest.jar", tenantCode, "content")); + tenantFileResourceDir + fileName, tenantCode, "content")); // SUCCESS - when(storageOperate.getFileStatus("/dolphinscheduler/123/resources/ResourcesServiceTest.jar", "", tenantCode, - ResourceType.FILE)).thenReturn(getStorageEntityResource()); + when(storageOperate.getFileStatus(tenantFileResourceDir + fileName, "", tenantCode, + ResourceType.FILE)).thenReturn(getStorageEntityResource(fileName)); when(Files.getFileExtension(Mockito.anyString())).thenReturn("jar"); when(FileUtils.getResourceViewSuffixes()).thenReturn("jar"); @@ -530,32 +505,25 @@ public class ResourcesServiceTest { when(FileUtils.getUploadFilename(Mockito.anyString(), Mockito.anyString())).thenReturn("test"); when(FileUtils.writeContent2File(Mockito.anyString(), Mockito.anyString())).thenReturn(true); result = resourcesService.updateResourceContent(getUser(), - "/dolphinscheduler/123/resources/ResourcesServiceTest.jar", tenantCode, "content"); - logger.info(result.toString()); + tenantFileResourceDir + fileName, tenantCode, "content"); assertEquals(Status.SUCCESS.getMsg(), result.getMsg()); } @Test - public void testDownloadResource() { + public void testDownloadResource() throws IOException { when(tenantMapper.queryById(1)).thenReturn(getTenant()); when(userMapper.selectById(1)).thenReturn(getUser()); org.springframework.core.io.Resource resourceMock = Mockito.mock(org.springframework.core.io.Resource.class); Path path = Mockito.mock(Path.class); when(Paths.get(Mockito.any())).thenReturn(path); - try { - when(java.nio.file.Files.size(Mockito.any())).thenReturn(1L); - // resource null - org.springframework.core.io.Resource resource = resourcesService.downloadResource(getUser(), ""); - Assertions.assertNull(resource); - - when(org.apache.dolphinscheduler.api.utils.FileUtils.file2Resource(Mockito.any())).thenReturn(resourceMock); - resource = resourcesService.downloadResource(getUser(), ""); - Assertions.assertNotNull(resource); - } catch (Exception e) { - logger.error("DownloadResource error", e); - Assertions.assertTrue(false); - } - + when(java.nio.file.Files.size(Mockito.any())).thenReturn(1L); + // resource null + org.springframework.core.io.Resource resource = resourcesService.downloadResource(getUser(), ""); + Assertions.assertNull(resource); + + when(org.apache.dolphinscheduler.api.utils.FileUtils.file2Resource(Mockito.any())).thenReturn(resourceMock); + resource = resourcesService.downloadResource(getUser(), ""); + Assertions.assertNotNull(resource); } @Test @@ -605,30 +573,21 @@ public class ResourcesServiceTest { } @Test - public void testCatFile() { + public void testCatFile() throws IOException { // SUCCESS - try { - List list = storageOperate.vimFile(Mockito.any(), Mockito.anyString(), eq(1), eq(10)); - Assertions.assertNotNull(list); - - } catch (IOException e) { - logger.error("hadoop error", e); - } + List list = storageOperate.vimFile(Mockito.any(), Mockito.anyString(), eq(1), eq(10)); + Assertions.assertNotNull(list); } @Test - void testQueryBaseDir() { + void testQueryBaseDir() throws Exception { User user = getUser(); + String fileName = "ResourcesServiceTest.jar"; when(userMapper.selectById(user.getId())).thenReturn(getUser()); when(tenantMapper.queryById(user.getTenantId())).thenReturn(getTenant()); - when(storageOperate.getDir(ResourceType.FILE, tenantCode)).thenReturn("/dolphinscheduler/123/resources/"); - try { - when(storageOperate.getFileStatus(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), - Mockito.any())).thenReturn(getStorageEntityResource()); - } catch (Exception e) { - logger.error(e.getMessage() + " Resource path: {}", "/dolphinscheduler/123/resources/ResourcesServiceTest", - e); - } + when(storageOperate.getDir(ResourceType.FILE, tenantCode)).thenReturn(tenantFileResourceDir); + when(storageOperate.getFileStatus(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), + Mockito.any())).thenReturn(getStorageEntityResource(fileName)); Result result = resourcesService.queryResourceBaseDir(user, ResourceType.FILE); assertEquals(Status.SUCCESS.getMsg(), result.getMsg()); } @@ -648,25 +607,25 @@ public class ResourcesServiceTest { return user; } - private StorageEntity getStorageEntityResource() { + private StorageEntity getStorageEntityResource(String fileName) { StorageEntity entity = new StorageEntity(); - entity.setAlias("ResourcesServiceTest"); - entity.setFileName("ResourcesServiceTest"); + entity.setAlias(fileName); + entity.setFileName(fileName); entity.setDirectory(false); entity.setUserName(tenantCode); entity.setType(ResourceType.FILE); - entity.setFullName("/dolphinscheduler/123/resources/ResourcesServiceTest"); + entity.setFullName(tenantFileResourceDir + fileName); return entity; } - private StorageEntity getStorageEntityUdfResource() { + private StorageEntity getStorageEntityUdfResource(String fileName) { StorageEntity entity = new StorageEntity(); - entity.setAlias("ResourcesServiceTest1.jar"); - entity.setFileName("ResourcesServiceTest1.jar"); + entity.setAlias(fileName); + entity.setFileName(fileName); entity.setDirectory(false); entity.setUserName(tenantCode); entity.setType(ResourceType.UDF); - entity.setFullName("/dolphinscheduler/123/resources/ResourcesServiceTest1.jar"); + entity.setFullName(tenantUdfResourceDir + fileName); return entity; }