diff --git a/service-web/src/main/java/com/lanyuanxiaoyao/service/web/controller/BaseController.java b/service-web/src/main/java/com/lanyuanxiaoyao/service/web/controller/BaseController.java index 0e1495d..50735e0 100644 --- a/service-web/src/main/java/com/lanyuanxiaoyao/service/web/controller/BaseController.java +++ b/service-web/src/main/java/com/lanyuanxiaoyao/service/web/controller/BaseController.java @@ -1,9 +1,12 @@ package com.lanyuanxiaoyao.service.web.controller; import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.StrUtil; import com.lanyuanxiaoyao.service.configuration.entity.AmisResponse; import java.util.HashMap; import java.util.Map; +import org.eclipse.collections.api.factory.Maps; +import org.eclipse.collections.api.map.MutableMap; /** * 放一些 Controller 的辅助方法 @@ -65,4 +68,28 @@ public class BaseController { .build()) .build(); } + + protected MutableMap buildQueryMap( + Integer page, + Integer count, + String order, + String direction, + String searchFlinkJobId, + String searchAlias + ) { + MutableMap queryMap = Maps.mutable.empty(); + queryMap.put("page", page); + queryMap.put("count", count); + if (StrUtil.isNotBlank(searchFlinkJobId)) { + queryMap.put("flink_job_id", searchFlinkJobId); + } + if (StrUtil.isNotBlank(searchAlias)) { + queryMap.put("alias", searchAlias); + } + if (StrUtil.isNotBlank(order) && StrUtil.isNotBlank(direction)) { + queryMap.put("order", order); + queryMap.put("direction", direction); + } + return queryMap; + } } diff --git a/service-web/src/main/java/com/lanyuanxiaoyao/service/web/controller/CloudController.java b/service-web/src/main/java/com/lanyuanxiaoyao/service/web/controller/CloudController.java index b0a886d..ed93d50 100644 --- a/service-web/src/main/java/com/lanyuanxiaoyao/service/web/controller/CloudController.java +++ b/service-web/src/main/java/com/lanyuanxiaoyao/service/web/controller/CloudController.java @@ -6,6 +6,7 @@ import cn.hutool.core.util.StrUtil; import com.lanyuanxiaoyao.service.configuration.entity.AmisResponse; import com.lanyuanxiaoyao.service.web.entity.CloudServiceVO; import com.netflix.appinfo.InstanceInfo; +import java.util.Map; import org.eclipse.collections.api.block.function.Function; import org.eclipse.collections.api.factory.Lists; import org.eclipse.collections.api.factory.Maps; @@ -20,8 +21,6 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.Map; - /** * 云页面 * @@ -138,4 +137,9 @@ public class CloudController extends BaseController { .build() ); } + + @GetMapping("heart") + public AmisResponse heart() { + return responseData().withData("status", true); + } } diff --git a/service-web/src/main/java/com/lanyuanxiaoyao/service/web/controller/VersionController.java b/service-web/src/main/java/com/lanyuanxiaoyao/service/web/controller/VersionController.java new file mode 100644 index 0000000..c0fdee9 --- /dev/null +++ b/service-web/src/main/java/com/lanyuanxiaoyao/service/web/controller/VersionController.java @@ -0,0 +1,89 @@ +package com.lanyuanxiaoyao.service.web.controller; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.eshore.odcp.hudi.connector.entity.FlinkJob; +import com.eshore.odcp.hudi.connector.entity.TableMeta; +import com.lanyuanxiaoyao.service.configuration.ExecutorProvider; +import com.lanyuanxiaoyao.service.configuration.entity.AmisResponse; +import com.lanyuanxiaoyao.service.configuration.entity.PageResponse; +import com.lanyuanxiaoyao.service.configuration.entity.info.VersionUpdated; +import com.lanyuanxiaoyao.service.forest.service.InfoService; +import com.lanyuanxiaoyao.service.web.entity.VersionUpdateVO; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import org.eclipse.collections.api.factory.Lists; +import org.eclipse.collections.api.list.ImmutableList; +import org.eclipse.collections.api.map.MutableMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +/** + * 跨天相关 + * + * @author lanyuanxiaoyao + * @date 2023-06-06 + */ +@RestController +@RequestMapping("version_upadte") +public class VersionController extends BaseController { + private static final Logger logger = LoggerFactory.getLogger(VersionController.class); + + private final InfoService infoService; + + @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") + public VersionController(InfoService infoService) { + this.infoService = infoService; + } + + @GetMapping("list") + public AmisResponse list( + @RequestParam(value = "page", defaultValue = "1") Integer page, + @RequestParam(value = "count", defaultValue = "10") Integer count, + @RequestParam(value = "order", required = false) String order, + @RequestParam(value = "direction", required = false) String direction, + @RequestParam(value = "search_version", required = false) String searchVersion, + @RequestParam(value = "search_flink_job_id", required = false) String searchFlinkJobId, + @RequestParam(value = "search_alias", required = false) String searchAlias, + @RequestParam(value = "filter_schedules", required = false) List filterSchedules + ) { + MutableMap queryMap = buildQueryMap(page, count, order, direction, searchFlinkJobId, searchAlias); + if (StrUtil.isNotBlank(searchVersion)) { + queryMap.put("version", searchVersion); + } + if (ObjectUtil.isNotEmpty(filterSchedules)) { + queryMap.put("filter_schedules", filterSchedules); + } + PageResponse pageResponse = infoService.versionTables(queryMap); + Long total = pageResponse.getTotal(); + ImmutableList vos = Lists.immutable.ofAll(pageResponse.getData()) + .asParallel(ExecutorProvider.EXECUTORS, 1) + .collect(item -> { + CompletableFuture flinkJobFuture = CompletableFuture.supplyAsync(() -> infoService.flinkJobDetail(item.getFlinkJobId()), ExecutorProvider.EXECUTORS); + CompletableFuture tableMetaFuture = CompletableFuture.supplyAsync(() -> infoService.tableMetaDetail(item.getFlinkJobId(), item.getAlias()), ExecutorProvider.EXECUTORS); + try { + CompletableFuture.allOf(flinkJobFuture, tableMetaFuture).get(); + return new VersionUpdateVO( + item.getFlinkJobId(), + item.getAlias(), + item.getVersion(), + item.getUpdated(), + flinkJobFuture.get(), + tableMetaFuture.get() + ); + } catch (InterruptedException | ExecutionException e) { + logger.error("Something bad", e); + return null; + } + }) + .reject(ObjectUtil::isNull) + .toList() + .toImmutable(); + return responseCrudData(vos, total); + } +} diff --git a/service-web/src/main/java/com/lanyuanxiaoyao/service/web/entity/VersionUpdateVO.java b/service-web/src/main/java/com/lanyuanxiaoyao/service/web/entity/VersionUpdateVO.java new file mode 100644 index 0000000..8c386e0 --- /dev/null +++ b/service-web/src/main/java/com/lanyuanxiaoyao/service/web/entity/VersionUpdateVO.java @@ -0,0 +1,70 @@ +package com.lanyuanxiaoyao.service.web.entity; + +import com.eshore.odcp.hudi.connector.entity.FlinkJob; +import com.eshore.odcp.hudi.connector.entity.TableMeta; + +/** + * @author lanyuanxiaoyao + * @date 2023-06-07 + */ +public class VersionUpdateVO { + private final String flinkJobId; + private final String alias; + private final String version; + private final Boolean updated; + private final Integer priority; + + private final FlinkJob flinkJob; + private final TableMeta tableMeta; + + public VersionUpdateVO(Long flinkJobId, String alias, String version, Boolean updated, FlinkJob flinkJob, TableMeta tableMeta) { + this.flinkJobId = flinkJobId.toString(); + this.alias = alias; + this.version = version; + this.updated = updated; + this.flinkJob = flinkJob; + this.tableMeta = tableMeta; + this.priority = tableMeta.getPriority(); + } + + public String getFlinkJobId() { + return flinkJobId; + } + + public String getAlias() { + return alias; + } + + public String getVersion() { + return version; + } + + public Boolean getUpdated() { + return updated; + } + + public Integer getPriority() { + return priority; + } + + public FlinkJob getFlinkJob() { + return flinkJob; + } + + public TableMeta getTableMeta() { + return tableMeta; + } + + @Override + public String toString() { + return "VersionUpdateVO{" + + "flinkJobId='" + flinkJobId + '\'' + + ", alias='" + alias + '\'' + + ", version='" + version + '\'' + + ", updated=" + updated + + ", priority=" + priority + + ", flinkJob=" + flinkJob + + ", tableMeta=" + tableMeta + + '}'; + } +} diff --git a/web/components/common.js b/web/components/common.js index 0cab975..6ac025d 100644 --- a/web/components/common.js +++ b/web/components/common.js @@ -1403,6 +1403,11 @@ let tableRunningStateMapping = [ mappingItem('未运行', 'false'), ] +let versionUpdateStateMapping = [ + mappingItem('已跨天', 'true', 'label-success'), + mappingItem('未跨天', 'false', 'label-danger'), +] + function mappingField(field, mapping) { let mapData = { '*': `\${${field}}`, diff --git a/web/components/version-tab.js b/web/components/version-tab.js new file mode 100644 index 0000000..f874991 --- /dev/null +++ b/web/components/version-tab.js @@ -0,0 +1,183 @@ +function versionTab() { + return { + title: '跨天', + tab: [ + { + type: 'crud', + api: { + method: 'get', + url: `\${base}/version_upadte/list`, + data: { + page: '${page|default:undefined}', + count: '${perPage|default:undefined}', + order: '${orderBy|default:undefined}', + direction: '${orderDir|default:undefined}', + search_flink_job_id: '${flinkJobId|default:undefined}', + search_alias: '${alias|default:undefined}', + search_version: '${version|default:undefined}', + filter_schedules: '${updated|default:undefined}' + } + }, + data: { + now: "${DATETOSTR(DATEMODIFY(NOW(), -1, 'days'), 'YYYYMMDD')}" + }, + defaultParams: { + // version: "${DATETOSTR(NOW(), 'YYYYMMDD')}" + }, + syncLocation: false, + interval: 10000, + silentPolling: true, + filter: { + mode: 'inline', + title: '表筛选', + body: [ + { + type: 'group', + body: [ + { + type: 'input-text', + name: 'flinkJobId', + label: 'Flink job id', + clearable: true, + placeholder: '通过 ID 搜索', + size: 'md' + }, + { + type: 'input-text', + name: 'alias', + label: '名称', + clearable: true, + placeholder: '通过别名搜索', + size: 'md' + }, + { + type: 'input-date', + name: 'version', + label: '版本', + clearable: true, + placeholder: '通过版本搜索', + size: 'md', + format: 'YYYYMMDD', + inputFormat: 'YYYYMMDD', + value: '${now}', + }, + ] + }, + ], + actions: [ + { + type: "submit", + level: "primary", + label: "查询", + }, + { + type: "reset", + label: "重置", + }, + ] + }, + filterTogglable: true, + filterDefaultVisible: true, + stopAutoRefreshWhenModalIsOpen: true, + resizable: false, + perPage: 20, + headerToolbar: [ + "reload", + 'filter-toggler', + { + type: 'pagination', + layout: ['pager', 'perPage'], + maxButtons: 5, + showPageInput: false, + }, + ], + footerToolbar: [ + { + type: 'pagination', + layout: ['pager', 'perPage'], + maxButtons: 5, + showPageInput: false, + }, + ], + columns: [ + { + label: 'Flink job id', + width: 170, + fixed: 'left', + type: 'wrapper', + size: 'none', + body: [ + { + type: 'action', + level: 'link', + label: '${flinkJobId}', + size: 'xs', + actionType: 'dialog', + tooltip: '查看详情', + dialog: flinkJobDialog(), + }, + { + type: 'action', + level: 'link', + label: '', + icon: 'fa fa-copy', + size: 'xs', + actionType: 'copy', + content: '${flinkJobId}', + tooltip: '复制 ID', + } + ], + }, + { + label: '别名', + type: 'wrapper', + fixed: 'left', + size: 'none', + className: 'nowrap', + body: [ + { + type: 'action', + level: 'link', + label: '${tableMeta.alias}', + size: 'xs', + actionType: 'dialog', + tooltip: '查看详情', + dialog: tableMetaDialog(), + }, + { + type: 'action', + level: 'link', + label: '', + icon: 'fa fa-copy', + size: 'xs', + actionType: 'copy', + content: '${tableMeta.alias}', + tooltip: '复制别名', + }, + ], + }, + { + name: 'priority', + label: '表优先级', + align: 'center', + width: 75, + sortable: true, + },{ + name: 'version', + label: '版本', + align: 'center', + width: 75, + }, + { + name: 'updated', + label: '状态', + align: 'center', + ...mappingField('updated', versionUpdateStateMapping), + filterable: filterableField(versionUpdateStateMapping, true), + width: 70, + }, + ] + } + ] + } +} \ No newline at end of file diff --git a/web/index.html b/web/index.html index a38b5e2..d3f04e1 100644 --- a/web/index.html +++ b/web/index.html @@ -42,12 +42,44 @@ +