From f3b5d1f57da54b0da8dbce630beb1cfe242aab02 Mon Sep 17 00:00:00 2001 From: xiangzihao <460888207@qq.com> Date: Mon, 18 Nov 2024 17:12:18 +0800 Subject: [PATCH] [Feature-16801][UI] Add copy path of resource file in task definition (#16803) --- .../visitor/ResourceTreeVisitor.java | 1 + .../common/constants/Constants.java | 2 - .../storage/api/AbstractStorageOperator.java | 2 +- .../plugin/storage/api/StorageEntity.java | 1 + .../plugin/storage/api/StorageOperator.java | 1 - .../storage/cos/CosStorageOperator.java | 1 + .../storage/gcs/GcsStorageOperator.java | 1 + .../storage/hdfs/HdfsStorageOperator.java | 2 +- .../hdfs/LocalStorageOperatorTest.java | 13 ++--- .../storage/obs/ObsStorageOperator.java | 1 + .../storage/oss/OssStorageOperator.java | 1 + .../plugin/storage/s3/S3StorageOperator.java | 1 + .../components/node/fields/use-resources.ts | 57 ++++++++++++++++++- 13 files changed, 70 insertions(+), 14 deletions(-) diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/resources/visitor/ResourceTreeVisitor.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/resources/visitor/ResourceTreeVisitor.java index 59ccd404f0..f7f93e780d 100644 --- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/resources/visitor/ResourceTreeVisitor.java +++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/resources/visitor/ResourceTreeVisitor.java @@ -126,6 +126,7 @@ public class ResourceTreeVisitor implements Visitor { tempResourceComponent.setName(resource.getFileName()); tempResourceComponent.setFullName(resource.getFullName()); tempResourceComponent.setType(resource.getType()); + tempResourceComponent.setCurrentDir(resource.getRelativePath()); return tempResourceComponent; } diff --git a/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/constants/Constants.java b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/constants/Constants.java index 254896a27c..cc01c45c1d 100644 --- a/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/constants/Constants.java +++ b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/constants/Constants.java @@ -43,8 +43,6 @@ public final class Constants { public static final String FORMAT_S_S_COLON = "%s:%s"; public static final String FOLDER_SEPARATOR = "/"; - public static final String RESOURCE_TYPE_FILE = "resources"; - public static final String EMPTY_STRING = ""; /** diff --git a/dolphinscheduler-storage-plugin/dolphinscheduler-storage-api/src/main/java/org/apache/dolphinscheduler/plugin/storage/api/AbstractStorageOperator.java b/dolphinscheduler-storage-plugin/dolphinscheduler-storage-api/src/main/java/org/apache/dolphinscheduler/plugin/storage/api/AbstractStorageOperator.java index 72e5867359..76a0f3096f 100644 --- a/dolphinscheduler-storage-plugin/dolphinscheduler-storage-api/src/main/java/org/apache/dolphinscheduler/plugin/storage/api/AbstractStorageOperator.java +++ b/dolphinscheduler-storage-plugin/dolphinscheduler-storage-api/src/main/java/org/apache/dolphinscheduler/plugin/storage/api/AbstractStorageOperator.java @@ -85,7 +85,7 @@ public abstract class AbstractStorageOperator implements StorageOperator { String resourceBaseDirectory; switch (resourceType) { case FILE: - resourceBaseDirectory = FileUtils.concatFilePath(tenantBaseDirectory, FILE_FOLDER_NAME); + resourceBaseDirectory = FileUtils.concatFilePath(tenantBaseDirectory, StorageOperator.FILE_FOLDER_NAME); break; case ALL: resourceBaseDirectory = tenantBaseDirectory; diff --git a/dolphinscheduler-storage-plugin/dolphinscheduler-storage-api/src/main/java/org/apache/dolphinscheduler/plugin/storage/api/StorageEntity.java b/dolphinscheduler-storage-plugin/dolphinscheduler-storage-api/src/main/java/org/apache/dolphinscheduler/plugin/storage/api/StorageEntity.java index ef9d588129..e934321b46 100644 --- a/dolphinscheduler-storage-plugin/dolphinscheduler-storage-api/src/main/java/org/apache/dolphinscheduler/plugin/storage/api/StorageEntity.java +++ b/dolphinscheduler-storage-plugin/dolphinscheduler-storage-api/src/main/java/org/apache/dolphinscheduler/plugin/storage/api/StorageEntity.java @@ -46,4 +46,5 @@ public class StorageEntity { private long size; private Date createTime; private Date updateTime; + private String relativePath; } diff --git a/dolphinscheduler-storage-plugin/dolphinscheduler-storage-api/src/main/java/org/apache/dolphinscheduler/plugin/storage/api/StorageOperator.java b/dolphinscheduler-storage-plugin/dolphinscheduler-storage-api/src/main/java/org/apache/dolphinscheduler/plugin/storage/api/StorageOperator.java index fb27bba217..b7855120f1 100644 --- a/dolphinscheduler-storage-plugin/dolphinscheduler-storage-api/src/main/java/org/apache/dolphinscheduler/plugin/storage/api/StorageOperator.java +++ b/dolphinscheduler-storage-plugin/dolphinscheduler-storage-api/src/main/java/org/apache/dolphinscheduler/plugin/storage/api/StorageOperator.java @@ -25,7 +25,6 @@ import java.util.List; public interface StorageOperator { String FILE_FOLDER_NAME = "resources"; - String UDF_FOLDER_NAME = "udfs"; ResourceMetadata getResourceMetaData(String resourceAbsolutePath); diff --git a/dolphinscheduler-storage-plugin/dolphinscheduler-storage-cos/src/main/java/org/apache/dolphinscheduler/plugin/storage/cos/CosStorageOperator.java b/dolphinscheduler-storage-plugin/dolphinscheduler-storage-cos/src/main/java/org/apache/dolphinscheduler/plugin/storage/cos/CosStorageOperator.java index a8eb50b33d..e2f605ec91 100644 --- a/dolphinscheduler-storage-plugin/dolphinscheduler-storage-cos/src/main/java/org/apache/dolphinscheduler/plugin/storage/cos/CosStorageOperator.java +++ b/dolphinscheduler-storage-plugin/dolphinscheduler-storage-cos/src/main/java/org/apache/dolphinscheduler/plugin/storage/cos/CosStorageOperator.java @@ -306,6 +306,7 @@ public class CosStorageOperator extends AbstractStorageOperator implements Close .type(resourceMetaData.getResourceType()) .isDirectory(StringUtils.isEmpty(fileExtension)) .size(metadata.getContentLength()) + .relativePath(resourceMetaData.getResourceRelativePath()) .createTime(metadata.getLastModified()) .updateTime(metadata.getLastModified()) .build(); diff --git a/dolphinscheduler-storage-plugin/dolphinscheduler-storage-gcs/src/main/java/org/apache/dolphinscheduler/plugin/storage/gcs/GcsStorageOperator.java b/dolphinscheduler-storage-plugin/dolphinscheduler-storage-gcs/src/main/java/org/apache/dolphinscheduler/plugin/storage/gcs/GcsStorageOperator.java index 45f9c8ab6f..fe85a402b8 100644 --- a/dolphinscheduler-storage-plugin/dolphinscheduler-storage-gcs/src/main/java/org/apache/dolphinscheduler/plugin/storage/gcs/GcsStorageOperator.java +++ b/dolphinscheduler-storage-plugin/dolphinscheduler-storage-gcs/src/main/java/org/apache/dolphinscheduler/plugin/storage/gcs/GcsStorageOperator.java @@ -273,6 +273,7 @@ public class GcsStorageOperator extends AbstractStorageOperator implements Close entity.setDirectory(resourceMetaData.isDirectory()); entity.setType(resourceMetaData.getResourceType()); entity.setSize(blob.getSize()); + entity.setRelativePath(resourceMetaData.getResourceRelativePath()); entity.setCreateTime(Date.from(blob.getCreateTimeOffsetDateTime().toInstant())); entity.setUpdateTime(Date.from(blob.getUpdateTimeOffsetDateTime().toInstant())); return entity; diff --git a/dolphinscheduler-storage-plugin/dolphinscheduler-storage-hdfs/src/main/java/org/apache/dolphinscheduler/plugin/storage/hdfs/HdfsStorageOperator.java b/dolphinscheduler-storage-plugin/dolphinscheduler-storage-hdfs/src/main/java/org/apache/dolphinscheduler/plugin/storage/hdfs/HdfsStorageOperator.java index 0d21b769a9..3a1092077b 100644 --- a/dolphinscheduler-storage-plugin/dolphinscheduler-storage-hdfs/src/main/java/org/apache/dolphinscheduler/plugin/storage/hdfs/HdfsStorageOperator.java +++ b/dolphinscheduler-storage-plugin/dolphinscheduler-storage-hdfs/src/main/java/org/apache/dolphinscheduler/plugin/storage/hdfs/HdfsStorageOperator.java @@ -268,7 +268,6 @@ public class HdfsStorageOperator extends AbstractStorageOperator implements Clos Path fileStatusPath = fileStatus.getPath(); String fileAbsolutePath = fileStatusPath.toString(); ResourceMetadata resourceMetaData = getResourceMetaData(fileAbsolutePath); - return StorageEntity.builder() .fileName(fileStatusPath.getName()) .fullName(fileAbsolutePath) @@ -276,6 +275,7 @@ public class HdfsStorageOperator extends AbstractStorageOperator implements Clos .type(resourceMetaData.getResourceType()) .isDirectory(fileStatus.isDirectory()) .size(fileStatus.getLen()) + .relativePath(resourceMetaData.getResourceRelativePath()) .createTime(new Date(fileStatus.getModificationTime())) .updateTime(new Date(fileStatus.getModificationTime())) .build(); diff --git a/dolphinscheduler-storage-plugin/dolphinscheduler-storage-hdfs/src/test/java/org/apache/dolphinscheduler/plugin/storage/hdfs/LocalStorageOperatorTest.java b/dolphinscheduler-storage-plugin/dolphinscheduler-storage-hdfs/src/test/java/org/apache/dolphinscheduler/plugin/storage/hdfs/LocalStorageOperatorTest.java index 5730f46dbd..899f17873a 100644 --- a/dolphinscheduler-storage-plugin/dolphinscheduler-storage-hdfs/src/test/java/org/apache/dolphinscheduler/plugin/storage/hdfs/LocalStorageOperatorTest.java +++ b/dolphinscheduler-storage-plugin/dolphinscheduler-storage-hdfs/src/test/java/org/apache/dolphinscheduler/plugin/storage/hdfs/LocalStorageOperatorTest.java @@ -20,7 +20,6 @@ package org.apache.dolphinscheduler.plugin.storage.hdfs; import static com.google.common.truth.Truth.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; -import org.apache.dolphinscheduler.common.constants.Constants; import org.apache.dolphinscheduler.common.utils.FileUtils; import org.apache.dolphinscheduler.plugin.storage.api.ResourceMetadata; import org.apache.dolphinscheduler.plugin.storage.api.StorageEntity; @@ -47,7 +46,7 @@ class LocalStorageOperatorTest { Paths.get(LocalStorageOperatorTest.class.getResource("/").getFile(), "localStorage").toString(); private static final String tenantCode = "default"; private static final String baseDir = - Paths.get(resourceBaseDir, tenantCode, StorageConstants.RESOURCE_TYPE_FILE).toString(); + Paths.get(resourceBaseDir, tenantCode, StorageOperator.FILE_FOLDER_NAME).toString(); @SneakyThrows @BeforeEach @@ -116,7 +115,7 @@ class LocalStorageOperatorTest { public void testGetStorageBaseDirectory_withTenant_withResourceTypeFile() { String storageBaseDirectory = storageOperator.getStorageBaseDirectory("default", ResourceType.FILE); assertThat(storageBaseDirectory) - .isEqualTo("file:" + Paths.get(resourceBaseDir, tenantCode, Constants.RESOURCE_TYPE_FILE)); + .isEqualTo("file:" + Paths.get(resourceBaseDir, tenantCode, StorageOperator.FILE_FOLDER_NAME)); } @Test @@ -143,21 +142,21 @@ class LocalStorageOperatorTest { public void testGetStorageFileAbsolutePath() { String fileAbsolutePath = storageOperator.getStorageFileAbsolutePath("default", "test.sh"); assertThat(fileAbsolutePath).isEqualTo( - "file:" + Paths.get(resourceBaseDir, tenantCode, Constants.RESOURCE_TYPE_FILE, "test.sh")); + "file:" + Paths.get(resourceBaseDir, tenantCode, StorageOperator.FILE_FOLDER_NAME, "test.sh")); } @SneakyThrows @Test public void testCreateStorageDir_notExists() { String testDirFileAbsolutePath = - "file:" + Paths.get(resourceBaseDir, "root", Constants.RESOURCE_TYPE_FILE, "testDir"); + "file:" + Paths.get(resourceBaseDir, "root", StorageOperator.FILE_FOLDER_NAME, "testDir"); try { storageOperator.createStorageDir(testDirFileAbsolutePath); StorageEntity storageEntity = storageOperator.getStorageEntity(testDirFileAbsolutePath); assertThat(storageEntity.getFullName()).isEqualTo(testDirFileAbsolutePath); assertThat(storageEntity.getFileName()).isEqualTo("testDir"); assertThat(storageEntity.getPfullName()) - .isEqualTo("file:" + Paths.get(resourceBaseDir, "root", Constants.RESOURCE_TYPE_FILE)); + .isEqualTo("file:" + Paths.get(resourceBaseDir, "root", StorageOperator.FILE_FOLDER_NAME)); assertThat(storageEntity.isDirectory()).isTrue(); assertThat(storageEntity.getType()).isEqualTo(ResourceType.FILE); } finally { @@ -169,7 +168,7 @@ class LocalStorageOperatorTest { @Test public void testCreateStorageDir_exists() { String testDirFileAbsolutePath = - "file:" + Paths.get(resourceBaseDir, "default", Constants.RESOURCE_TYPE_FILE, "sqlDirectory"); + "file:" + Paths.get(resourceBaseDir, "default", StorageOperator.FILE_FOLDER_NAME, "sqlDirectory"); assertThrows(FileAlreadyExistsException.class, () -> storageOperator.createStorageDir(testDirFileAbsolutePath)); } diff --git a/dolphinscheduler-storage-plugin/dolphinscheduler-storage-obs/src/main/java/org/apache/dolphinscheduler/plugin/storage/obs/ObsStorageOperator.java b/dolphinscheduler-storage-plugin/dolphinscheduler-storage-obs/src/main/java/org/apache/dolphinscheduler/plugin/storage/obs/ObsStorageOperator.java index 1f32cb34af..129b9a8828 100644 --- a/dolphinscheduler-storage-plugin/dolphinscheduler-storage-obs/src/main/java/org/apache/dolphinscheduler/plugin/storage/obs/ObsStorageOperator.java +++ b/dolphinscheduler-storage-plugin/dolphinscheduler-storage-obs/src/main/java/org/apache/dolphinscheduler/plugin/storage/obs/ObsStorageOperator.java @@ -260,6 +260,7 @@ public class ObsStorageOperator extends AbstractStorageOperator implements Close .type(resourceMetaData.getResourceType()) .isDirectory(StringUtils.isEmpty(fileExtension)) .size(metadata.getContentLength()) + .relativePath(resourceMetaData.getResourceRelativePath()) .createTime(metadata.getLastModified()) .updateTime(metadata.getLastModified()) .build(); diff --git a/dolphinscheduler-storage-plugin/dolphinscheduler-storage-oss/src/main/java/org/apache/dolphinscheduler/plugin/storage/oss/OssStorageOperator.java b/dolphinscheduler-storage-plugin/dolphinscheduler-storage-oss/src/main/java/org/apache/dolphinscheduler/plugin/storage/oss/OssStorageOperator.java index 4b142466ce..0b78ce49b4 100644 --- a/dolphinscheduler-storage-plugin/dolphinscheduler-storage-oss/src/main/java/org/apache/dolphinscheduler/plugin/storage/oss/OssStorageOperator.java +++ b/dolphinscheduler-storage-plugin/dolphinscheduler-storage-oss/src/main/java/org/apache/dolphinscheduler/plugin/storage/oss/OssStorageOperator.java @@ -331,6 +331,7 @@ public class OssStorageOperator extends AbstractStorageOperator implements Close storageEntity.setType(resourceMetaData.getResourceType()); storageEntity.setDirectory(resourceMetaData.isDirectory()); storageEntity.setSize(ossObject.getObjectMetadata().getContentLength()); + storageEntity.setRelativePath(resourceMetaData.getResourceRelativePath()); storageEntity.setCreateTime(ossObject.getObjectMetadata().getLastModified()); storageEntity.setUpdateTime(ossObject.getObjectMetadata().getLastModified()); return storageEntity; diff --git a/dolphinscheduler-storage-plugin/dolphinscheduler-storage-s3/src/main/java/org/apache/dolphinscheduler/plugin/storage/s3/S3StorageOperator.java b/dolphinscheduler-storage-plugin/dolphinscheduler-storage-s3/src/main/java/org/apache/dolphinscheduler/plugin/storage/s3/S3StorageOperator.java index 2bd479de63..d1836d7c94 100644 --- a/dolphinscheduler-storage-plugin/dolphinscheduler-storage-s3/src/main/java/org/apache/dolphinscheduler/plugin/storage/s3/S3StorageOperator.java +++ b/dolphinscheduler-storage-plugin/dolphinscheduler-storage-s3/src/main/java/org/apache/dolphinscheduler/plugin/storage/s3/S3StorageOperator.java @@ -294,6 +294,7 @@ public class S3StorageOperator extends AbstractStorageOperator implements Closea entity.setDirectory(resourceMetaData.isDirectory()); entity.setType(resourceMetaData.getResourceType()); entity.setSize(object.getObjectMetadata().getContentLength()); + entity.setRelativePath(resourceMetaData.getResourceRelativePath()); entity.setCreateTime(object.getObjectMetadata().getLastModified()); entity.setUpdateTime(object.getObjectMetadata().getLastModified()); return entity; diff --git a/dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-resources.ts b/dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-resources.ts index f9fa187314..ae9020534a 100644 --- a/dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-resources.ts +++ b/dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-resources.ts @@ -15,12 +15,15 @@ * limitations under the License. */ -import { ref, onMounted, Ref, isRef } from 'vue' +import { ref, onMounted, Ref, isRef, h } from 'vue' import { useI18n } from 'vue-i18n' import { queryResourceList } from '@/service/modules/resources' import { useTaskNodeStore } from '@/store/project/task-node' import utils from '@/utils' import type { IJsonItem, IResource } from '../types' +import { NButton, NIcon, NTag } from 'naive-ui' +import { CopyOutlined } from '@vicons/antd' +import { useClipboard } from '@vueuse/core' export function useResources( span: number | Ref = 24, @@ -42,6 +45,9 @@ export function useResources( const taskStore = useTaskNodeStore() + const source = ref('Hello') + const { copy, isSupported } = useClipboard({ source }) + const getResources = async () => { if (taskStore.resources.length) { resourcesOptions.value = taskStore.resources @@ -116,6 +122,16 @@ export function useResources( } } + const copyResourceName = async (name: string) => { + if (isSupported.value) { + event?.stopPropagation() + await copy(name) + window.$message.success(t('project.node.copy_success')) + } else { + window.$message.error(t('project.node.copy_failed')) + } + } + onMounted(() => { getResources() }) @@ -139,7 +155,44 @@ export function useResources( keyField: 'fullName', labelField: 'name', disabledField: 'disable', - loading: resourcesLoading + loading: resourcesLoading, + 'render-tag': ({ + option, + handleClose + }: { + option: any + handleClose: any + }) => { + return h( + NTag, + { + type: 'success', + closable: true, + onClose: () => { + handleClose() + } + }, + { + default: () => option.currentDir, + avatar: () => + h( + NButton, + { + tag: 'div', + type: 'info', + size: 'tiny', + onClick: () => copyResourceName(option.currentDir) + }, + { + icon: () => + h(NIcon, null, { + default: () => h(CopyOutlined) + }) + } + ) + } + ) + } }, validate: { trigger: ['blur'],