This is an automated email from the ASF dual-hosted git repository.
zhoujinsong pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/amoro.git
The following commit(s) were added to refs/heads/master by this push:
new 4ed2e91e3 [AMORO-4236] Splitting the “Optimizing” tab into the
“Optimizing” tab,“Cleanup” tab and “Profiling” tab (#4238)
4ed2e91e3 is described below
commit 4ed2e91e3f70f3f3c0f8ca2b0cda5e187608041e
Author: WenLingzhang <[email protected]>
AuthorDate: Tue Jun 9 17:04:59 2026 +0800
[AMORO-4236] Splitting the “Optimizing” tab into the “Optimizing”
tab,“Cleanup” tab and “Profiling” tab (#4238)
* Add Maintenance tab for table process management
* fix optimizing types in PaimonTableDescriptor
* Refactor OPTIMIZING tab from OPTIMIZING to OPTIMIZING/CLEANUP/PROFILING
tab
* Replace static resolveCategoryTypes/matchProcessCategory with instance
method getProcessTypesByCategory, moving routing logic into each descriptor.
* fixup style
---------
Co-authored-by: 张文领 <[email protected]>
---
.../amoro/server/dashboard/DashboardServer.java | 4 +-
.../dashboard/MixedAndIcebergTableDescriptor.java | 88 +++++++++++++++-
.../server/dashboard/ServerTableDescriptor.java | 14 ++-
.../dashboard/controller/TableController.java | 25 ++++-
.../persistence/mapper/TableProcessMapper.java | 2 +
.../TestIcebergServerTableDescriptor.java | 117 ++++++++++++++++++++-
.../server/optimizing/BaseOptimizingChecker.java | 6 +-
.../inline/TestProcessDataExpiringExecutor.java | 3 +-
.../table/descriptor/FormatTableDescriptor.java | 21 +++-
.../amoro/table/descriptor/ProcessCategory.java | 55 ++++++++++
.../amoro/formats/hudi/HudiTableDescriptor.java | 25 ++++-
.../formats/paimon/PaimonTableDescriptor.java | 34 +++++-
amoro-web/mock/modules/table.js | 33 ++++--
amoro-web/src/language/en.ts | 5 +
amoro-web/src/language/zh.ts | 5 +
amoro-web/src/services/table.service.ts | 14 +--
amoro-web/src/views/tables/components/Cleanup.vue | 26 +++++
.../src/views/tables/components/Optimizing.vue | 41 +++++---
.../src/views/tables/components/Profiling.vue | 26 +++++
amoro-web/src/views/tables/index.vue | 6 ++
20 files changed, 493 insertions(+), 57 deletions(-)
diff --git
a/amoro-ams/src/main/java/org/apache/amoro/server/dashboard/DashboardServer.java
b/amoro-ams/src/main/java/org/apache/amoro/server/dashboard/DashboardServer.java
index 2246cf68b..f6e1ab29d 100644
---
a/amoro-ams/src/main/java/org/apache/amoro/server/dashboard/DashboardServer.java
+++
b/amoro-ams/src/main/java/org/apache/amoro/server/dashboard/DashboardServer.java
@@ -268,8 +268,8 @@ public class DashboardServer {
"/catalogs/{catalog}/dbs/{db}/tables/{table}/optimizing-processes",
tableController::getOptimizingProcesses);
get(
- "/catalogs/{catalog}/dbs/{db}/tables/{table}/optimizing-types",
- tableController::getOptimizingTypes);
+ "/catalogs/{catalog}/dbs/{db}/tables/{table}/process-types",
+ tableController::getProcessTypes);
get(
"/catalogs/{catalog}/dbs/{db}/tables/{table}/optimizing-processes/{processId}/tasks",
tableController::getOptimizingProcessTasks);
diff --git
a/amoro-ams/src/main/java/org/apache/amoro/server/dashboard/MixedAndIcebergTableDescriptor.java
b/amoro-ams/src/main/java/org/apache/amoro/server/dashboard/MixedAndIcebergTableDescriptor.java
index 7f3a49d0c..f6c1dd8d3 100644
---
a/amoro-ams/src/main/java/org/apache/amoro/server/dashboard/MixedAndIcebergTableDescriptor.java
+++
b/amoro-ams/src/main/java/org/apache/amoro/server/dashboard/MixedAndIcebergTableDescriptor.java
@@ -22,6 +22,7 @@ import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.amoro.AmoroTable;
+import org.apache.amoro.IcebergActions;
import org.apache.amoro.ServerTableIdentifier;
import org.apache.amoro.TableFormat;
import org.apache.amoro.api.CommitMetaProducer;
@@ -67,12 +68,14 @@ import
org.apache.amoro.table.descriptor.OptimizingProcessInfo;
import org.apache.amoro.table.descriptor.OptimizingTaskInfo;
import org.apache.amoro.table.descriptor.PartitionBaseInfo;
import org.apache.amoro.table.descriptor.PartitionFileBaseInfo;
+import org.apache.amoro.table.descriptor.ProcessCategory;
import org.apache.amoro.table.descriptor.ServerTableMeta;
import org.apache.amoro.table.descriptor.TableSummary;
import org.apache.amoro.table.descriptor.TagOrBranchInfo;
import org.apache.amoro.utils.MixedDataFiles;
import org.apache.amoro.utils.MixedTableUtil;
import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.iceberg.ContentFile;
import org.apache.iceberg.FileScanTask;
@@ -118,6 +121,19 @@ public class MixedAndIcebergTableDescriptor extends
PersistentBase
private static final Logger LOG =
LoggerFactory.getLogger(MixedAndIcebergTableDescriptor.class);
+ private static final List<String> OPTIMIZING_TYPE_LIST =
+
Arrays.stream(OptimizingType.values()).map(Enum::name).collect(Collectors.toList());
+
+ private static final List<String> CLEANUP_TYPE_LIST =
+ ImmutableList.of(
+ IcebergActions.EXPIRE_SNAPSHOTS.getName(),
+ IcebergActions.CLEAN_ORPHAN.getName(),
+ IcebergActions.CLEAN_DANGLING_DELETE.getName(),
+ IcebergActions.EXPIRE_DATA.getName());
+
+ private static final List<String> PROFILING_TYPE_LIST =
+ ImmutableList.of(IcebergActions.AUTO_CREATE_TAGS.getName());
+
private ExecutorService executorService;
@Override
@@ -655,7 +671,12 @@ public class MixedAndIcebergTableDescriptor extends
PersistentBase
@Override
public Pair<List<OptimizingProcessInfo>, Integer> getOptimizingProcessesInfo(
- AmoroTable<?> amoroTable, String type, ProcessStatus status, int limit,
int offset) {
+ AmoroTable<?> amoroTable,
+ String type,
+ String processCategory,
+ ProcessStatus status,
+ int limit,
+ int offset) {
TableIdentifier tableIdentifier = amoroTable.id();
ServerTableIdentifier identifier =
getAs(
@@ -671,12 +692,33 @@ public class MixedAndIcebergTableDescriptor extends
PersistentBase
int total = 0;
// page helper is 1-based
int pageNumber = (offset / limit) + 1;
+
+ // Only apply category filtering when type is not specified
+ final List<String> includeTypes;
+
+ if (StringUtils.isBlank(type)) {
+ if (processCategory == null) {
+ // No category specified: return empty results
+ return Pair.of(Collections.emptyList(), 0);
+ } else {
+ List<String> categoryTypes =
getProcessTypesByCategory(processCategory);
+ if (categoryTypes.isEmpty()) {
+ // Unknown category: return empty results to avoid exposing all
processes
+ return Pair.of(Collections.emptyList(), 0);
+ }
+
+ includeTypes = categoryTypes;
+ }
+ } else {
+ includeTypes = null;
+ }
+
List<TableProcessMeta> processMetaList = Collections.emptyList();
try (Page<?> ignored = PageHelper.startPage(pageNumber, limit, true)) {
processMetaList =
getAs(
TableProcessMapper.class,
- mapper -> mapper.listProcessMeta(identifier.getId(), type,
status));
+ mapper -> mapper.listProcessMeta(identifier.getId(), type,
includeTypes, status));
PageInfo<TableProcessMeta> pageInfo = new PageInfo<>(processMetaList);
total = (int) pageInfo.getTotal();
LOG.info(
@@ -716,6 +758,48 @@ public class MixedAndIcebergTableDescriptor extends
PersistentBase
return types;
}
+ @Override
+ public Map<String, String> getTableProcessTypes(
+ AmoroTable<?> amoroTable, String processCategory) {
+ if
(ProcessCategory.OPTIMIZING.getName().equalsIgnoreCase(processCategory)) {
+ return getTableOptimizingTypes(amoroTable);
+ }
+
+ if (ProcessCategory.CLEANUP.getName().equalsIgnoreCase(processCategory)) {
+ Map<String, String> types = Maps.newHashMap();
+ types.put(IcebergActions.EXPIRE_SNAPSHOTS.getName(), "Expire Snapshots");
+ types.put(IcebergActions.CLEAN_ORPHAN.getName(), "Clean Orphan Files");
+ types.put(IcebergActions.CLEAN_DANGLING_DELETE.getName(), "Clean
Dangling Delete Files");
+ types.put(IcebergActions.EXPIRE_DATA.getName(), "Expire Data");
+ return types;
+ }
+
+ if (ProcessCategory.PROFILING.getName().equalsIgnoreCase(processCategory))
{
+ Map<String, String> types = Maps.newHashMap();
+ types.put(IcebergActions.AUTO_CREATE_TAGS.getName(), "Auto Create Tags");
+ return types;
+ }
+
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public List<String> getProcessTypesByCategory(String processCategory) {
+ if
(ProcessCategory.OPTIMIZING.getName().equalsIgnoreCase(processCategory)) {
+ return OPTIMIZING_TYPE_LIST;
+ }
+
+ if (ProcessCategory.CLEANUP.getName().equalsIgnoreCase(processCategory)) {
+ return CLEANUP_TYPE_LIST;
+ }
+
+ if (ProcessCategory.PROFILING.getName().equalsIgnoreCase(processCategory))
{
+ return PROFILING_TYPE_LIST;
+ }
+
+ return Collections.emptyList();
+ }
+
@Override
public List<OptimizingTaskInfo> getOptimizingTaskInfos(
AmoroTable<?> amoroTable, String processId) {
diff --git
a/amoro-ams/src/main/java/org/apache/amoro/server/dashboard/ServerTableDescriptor.java
b/amoro-ams/src/main/java/org/apache/amoro/server/dashboard/ServerTableDescriptor.java
index 4e2b1aef8..bbd68bf69 100644
---
a/amoro-ams/src/main/java/org/apache/amoro/server/dashboard/ServerTableDescriptor.java
+++
b/amoro-ams/src/main/java/org/apache/amoro/server/dashboard/ServerTableDescriptor.java
@@ -129,11 +129,16 @@ public class ServerTableDescriptor extends PersistentBase
{
}
public Pair<List<OptimizingProcessInfo>, Integer> getOptimizingProcessesInfo(
- TableIdentifier tableIdentifier, String type, ProcessStatus status, int
limit, int offset) {
+ TableIdentifier tableIdentifier,
+ String type,
+ String processCategory,
+ ProcessStatus status,
+ int limit,
+ int offset) {
AmoroTable<?> amoroTable = loadTable(tableIdentifier);
FormatTableDescriptor formatTableDescriptor =
formatDescriptorMap.get(amoroTable.format());
return formatTableDescriptor.getOptimizingProcessesInfo(
- amoroTable, type, status, limit, offset);
+ amoroTable, type, processCategory, status, limit, offset);
}
public List<OptimizingTaskInfo> getOptimizingProcessTaskInfos(
@@ -143,10 +148,11 @@ public class ServerTableDescriptor extends PersistentBase
{
return formatTableDescriptor.getOptimizingTaskInfos(amoroTable, processId);
}
- public Map<String, String> getTableOptimizingTypes(TableIdentifier
tableIdentifier) {
+ public Map<String, String> getTableProcessTypes(
+ TableIdentifier tableIdentifier, String processCategory) {
AmoroTable<?> amoroTable = loadTable(tableIdentifier);
FormatTableDescriptor formatTableDescriptor =
formatDescriptorMap.get(amoroTable.format());
- return formatTableDescriptor.getTableOptimizingTypes(amoroTable);
+ return formatTableDescriptor.getTableProcessTypes(amoroTable,
processCategory);
}
private AmoroTable<?> loadTable(TableIdentifier identifier) {
diff --git
a/amoro-ams/src/main/java/org/apache/amoro/server/dashboard/controller/TableController.java
b/amoro-ams/src/main/java/org/apache/amoro/server/dashboard/controller/TableController.java
index 8b4acba44..81d29a425 100644
---
a/amoro-ams/src/main/java/org/apache/amoro/server/dashboard/controller/TableController.java
+++
b/amoro-ams/src/main/java/org/apache/amoro/server/dashboard/controller/TableController.java
@@ -71,6 +71,7 @@ import
org.apache.amoro.table.descriptor.OptimizingProcessInfo;
import org.apache.amoro.table.descriptor.OptimizingTaskInfo;
import org.apache.amoro.table.descriptor.PartitionBaseInfo;
import org.apache.amoro.table.descriptor.PartitionFileBaseInfo;
+import org.apache.amoro.table.descriptor.ProcessCategory;
import org.apache.amoro.table.descriptor.ServerTableMeta;
import org.apache.amoro.table.descriptor.TableSummary;
import org.apache.amoro.table.descriptor.TagOrBranchInfo;
@@ -332,6 +333,11 @@ public class TableController {
type = null;
}
+ String processCategory = ctx.queryParam("processCategory");
+ if (StringUtils.isBlank(processCategory)) {
+ processCategory = null;
+ }
+
String status = ctx.queryParam("status");
Integer page = ctx.queryParamAsClass("page",
Integer.class).getOrDefault(1);
Integer pageSize = ctx.queryParamAsClass("pageSize",
Integer.class).getOrDefault(20);
@@ -346,21 +352,32 @@ public class TableController {
StringUtils.isBlank(status) ? null : ProcessStatus.valueOf(status);
Pair<List<OptimizingProcessInfo>, Integer> optimizingProcessesInfo =
tableDescriptor.getOptimizingProcessesInfo(
- tableIdentifier.buildTableIdentifier(), type, processStatus,
limit, offset);
+ tableIdentifier.buildTableIdentifier(),
+ type,
+ processCategory,
+ processStatus,
+ limit,
+ offset);
List<OptimizingProcessInfo> result = optimizingProcessesInfo.getLeft();
int total = optimizingProcessesInfo.getRight();
ctx.json(OkResponse.of(PageResult.of(result, total)));
}
- public void getOptimizingTypes(Context ctx) {
+ public void getProcessTypes(Context ctx) {
String catalog = ctx.pathParam("catalog");
String db = ctx.pathParam("db");
String table = ctx.pathParam("table");
+ String processCategory =
+ ctx.queryParamAsClass("processCategory",
String.class).getOrDefault(null);
+ if (StringUtils.isBlank(processCategory)) {
+ processCategory = ProcessCategory.OPTIMIZING.getName();
+ }
TableIdentifier tableIdentifier = TableIdentifier.of(catalog, db, table);
Map<String, String> values =
-
tableDescriptor.getTableOptimizingTypes(tableIdentifier.buildTableIdentifier());
+ tableDescriptor.getTableProcessTypes(
+ tableIdentifier.buildTableIdentifier(), processCategory);
ctx.json(OkResponse.of(values));
}
@@ -671,7 +688,7 @@ public class TableController {
}
/**
- * cancel the running optimizing process of one certain table.
+ * Cancel the running process of one certain table.
*
* @param ctx - context for handling the request and response
*/
diff --git
a/amoro-ams/src/main/java/org/apache/amoro/server/persistence/mapper/TableProcessMapper.java
b/amoro-ams/src/main/java/org/apache/amoro/server/persistence/mapper/TableProcessMapper.java
index bbf4019c7..ba21e01ff 100644
---
a/amoro-ams/src/main/java/org/apache/amoro/server/persistence/mapper/TableProcessMapper.java
+++
b/amoro-ams/src/main/java/org/apache/amoro/server/persistence/mapper/TableProcessMapper.java
@@ -131,6 +131,7 @@ public interface TableProcessMapper {
+ "create_time, finish_time, fail_message, process_parameters,
summary "
+ "FROM table_process WHERE table_id = #{tableId} "
+ " <if test='processType != null'> AND process_type =
#{processType}</if>"
+ + " <if test='processType == null and includeTypes != null and
includeTypes.size() > 0'> AND process_type IN <foreach
collection='includeTypes' item='type' open='(' separator=','
close=')'>#{type}</foreach></if>"
+ " <if test='status != null'> AND status = #{status}</if>"
+ " ORDER BY process_id desc"
+ "</script>")
@@ -138,6 +139,7 @@ public interface TableProcessMapper {
List<TableProcessMeta> listProcessMeta(
@Param("tableId") long tableId,
@Param("processType") String processType,
+ @Param("includeTypes") List<String> includeTypes,
@Param("status") ProcessStatus optimizingStatus);
@Select(
diff --git
a/amoro-ams/src/test/java/org/apache/amoro/server/dashboard/TestIcebergServerTableDescriptor.java
b/amoro-ams/src/test/java/org/apache/amoro/server/dashboard/TestIcebergServerTableDescriptor.java
index 4b9d6b296..cf2a856fe 100644
---
a/amoro-ams/src/test/java/org/apache/amoro/server/dashboard/TestIcebergServerTableDescriptor.java
+++
b/amoro-ams/src/test/java/org/apache/amoro/server/dashboard/TestIcebergServerTableDescriptor.java
@@ -21,7 +21,9 @@ package org.apache.amoro.server.dashboard;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
+import org.apache.amoro.Action;
import org.apache.amoro.AmoroTable;
+import org.apache.amoro.IcebergActions;
import org.apache.amoro.ServerTableIdentifier;
import org.apache.amoro.TableFormat;
import org.apache.amoro.formats.AmoroCatalogTestHelper;
@@ -301,21 +303,25 @@ public class TestIcebergServerTableDescriptor extends
TestServerTableDescriptor
doReturn(tableIdentifier).when(table).id();
Pair<List<OptimizingProcessInfo>, Integer> res =
- descriptor.getOptimizingProcessesInfo(table, null, null, 4, 4);
+ descriptor.getOptimizingProcessesInfo(table, null, "OPTIMIZING", null,
4, 4);
Integer expectReturnItemSizeForNoTypeNoStatusOffset0Limit5 = 4;
Integer expectTotalForNoTypeNoStatusOffset0Limit5 = 10;
Assert.assertEquals(
expectReturnItemSizeForNoTypeNoStatusOffset0Limit5, (Integer)
res.getLeft().size());
Assert.assertEquals(expectTotalForNoTypeNoStatusOffset0Limit5,
res.getRight());
- res = descriptor.getOptimizingProcessesInfo(table, null,
ProcessStatus.SUCCESS, 5, 0);
+ res =
+ descriptor.getOptimizingProcessesInfo(
+ table, null, "OPTIMIZING", ProcessStatus.SUCCESS, 5, 0);
Integer expectReturnItemSizeForOnlyStatusOffset0limit5 = 5;
Integer expectedTotalForOnlyStatusOffset0Limit5 = 7;
Assert.assertEquals(
expectReturnItemSizeForOnlyStatusOffset0limit5, (Integer)
res.getLeft().size());
Assert.assertEquals(expectedTotalForOnlyStatusOffset0Limit5,
res.getRight());
- res = descriptor.getOptimizingProcessesInfo(table,
OptimizingType.MINOR.name(), null, 5, 0);
+ res =
+ descriptor.getOptimizingProcessesInfo(
+ table, OptimizingType.MINOR.name(), "OPTIMIZING", null, 5, 0);
Integer expectedRetItemsSizeForOnlyTypeOffset0Limit5 = 4;
Integer expectedRetTotalForOnlyTypeOffset0Limit5 = 4;
Assert.assertEquals(
@@ -324,7 +330,7 @@ public class TestIcebergServerTableDescriptor extends
TestServerTableDescriptor
res =
descriptor.getOptimizingProcessesInfo(
- table, OptimizingType.MINOR.name(), ProcessStatus.SUCCESS, 2, 2);
+ table, OptimizingType.MINOR.name(), "OPTIMIZING",
ProcessStatus.SUCCESS, 2, 2);
Integer expectedRetItemSizeForBothTypeAndStatusOffset2Limit2 = 2;
Integer expectedRetTotalForBothTypeAndStatusOffset2Limit2 = 4;
Assert.assertEquals(
@@ -332,6 +338,85 @@ public class TestIcebergServerTableDescriptor extends
TestServerTableDescriptor
Assert.assertEquals(expectedRetTotalForBothTypeAndStatusOffset2Limit2,
res.getRight());
}
+ @Test
+ public void testProcessCategoryFiltering() {
+ TestMixedAndIcebergTableDescriptor descriptor = new
TestMixedAndIcebergTableDescriptor();
+
+ String catalogName = "catalog1";
+ String dbName = "db1";
+ String tableName = "table1";
+
+ ServerTableIdentifier identifier =
+ ServerTableIdentifier.of(1L, catalogName, dbName, tableName,
TableFormat.ICEBERG);
+ descriptor.insertTable(identifier);
+ MetricsSummary dummySummary = new MetricsSummary();
+ dummySummary.setNewDeleteFileCnt(1);
+ dummySummary.setNewDataFileCnt(1);
+ dummySummary.setNewDataSize(1);
+ dummySummary.setNewDeleteSize(1);
+
+ // Insert OPTIMIZING processes: MAJOR, MINOR
+ descriptor.insertOptimizingProcess(
+ identifier,
+ 1L,
+ 1,
+ 1,
+ ProcessStatus.SUCCESS,
+ OptimizingType.MAJOR,
+ 1L,
+ dummySummary,
+ Collections.emptyMap(),
+ Collections.emptyMap());
+ descriptor.insertOptimizingProcess(
+ identifier,
+ 2L,
+ 2L,
+ 2L,
+ ProcessStatus.SUCCESS,
+ OptimizingType.MINOR,
+ 2L,
+ dummySummary,
+ Collections.emptyMap(),
+ Collections.emptyMap());
+
+ // Insert CLEANUP processes: EXPIRE_SNAPSHOTS, CLEAN_ORPHAN
+ descriptor.insertIcebergActionProcess(
+ identifier, 3L, ProcessStatus.SUCCESS,
IcebergActions.EXPIRE_SNAPSHOTS, 3L, dummySummary);
+ descriptor.insertIcebergActionProcess(
+ identifier, 4L, ProcessStatus.SUCCESS, IcebergActions.CLEAN_ORPHAN,
4L, dummySummary);
+
+ // Insert PROFILING process: AUTO_CREATE_TAGS
+ descriptor.insertIcebergActionProcess(
+ identifier, 5L, ProcessStatus.SUCCESS,
IcebergActions.AUTO_CREATE_TAGS, 5L, dummySummary);
+
+ AmoroTable<?> table = mock(IcebergTable.class);
+ TableIdentifier tableIdentifier =
+ TableIdentifier.of(
+ identifier.getCatalog(), identifier.getDatabase(),
identifier.getTableName());
+ doReturn(tableIdentifier).when(table).id();
+
+ // Test OPTIMIZING category: should return only MAJOR and MINOR
+ Pair<List<OptimizingProcessInfo>, Integer> res =
+ descriptor.getOptimizingProcessesInfo(table, null, "OPTIMIZING", null,
10, 0);
+ Assert.assertEquals(2, (int) res.getRight());
+ Assert.assertEquals(2, res.getLeft().size());
+
+ // Test CLEANUP category: should return EXPIRE_SNAPSHOTS and CLEAN_ORPHAN
+ res = descriptor.getOptimizingProcessesInfo(table, null, "CLEANUP", null,
10, 0);
+ Assert.assertEquals(2, (int) res.getRight());
+ Assert.assertEquals(2, res.getLeft().size());
+
+ // Test PROFILING category: should return only AUTO_CREATE_TAGS
+ res = descriptor.getOptimizingProcessesInfo(table, null, "PROFILING",
null, 10, 0);
+ Assert.assertEquals(1, (int) res.getRight());
+ Assert.assertEquals(1, res.getLeft().size());
+
+ // Test null category: should return empty results
+ res = descriptor.getOptimizingProcessesInfo(table, null, null, null, 10,
0);
+ Assert.assertEquals(0, (int) res.getRight());
+ Assert.assertEquals(0, res.getLeft().size());
+ }
+
@Override
protected void tableOperationsRenameColumns() {
getTable().updateSchema().renameColumn("new_col", "renamed_col").commit();
@@ -418,5 +503,29 @@ public class TestIcebergServerTableDescriptor extends
TestServerTableDescriptor
fromSequence,
toSequence));
}
+
+ public void insertIcebergActionProcess(
+ ServerTableIdentifier identifier,
+ long processId,
+ ProcessStatus status,
+ Action action,
+ long planTime,
+ MetricsSummary summary) {
+ doAs(
+ TableProcessMapper.class,
+ mapper ->
+ mapper.insertProcess(
+ identifier.getId(),
+ processId,
+ "",
+ status,
+ action.getName(),
+ action.getName(),
+ "AMORO",
+ 0,
+ planTime,
+ new HashMap<>(),
+ summary.summaryAsMap(false)));
+ }
}
}
diff --git
a/amoro-ams/src/test/java/org/apache/amoro/server/optimizing/BaseOptimizingChecker.java
b/amoro-ams/src/test/java/org/apache/amoro/server/optimizing/BaseOptimizingChecker.java
index 06ae381a5..d440b9e54 100644
---
a/amoro-ams/src/test/java/org/apache/amoro/server/optimizing/BaseOptimizingChecker.java
+++
b/amoro-ams/src/test/java/org/apache/amoro/server/optimizing/BaseOptimizingChecker.java
@@ -124,7 +124,7 @@ public class BaseOptimizingChecker extends PersistentBase {
List<TableProcessMeta> tableOptimizingProcesses =
getAs(
TableProcessMapper.class,
- mapper -> mapper.listProcessMeta(identifier.getId(),
null, null));
+ mapper -> mapper.listProcessMeta(identifier.getId(),
null, null, null));
if (tableOptimizingProcesses == null ||
tableOptimizingProcesses.isEmpty()) {
LOG.info("optimize history is empty");
return Status.RUNNING;
@@ -157,7 +157,7 @@ public class BaseOptimizingChecker extends PersistentBase {
List<TableProcessMeta> result =
getAs(
TableProcessMapper.class,
- mapper -> mapper.listProcessMeta(identifier.getId(), null,
null))
+ mapper -> mapper.listProcessMeta(identifier.getId(), null,
null, null))
.stream()
.filter(p -> p.getProcessId() > lastProcessId)
.filter(p -> p.getStatus().equals(ProcessStatus.SUCCESS))
@@ -190,7 +190,7 @@ public class BaseOptimizingChecker extends PersistentBase {
List<TableProcessMeta> tableOptimizingProcesses =
getAs(
TableProcessMapper.class,
- mapper -> mapper.listProcessMeta(identifier.getId(), null,
null))
+ mapper -> mapper.listProcessMeta(identifier.getId(), null,
null, null))
.stream()
.filter(p -> p.getProcessId() > lastProcessId)
.collect(Collectors.toList());
diff --git
a/amoro-ams/src/test/java/org/apache/amoro/server/scheduler/inline/TestProcessDataExpiringExecutor.java
b/amoro-ams/src/test/java/org/apache/amoro/server/scheduler/inline/TestProcessDataExpiringExecutor.java
index bd251b02d..8e2139ba6 100644
---
a/amoro-ams/src/test/java/org/apache/amoro/server/scheduler/inline/TestProcessDataExpiringExecutor.java
+++
b/amoro-ams/src/test/java/org/apache/amoro/server/scheduler/inline/TestProcessDataExpiringExecutor.java
@@ -184,7 +184,8 @@ public class TestProcessDataExpiringExecutor extends
AMSServiceTestBase {
}
public List<TableProcessMeta> listProcesses(long tableId) {
- return getAs(TableProcessMapper.class, mapper ->
mapper.listProcessMeta(tableId, null, null));
+ return getAs(
+ TableProcessMapper.class, mapper -> mapper.listProcessMeta(tableId,
null, null, null));
}
public void cleanAll(long tableId) {
diff --git
a/amoro-common/src/main/java/org/apache/amoro/table/descriptor/FormatTableDescriptor.java
b/amoro-common/src/main/java/org/apache/amoro/table/descriptor/FormatTableDescriptor.java
index 1e8bc62c2..40261fc87 100644
---
a/amoro-common/src/main/java/org/apache/amoro/table/descriptor/FormatTableDescriptor.java
+++
b/amoro-common/src/main/java/org/apache/amoro/table/descriptor/FormatTableDescriptor.java
@@ -23,6 +23,7 @@ import org.apache.amoro.TableFormat;
import org.apache.amoro.process.ProcessStatus;
import org.apache.commons.lang3.tuple.Pair;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
@@ -63,11 +64,29 @@ public interface FormatTableDescriptor {
/** Get the paged optimizing process information of the {@link AmoroTable}
and total size. */
Pair<List<OptimizingProcessInfo>, Integer> getOptimizingProcessesInfo(
- AmoroTable<?> amoroTable, String type, ProcessStatus status, int limit,
int offset);
+ AmoroTable<?> amoroTable,
+ String type,
+ String processCategory,
+ ProcessStatus status,
+ int limit,
+ int offset);
/** Return the optimizing types of the {@link AmoroTable} is supported. */
Map<String, String> getTableOptimizingTypes(AmoroTable<?> amoroTable);
+ /** Return the process types for the given category of the {@link
AmoroTable}. */
+ default Map<String, String> getTableProcessTypes(
+ AmoroTable<?> amoroTable, String processCategory) {
+ if
(ProcessCategory.OPTIMIZING.getName().equalsIgnoreCase(processCategory)) {
+ return getTableOptimizingTypes(amoroTable);
+ }
+
+ return Collections.emptyMap();
+ }
+
+ /** Returns the list of process type names belonging to the given category.
*/
+ List<String> getProcessTypesByCategory(String processCategory);
+
/** Get the paged optimizing process tasks information of the {@link
AmoroTable}. */
List<OptimizingTaskInfo> getOptimizingTaskInfos(AmoroTable<?> amoroTable,
String processId);
diff --git
a/amoro-common/src/main/java/org/apache/amoro/table/descriptor/ProcessCategory.java
b/amoro-common/src/main/java/org/apache/amoro/table/descriptor/ProcessCategory.java
new file mode 100644
index 000000000..070a5bc2f
--- /dev/null
+++
b/amoro-common/src/main/java/org/apache/amoro/table/descriptor/ProcessCategory.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.amoro.table.descriptor;
+
+import java.util.Arrays;
+
+/**
+ * Categories for table processes displayed in the dashboard.
+ * <li>OPTIMIZING: Performance optimization processes (e.g., compaction,
clustering).
+ * <li>CLEANUP: Space reclamation and lifecycle management processes (e.g.,
expire snapshots, clean
+ * orphan files).
+ * <li>PROFILING: Information enrichment and metadata augmentation processes
(e.g., auto create
+ * tags).
+ */
+public enum ProcessCategory {
+ OPTIMIZING("OPTIMIZING"),
+ CLEANUP("CLEANUP"),
+ PROFILING("PROFILING");
+
+ private final String name;
+
+ ProcessCategory(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public static ProcessCategory fromString(String value) {
+ if (value == null) {
+ return null;
+ }
+ return Arrays.stream(values())
+ .filter(c -> c.name.equalsIgnoreCase(value))
+ .findFirst()
+ .orElse(null);
+ }
+}
diff --git
a/amoro-format-hudi/src/main/java/org/apache/amoro/formats/hudi/HudiTableDescriptor.java
b/amoro-format-hudi/src/main/java/org/apache/amoro/formats/hudi/HudiTableDescriptor.java
index 04d089233..7f1a35880 100644
---
a/amoro-format-hudi/src/main/java/org/apache/amoro/formats/hudi/HudiTableDescriptor.java
+++
b/amoro-format-hudi/src/main/java/org/apache/amoro/formats/hudi/HudiTableDescriptor.java
@@ -37,6 +37,7 @@ import
org.apache.amoro.table.descriptor.OptimizingProcessInfo;
import org.apache.amoro.table.descriptor.OptimizingTaskInfo;
import org.apache.amoro.table.descriptor.PartitionBaseInfo;
import org.apache.amoro.table.descriptor.PartitionFileBaseInfo;
+import org.apache.amoro.table.descriptor.ProcessCategory;
import org.apache.amoro.table.descriptor.ServerTableMeta;
import org.apache.amoro.table.descriptor.TableSummary;
import org.apache.amoro.table.descriptor.TagOrBranchInfo;
@@ -79,6 +80,7 @@ import javax.annotation.Nullable;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
@@ -97,6 +99,7 @@ public class HudiTableDescriptor implements
FormatTableDescriptor {
private static final Logger LOG =
LoggerFactory.getLogger(HudiTableDescriptor.class);
private static final String COMPACTION = "compaction";
private static final String CLUSTERING = "clustering";
+ private static final List<String> OPTIMIZING_TYPES =
Arrays.asList(COMPACTION, CLUSTERING);
// table comment
private static final String COMMENT = "comment";
@@ -340,7 +343,12 @@ public class HudiTableDescriptor implements
FormatTableDescriptor {
@Override
public Pair<List<OptimizingProcessInfo>, Integer> getOptimizingProcessesInfo(
- AmoroTable<?> amoroTable, String type, ProcessStatus status, int limit,
int offset) {
+ AmoroTable<?> amoroTable,
+ String type,
+ String processCategory,
+ ProcessStatus status,
+ int limit,
+ int offset) {
HoodieJavaTable hoodieTable = (HoodieJavaTable) amoroTable.originalTable();
HoodieDefaultTimeline timeline = new
HoodieActiveTimeline(hoodieTable.getMetaClient(), false);
List<HoodieInstant> instants = timeline.getInstants();
@@ -381,12 +389,18 @@ public class HudiTableDescriptor implements
FormatTableDescriptor {
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
+ List<String> categoryTypes = getProcessTypesByCategory(processCategory);
infos =
infos.stream()
.filter(
i ->
StringUtils.isNullOrEmpty(type) ||
type.equalsIgnoreCase(i.getOptimizingType()))
.filter(i -> status == null || status == i.getStatus())
+ .filter(
+ i ->
+ i.getOptimizingType() != null
+ && categoryTypes.stream()
+ .anyMatch(t ->
t.equalsIgnoreCase(i.getOptimizingType())))
.collect(Collectors.toList());
int total = infos.size();
infos =
infos.stream().skip(offset).limit(limit).collect(Collectors.toList());
@@ -401,6 +415,15 @@ public class HudiTableDescriptor implements
FormatTableDescriptor {
return types;
}
+ @Override
+ public List<String> getProcessTypesByCategory(String processCategory) {
+ if
(ProcessCategory.OPTIMIZING.getName().equalsIgnoreCase(processCategory)) {
+ return OPTIMIZING_TYPES;
+ }
+
+ return Collections.emptyList();
+ }
+
protected OptimizingProcessInfo getOptimizingInfo(
String instantTimestamp, Map<String, HoodieInstant> instantMap,
HoodieTimeline timeline)
throws IOException {
diff --git
a/amoro-format-paimon/src/main/java/org/apache/amoro/formats/paimon/PaimonTableDescriptor.java
b/amoro-format-paimon/src/main/java/org/apache/amoro/formats/paimon/PaimonTableDescriptor.java
index 566da688a..7263dc8a5 100644
---
a/amoro-format-paimon/src/main/java/org/apache/amoro/formats/paimon/PaimonTableDescriptor.java
+++
b/amoro-format-paimon/src/main/java/org/apache/amoro/formats/paimon/PaimonTableDescriptor.java
@@ -41,6 +41,7 @@ import
org.apache.amoro.table.descriptor.OptimizingProcessInfo;
import org.apache.amoro.table.descriptor.OptimizingTaskInfo;
import org.apache.amoro.table.descriptor.PartitionBaseInfo;
import org.apache.amoro.table.descriptor.PartitionFileBaseInfo;
+import org.apache.amoro.table.descriptor.ProcessCategory;
import org.apache.amoro.table.descriptor.ServerTableMeta;
import org.apache.amoro.table.descriptor.TableSummary;
import org.apache.amoro.table.descriptor.TagOrBranchInfo;
@@ -89,6 +90,9 @@ import java.util.stream.Collectors;
public class PaimonTableDescriptor implements FormatTableDescriptor {
public static final String PAIMON_MAIN_BRANCH_NAME = "main";
+ private static final String FULL_TYPE = "FULL";
+ private static final String MINOR_TYPE = "MINOR";
+ private static final List<String> OPTIMIZING_TYPES =
Arrays.asList(FULL_TYPE, MINOR_TYPE);
private ExecutorService executor;
@@ -372,7 +376,12 @@ public class PaimonTableDescriptor implements
FormatTableDescriptor {
@Override
public Pair<List<OptimizingProcessInfo>, Integer> getOptimizingProcessesInfo(
- AmoroTable<?> amoroTable, String type, ProcessStatus status, int limit,
int offset) {
+ AmoroTable<?> amoroTable,
+ String type,
+ String processCategory,
+ ProcessStatus status,
+ int limit,
+ int offset) {
// Temporary solution for Paimon. TODO: Get compaction info from Paimon
compaction task
List<OptimizingProcessInfo> processInfoList;
TableIdentifier tableIdentifier = amoroTable.id();
@@ -428,9 +437,9 @@ public class PaimonTableDescriptor implements
FormatTableDescriptor {
}
}
if (isPrimaryTable && hasMaxLevels) {
- optimizingProcessInfo.setOptimizingType("FULL");
+ optimizingProcessInfo.setOptimizingType(FULL_TYPE);
} else {
- optimizingProcessInfo.setOptimizingType("MINOR");
+ optimizingProcessInfo.setOptimizingType(MINOR_TYPE);
}
optimizingProcessInfo.setSuccessTasks(buckets.size());
optimizingProcessInfo.setTotalTasks(buckets.size());
@@ -445,10 +454,16 @@ public class PaimonTableDescriptor implements
FormatTableDescriptor {
} catch (IOException e) {
throw new RuntimeException(e);
}
+ List<String> categoryTypes = getProcessTypesByCategory(processCategory);
processInfoList =
processInfoList.stream()
.filter(p -> StringUtils.isBlank(type) ||
type.equalsIgnoreCase(p.getOptimizingType()))
.filter(p -> status == null || status == p.getStatus())
+ .filter(
+ p ->
+ p.getOptimizingType() != null
+ && categoryTypes.stream()
+ .anyMatch(t ->
t.equalsIgnoreCase(p.getOptimizingType())))
.collect(Collectors.toList());
int total = processInfoList.size();
processInfoList =
@@ -459,11 +474,20 @@ public class PaimonTableDescriptor implements
FormatTableDescriptor {
@Override
public Map<String, String> getTableOptimizingTypes(AmoroTable<?> amoroTable)
{
Map<String, String> types = Maps.newHashMap();
- types.put("FULL", "full");
- types.put("MINOR", "MINOR");
+ types.put(FULL_TYPE, "full");
+ types.put(MINOR_TYPE, "MINOR");
return types;
}
+ @Override
+ public List<String> getProcessTypesByCategory(String processCategory) {
+ if
(ProcessCategory.OPTIMIZING.getName().equalsIgnoreCase(processCategory)) {
+ return OPTIMIZING_TYPES;
+ }
+
+ return Collections.emptyList();
+ }
+
@Override
public List<OptimizingTaskInfo> getOptimizingTaskInfos(
AmoroTable<?> amoroTable, String processId) {
diff --git a/amoro-web/mock/modules/table.js b/amoro-web/mock/modules/table.js
index 372e81fd9..119cf7b3f 100644
--- a/amoro-web/mock/modules/table.js
+++ b/amoro-web/mock/modules/table.js
@@ -307,17 +307,32 @@ export default [
}),
},
{
- url:
'/mock/api/ams/v1/tables/catalogs/test_catalog/dbs/db/tables/user/optimizing-types',
+ url:
'/mock/api/ams/v1/tables/catalogs/test_catalog/dbs/db/tables/user/process-types',
method: 'get',
- response: () => ({
- "message": "success",
- "code": 200,
- "result": {
- "MINOR": "minor",
- "MAJOR": "major",
- "FULL": "full",
+ response: ({ query }) => {
+ const processCategory = query?.processCategory || 'OPTIMIZING'
+ const result = {
+ OPTIMIZING: {
+ 'MINOR': 'minor',
+ 'MAJOR': 'major',
+ 'FULL': 'full',
+ },
+ CLEANUP: {
+ 'EXPIRE-SNAPSHOTS': 'Expire Snapshots',
+ 'CLEAN-ORPHAN-FILES': 'Clean Orphan Files',
+ 'CLEAN-DANGLING-DELETE-FILES': 'Clean Dangling Delete Files',
+ 'EXPIRE-DATA': 'Expire Data',
+ },
+ PROFILING: {
+ 'AUTO-CREATE-TAGS': 'Auto Create Tags',
+ },
}
- }),
+ return {
+ 'message': 'success',
+ 'code': 200,
+ 'result': result[processCategory] || result.OPTIMIZING,
+ }
+ },
},
{
url:
'/mock/api/ams/v1/tables/catalogs/test_catalog/dbs/db/tables/user/operations',
diff --git a/amoro-web/src/language/en.ts b/amoro-web/src/language/en.ts
index d28c05cfd..b0be90e2d 100644
--- a/amoro-web/src/language/en.ts
+++ b/amoro-web/src/language/en.ts
@@ -28,6 +28,8 @@ export default {
catalog: 'Catalog',
tables: 'Tables',
optimizing: 'Optimizing',
+ cleanup: 'Cleanup',
+ profiling: 'Profiling',
terminal: 'Terminal',
settings: 'Settings',
systemSetting: 'System Settings',
@@ -124,6 +126,9 @@ export default {
resourceGroup: 'Resource Group',
releaseOptModalTitle: 'Release this optimizer?',
cancelOptimizingProcessOptModalTitle: 'Cancel the optimizing process of this
table?',
+ cancelCleanupProcessOptModalTitle: 'Cancel the cleanup process of this
table?',
+ cancelProfilingProcessOptModalTitle: 'Cancel the profiling process of this
table?',
+ loadProcessTypesFailed: 'Failed to load process types',
welcomeTip: 'Welcome to Amoro!',
signIn: 'Sign in',
username: 'Username',
diff --git a/amoro-web/src/language/zh.ts b/amoro-web/src/language/zh.ts
index 33087d9b1..cf20bcefc 100644
--- a/amoro-web/src/language/zh.ts
+++ b/amoro-web/src/language/zh.ts
@@ -28,6 +28,8 @@ export default {
catalog: '目录',
tables: '表',
optimizing: '优化',
+ cleanup: '清理',
+ profiling: '剖析',
terminal: '终端',
settings: '设置',
systemSetting: '系统设置',
@@ -124,6 +126,9 @@ export default {
resourceGroup: '资源组',
releaseOptModalTitle: '释放此优化器?',
cancelOptimizingProcessOptModalTitle: '取消该表的优化过程?',
+ cancelCleanupProcessOptModalTitle: '取消该表的清理过程?',
+ cancelProfilingProcessOptModalTitle: '取消该表的剖析过程?',
+ loadProcessTypesFailed: '加载流程类型失败',
welcomeTip: '欢迎访问 Amoro!',
signIn: '登入',
username: '用户名',
diff --git a/amoro-web/src/services/table.service.ts
b/amoro-web/src/services/table.service.ts
index 08f046cca..0ff5ba928 100644
--- a/amoro-web/src/services/table.service.ts
+++ b/amoro-web/src/services/table.service.ts
@@ -158,27 +158,29 @@ export function getOptimizingProcesses(
db: string
table: string
type: string
+ processCategory?: string
status: string
page: number
pageSize: number
token?: string
},
) {
- const { catalog, db, table, type, status, page, pageSize, token } = params
- return
request.get(`api/ams/v1/tables/catalogs/${catalog}/dbs/${db}/tables/${table}/optimizing-processes`,
{ params: { page, pageSize, token, type, status } })
+ const { catalog, db, table, type, processCategory, status, page, pageSize,
token } = params
+ return
request.get(`api/ams/v1/tables/catalogs/${catalog}/dbs/${db}/tables/${table}/optimizing-processes`,
{ params: { page, pageSize, token, type, processCategory, status } })
}
-// get optimizing process types
-export function getTableOptimizingTypes(
+// get process types by category
+export function getTableProcessTypes(
params: {
catalog: string
db: string
table: string
+ processCategory: string
token?: string
},
) {
- const { catalog, db, table, token } = params
- return
request.get(`api/ams/v1/tables/catalogs/${catalog}/dbs/${db}/tables/${table}/optimizing-types`,
{ params: { token } })
+ const { catalog, db, table, processCategory, token } = params
+ return
request.get(`api/ams/v1/tables/catalogs/${catalog}/dbs/${db}/tables/${table}/process-types`,
{ params: { processCategory, token } })
}
// get optimizing tasks
diff --git a/amoro-web/src/views/tables/components/Cleanup.vue
b/amoro-web/src/views/tables/components/Cleanup.vue
new file mode 100644
index 000000000..4bb29700d
--- /dev/null
+++ b/amoro-web/src/views/tables/components/Cleanup.vue
@@ -0,0 +1,26 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+/ -->
+
+<script lang="ts" setup>
+import Optimizing from './Optimizing.vue'
+</script>
+
+<template>
+ <Optimizing process-category="CLEANUP"
cancel-modal-title-key="cancelCleanupProcessOptModalTitle" />
+</template>
diff --git a/amoro-web/src/views/tables/components/Optimizing.vue
b/amoro-web/src/views/tables/components/Optimizing.vue
index c7ccc0b50..8aa424456 100644
--- a/amoro-web/src/views/tables/components/Optimizing.vue
+++ b/amoro-web/src/views/tables/components/Optimizing.vue
@@ -20,13 +20,21 @@ limitations under the License.
import { onMounted, reactive, ref, shallowReactive } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRoute } from 'vue-router'
-import { Modal } from 'ant-design-vue'
+import { Modal, message } from 'ant-design-vue'
import { usePagination } from '@/hooks/usePagination'
import type { BreadcrumbOptimizingItem, IColumns, ILableAndValue } from
'@/types/common.type'
-import { cancelOptimizingProcess, getOptimizingProcesses,
getTableOptimizingTypes, getTasksByOptimizingProcessId } from
'@/services/table.service'
+import { cancelOptimizingProcess, getOptimizingProcesses,
getTableProcessTypes, getTasksByOptimizingProcessId } from
'@/services/table.service'
import { bytesToSize, dateFormat, formatMS2Time } from '@/utils/index'
import { canManageTable } from '@/utils/permission'
+const props = withDefaults(defineProps<{
+ processCategory?: string
+ cancelModalTitleKey?: string
+}>(), {
+ processCategory: 'OPTIMIZING',
+ cancelModalTitleKey: 'cancelOptimizingProcessOptModalTitle',
+})
+
const hasBreadcrumb = ref<boolean>(false)
const statusMap = {
@@ -95,12 +103,18 @@ const statusType = ref<ILableAndValue>()
const statusTypeList = ref<ILableAndValue[]>([])
async function getQueryDataDictList() {
- const tableProcessTypes = await getTableOptimizingTypes({ ...sourceData })
- const typesList = Object.entries(tableProcessTypes).map(([typeName,
displayName]) => ({ label: displayName as string, value: typeName }))
const status = Object.entries(statusMap).map(([key, value]) => ({ label:
value.title, value: key }))
-
- actionTypeList.value = typesList
statusTypeList.value = status
+
+ try {
+ const rawTypes = await getTableProcessTypes({ ...sourceData,
processCategory: props.processCategory })
+ actionTypeList.value = Object.entries(rawTypes).map(([typeName,
displayName]) => ({ label: displayName as string, value: typeName }))
+ }
+ catch (error) {
+ console.error('Failed to load process types:', error)
+ message.error(t('loadProcessTypesFailed'))
+ actionTypeList.value = []
+ }
}
async function refreshOptimizingProcesses() {
@@ -109,14 +123,15 @@ async function refreshOptimizingProcesses() {
dataSource.length = 0
const result = await getOptimizingProcesses({
...sourceData,
- type: actionType.value || '',
- status: statusType.value || '',
+ type: String(actionType.value || ''),
+ processCategory: props.processCategory,
+ status: String(statusType.value || ''),
page: pagination.current,
pageSize: pagination.pageSize,
- } as any)
+ })
const { list, total = 0 } = result
pagination.total = total
- dataSource.push(...[...list || []].map((item) => {
+ dataSource.push(...[...list || []].map((item: any) => {
const { inputFiles = {}, outputFiles = {} } = item
return {
...item,
@@ -142,7 +157,7 @@ async function refreshOptimizingProcesses() {
async function cancel() {
Modal.confirm({
- title: t('cancelOptimizingProcessOptModalTitle'),
+ title: t(props.cancelModalTitleKey),
onOk: async () => {
try {
loading.value = true
@@ -421,10 +436,6 @@ onMounted(() => {
padding: 4px 16px !important;
}
- :deep(.ant-table-thead > tr > th) {
- padding: 4px 16px !important;
- }
-
:deep(.ant-table-row-expand-icon) {
border-radius: 0 !important;
}
diff --git a/amoro-web/src/views/tables/components/Profiling.vue
b/amoro-web/src/views/tables/components/Profiling.vue
new file mode 100644
index 000000000..704b55b3c
--- /dev/null
+++ b/amoro-web/src/views/tables/components/Profiling.vue
@@ -0,0 +1,26 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+/ -->
+
+<script lang="ts" setup>
+import Optimizing from './Optimizing.vue'
+</script>
+
+<template>
+ <Optimizing process-category="PROFILING"
cancel-modal-title-key="cancelProfilingProcessOptModalTitle" />
+</template>
diff --git a/amoro-web/src/views/tables/index.vue
b/amoro-web/src/views/tables/index.vue
index f3704dbe2..b3413d982 100644
--- a/amoro-web/src/views/tables/index.vue
+++ b/amoro-web/src/views/tables/index.vue
@@ -24,6 +24,8 @@ import UFiles from './components/Files.vue'
import UOperations from './components/Operations.vue'
import USnapshots from './components/Snapshots.vue'
import UOptimizing from './components/Optimizing.vue'
+import UCleanup from './components/Cleanup.vue'
+import UProfiling from './components/Profiling.vue'
import UHealthScore from './components/HealthScoreDetails.vue'
import TableExplorer from './components/TableExplorer.vue'
import useStore from '@/store/index'
@@ -38,6 +40,8 @@ export default defineComponent({
UOperations,
USnapshots,
UOptimizing,
+ UCleanup,
+ UProfiling,
UHealthScore,
TableExplorer,
},
@@ -106,6 +110,8 @@ export default defineComponent({
const tabConfigs = shallowReactive([
{ key: 'Snapshots', label: 'snapshots' },
{ key: 'Optimizing', label: 'optimizing' },
+ { key: 'Cleanup', label: 'cleanup' },
+ { key: 'Profiling', label: 'profiling' },
{ key: 'Operations', label: 'operations' },
])