feature(web): 优化时间线展示

加入分页,增加对时间点的排序,默认最近的在最前面
This commit is contained in:
2023-05-04 10:39:31 +08:00
parent f8ae7421a5
commit 78c6814880
5 changed files with 71 additions and 34 deletions

View File

@@ -34,31 +34,16 @@ public class TimelineController {
public ImmutableList<HudiInstant> allInstants(
@RequestParam("flink_job_id") Long flinkJobId,
@RequestParam("alias") String alias,
@RequestParam(value = "filter_type", required = false) List<String> filterType,
@RequestParam(value = "filter_action", required = false) List<String> filterAction,
@RequestParam(value = "filter_state", required = false) List<String> filterState
@RequestParam(value = "filter_type", required = false) List<String> filterType
) throws IOException {
return timelineService.timeline(
flinkJobId,
alias,
Lists.immutable.ofAll(filterType),
Lists.immutable.ofAll(filterAction),
Lists.immutable.ofAll(filterState)
);
return timelineService.timeline(flinkJobId, alias, Lists.immutable.ofAll(filterType));
}
@GetMapping("list_hdfs")
public ImmutableList<HudiInstant> allInstants(
@RequestParam("hdfs") String hdfs,
@RequestParam(value = "filter_type", required = false) List<String> filterType,
@RequestParam(value = "filter_action", required = false) List<String> filterAction,
@RequestParam(value = "filter_state", required = false) List<String> filterState
@RequestParam(value = "filter_type", required = false) List<String> filterType
) throws IOException {
return timelineService.timeline(
hdfs,
Lists.immutable.ofAll(filterType),
Lists.immutable.ofAll(filterAction),
Lists.immutable.ofAll(filterState)
);
return timelineService.timeline(hdfs, Lists.immutable.ofAll(filterType));
}
}

View File

@@ -37,9 +37,9 @@ public class TimelineService {
@Cacheable(value = "timeline", sync = true, key = "#flinkJobId.toString()+#alias")
@Retryable(Throwable.class)
public ImmutableList<HudiInstant> timeline(Long flinkJobId, String alias, ImmutableList<String> filterType, ImmutableList<String> filterAction, ImmutableList<String> filterState) throws IOException {
public ImmutableList<HudiInstant> timeline(Long flinkJobId, String alias, ImmutableList<String> filterType) throws IOException {
TableMeta meta = infoService.tableMetaDetail(flinkJobId, alias);
return timeline(meta.getHudi().getTargetHdfsPath(), filterType, filterAction, filterState);
return timeline(meta.getHudi().getTargetHdfsPath(), filterType);
}
private static final String INSTANT_TYPE_ACTIVE = "active";
@@ -47,7 +47,7 @@ public class TimelineService {
@Cacheable(value = "timeline", sync = true, key = "#hdfs")
@Retryable(Throwable.class)
public ImmutableList<HudiInstant> timeline(String hdfs, ImmutableList<String> filterType, ImmutableList<String> filterAction, ImmutableList<String> filterState) throws IOException {
public ImmutableList<HudiInstant> timeline(String hdfs, ImmutableList<String> filterType) throws IOException {
HoodieTableMetaClient client = HoodieTableMetaClient.builder()
.setConf(new Configuration())
.setBasePath(hdfs)
@@ -59,15 +59,11 @@ public class TimelineService {
if (filterType.contains(INSTANT_TYPE_ARCHIVE)) {
HoodieUtils.getAllInstants(client, HoodieTableMetaClient::getArchivedTimeline)
.collect(instant -> covert(INSTANT_TYPE_ARCHIVE, instant))
.select(instant -> ObjectUtil.isEmpty(filterAction) || filterAction.contains(instant.getAction()))
.select(instant -> ObjectUtil.isEmpty(filterState) || filterState.contains(instant.getState()))
.forEach(instants::add);
}
if (filterType.contains(INSTANT_TYPE_ACTIVE)) {
HoodieUtils.getAllInstants(client, HoodieTableMetaClient::getActiveTimeline)
.collect(instant -> covert(INSTANT_TYPE_ACTIVE, instant))
.select(instant -> ObjectUtil.isEmpty(filterAction) || filterAction.contains(instant.getAction()))
.select(instant -> ObjectUtil.isEmpty(filterState) || filterState.contains(instant.getState()))
.forEach(instants::add);
}
return instants

View File

@@ -2,9 +2,14 @@ package com.lanyuanxiaoyao.service.web.controller;
import cn.hutool.core.util.ObjectUtil;
import com.lanyuanxiaoyao.service.configuration.entity.AmisResponse;
import com.lanyuanxiaoyao.service.configuration.entity.hudi.HudiInstant;
import com.lanyuanxiaoyao.service.forest.service.HudiService;
import com.lanyuanxiaoyao.service.web.utils.ComparatorUtil;
import java.util.List;
import java.util.function.Function;
import org.eclipse.collections.api.factory.Maps;
import org.eclipse.collections.api.list.ImmutableList;
import org.eclipse.collections.api.map.ImmutableMap;
import org.eclipse.collections.api.map.MutableMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -31,8 +36,17 @@ public class HudiController extends BaseController {
this.hudiService = hudiService;
}
private static final ImmutableMap<String, Function<HudiInstant, String>> TIMELINE_SORT_MAP = Maps.immutable.of(
"timestamp",
HudiInstant::getTimestamp
);
@GetMapping("/timeline/list")
public AmisResponse timeline(
@RequestParam(value = "page", defaultValue = "1") Integer page,
@RequestParam(value = "count", defaultValue = "10") Integer count,
@RequestParam(value = "order", defaultValue = "timestamp") String order,
@RequestParam(value = "direction", defaultValue = "desc") String direction,
@RequestParam("flink_job_id") Long flinkJobId,
@RequestParam("alias") String alias,
@RequestParam(value = "filter_type", required = false) List<String> filterType,
@@ -45,12 +59,14 @@ public class HudiController extends BaseController {
if (ObjectUtil.isNotEmpty(filterType)) {
queryMap.put("filter_type", filterType);
}
if (ObjectUtil.isNotEmpty(filterAction)) {
queryMap.put("filter_action", filterAction);
}
if (ObjectUtil.isNotEmpty(filterAction)) {
queryMap.put("filter_state", filterState);
}
return responseCrudData(hudiService.timelineList(queryMap));
ImmutableList<HudiInstant> hudiInstants = hudiService.timelineList(queryMap)
.select(instant -> ObjectUtil.isEmpty(filterAction) || filterAction.contains(instant.getAction()))
.select(instant -> ObjectUtil.isEmpty(filterState) || filterState.contains(instant.getState()))
.toSortedList(ComparatorUtil.stringComparator(order, direction, TIMELINE_SORT_MAP))
.toImmutable();
ImmutableList<HudiInstant> result = hudiInstants
.drop(Math.max(page - 1, 0) * count)
.take(count);
return responseCrudData(result, hudiInstants.size());
}
}

View File

@@ -28,4 +28,18 @@ public class ComparatorUtil {
return (o1, o2) -> 0;
}
}
public static <T> Comparator<T> stringComparator(String order, String direction, ImmutableMap<String, Function<T, String>> getters) {
if (StrUtil.isBlank(order) || StrUtil.isBlank(direction) || !getters.containsKey(order)) {
return (o1, o2) -> 0;
}
Function<T, String> getter = getters.get(order);
if (DESC.equalsIgnoreCase(direction)) {
return (o1, o2) -> StrUtil.compare(getter.apply(o2), getter.apply(o1), true);
} else if (ASC.equalsIgnoreCase(direction)) {
return (o1, o2) -> StrUtil.compare(getter.apply(o1), getter.apply(o2), true);
} else {
return (o1, o2) -> 0;
}
}
}

View File

@@ -262,6 +262,10 @@ function tableTab() {
method: 'get',
url: '${base}/hudi/timeline/list',
data: {
page: '${page|default:undefined}',
count: '${perPage|default:undefined}',
order: '${orderBy|default:undefined}',
direction: '${orderDir|default:undefined}',
flink_job_id: '${flinkJobId|default:undefined}',
alias: '${tableMeta.alias|default:undefined}',
filter_type: '${filter_type|default:undefined}'
@@ -271,11 +275,33 @@ function tableTab() {
},
},
syncLocation: false,
silentPolling: true,
stopAutoRefreshWhenModalIsOpen: true,
resizable: false,
perPage: 10,
headerToolbar: [
"reload",
{
type: 'pagination',
layout: ['pager', 'perPage'],
maxButtons: 8,
showPageInput: false,
},
],
footerToolbar: [
{
type: 'pagination',
layout: ['pager', 'perPage'],
maxButtons: 8,
showPageInput: false,
},
],
columns: [
{
name: 'timestamp',
label: '时间点',
width: 150,
sortable: true,
},
{
name: 'filter_action',
@@ -287,7 +313,7 @@ function tableTab() {
{
name: 'filter_state',
label: ' 状态',
width: 100,
width: 80,
align: 'center',
...mappingField('state', hudiTimelineStateMapping),
filterable: filterableField(hudiTimelineStateMapping, true),