feat: 完善数据中枢联邦查询闭环
- 重构数据源生命周期、元数据纳管与运行时切换 - 增加只读 SQL、查询审计、跨节点取消与工作流联动 - 完善管理端连接配置、元数据浏览与 SQL 工作台
This commit is contained in:
@@ -24,6 +24,11 @@ import java.util.List;
|
||||
@RequestMapping("/api/v1/datacenterDataset")
|
||||
public class DatacenterDatasetController {
|
||||
|
||||
/** 对外 Schema 接口的默认字段页码。 */
|
||||
private static final long DEFAULT_FIELD_PAGE_NUMBER = 1L;
|
||||
/** 对外 Schema 接口的默认字段页大小。 */
|
||||
private static final long DEFAULT_FIELD_PAGE_SIZE = 200L;
|
||||
|
||||
@Resource
|
||||
private DatacenterDatasetQueryService queryService;
|
||||
@Resource
|
||||
@@ -32,13 +37,18 @@ public class DatacenterDatasetController {
|
||||
@PostMapping("/queryPage")
|
||||
@SaCheckPermission("/api/v1/datacenterSource/query")
|
||||
public Result<Page<Row>> queryPage(@RequestBody DatacenterQueryRequest request) {
|
||||
return Result.ok(queryService.queryPage(request));
|
||||
return Result.ok(queryService.queryPage(
|
||||
request, SaTokenUtil.getLoginAccount()));
|
||||
}
|
||||
|
||||
@GetMapping("/schema")
|
||||
@SaCheckPermission("/api/v1/datacenterSource/query")
|
||||
public Result<DatacenterSchemaResponse> schema(DatasetRef datasetRef) {
|
||||
return Result.ok(queryService.getSchema(datasetRef));
|
||||
public Result<DatacenterSchemaResponse> schema(
|
||||
DatasetRef datasetRef,
|
||||
@RequestParam(defaultValue = "1") Long fieldPageNumber,
|
||||
@RequestParam(defaultValue = "200") Long fieldPageSize) {
|
||||
return Result.ok(queryService.getSchema(
|
||||
datasetRef, fieldPageNumber, fieldPageSize));
|
||||
}
|
||||
|
||||
@GetMapping("/managedTables")
|
||||
@@ -63,6 +73,13 @@ public class DatacenterDatasetController {
|
||||
request == null ? List.of() : request.getFields(),
|
||||
account
|
||||
);
|
||||
return Result.ok(queryService.getSchema(registryService.resolveDatasetRef(table.getId())));
|
||||
return Result.ok(queryService.getSchema(
|
||||
registryService.resolveDatasetRef(table.getId()),
|
||||
request == null || request.getFieldPageNumber() == null
|
||||
? DEFAULT_FIELD_PAGE_NUMBER
|
||||
: request.getFieldPageNumber(),
|
||||
request == null || request.getFieldPageSize() == null
|
||||
? DEFAULT_FIELD_PAGE_SIZE
|
||||
: request.getFieldPageSize()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
package tech.easyflow.admin.controller.datacenter;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import tech.easyflow.common.domain.Result;
|
||||
import tech.easyflow.common.entity.LoginAccount;
|
||||
import tech.easyflow.common.satoken.util.SaTokenUtil;
|
||||
import tech.easyflow.datacenter.execution.model.DatacenterSqlConsoleRequest;
|
||||
import tech.easyflow.datacenter.execution.model.DatacenterSqlConsoleResult;
|
||||
import tech.easyflow.datacenter.execution.model.DatacenterSqlCancelRequest;
|
||||
import tech.easyflow.datacenter.federation.DatacenterFederationQueryService;
|
||||
import tech.easyflow.datacenter.federation.DatacenterFederationQueryCancellationService;
|
||||
import tech.easyflow.datacenter.meta.entity.DatacenterSource;
|
||||
import tech.easyflow.datacenter.meta.service.DatacenterDatasetRegistryService;
|
||||
|
||||
/**
|
||||
* 数据中枢管理端只读 SQL 控制台。
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/datacenterQuery")
|
||||
public class DatacenterQueryController {
|
||||
|
||||
private final DatacenterDatasetRegistryService registryService;
|
||||
private final DatacenterFederationQueryService queryService;
|
||||
private final DatacenterFederationQueryCancellationService cancellationService;
|
||||
|
||||
/**
|
||||
* 创建查询 Controller。
|
||||
*
|
||||
* @param registryService 数据集注册服务
|
||||
* @param queryService Federation 查询服务
|
||||
* @param cancellationService 跨节点查询取消服务
|
||||
*/
|
||||
public DatacenterQueryController(
|
||||
DatacenterDatasetRegistryService registryService,
|
||||
DatacenterFederationQueryService queryService,
|
||||
DatacenterFederationQueryCancellationService cancellationService) {
|
||||
this.registryService = registryService;
|
||||
this.queryService = queryService;
|
||||
this.cancellationService = cancellationService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行一条受 Calcite 与业务 Policy 校验的只读 SQL。
|
||||
*
|
||||
* @param request 查询请求
|
||||
* @return 有界查询结果
|
||||
*/
|
||||
@PostMapping("/execute")
|
||||
@SaCheckPermission("/api/v1/datacenterSource/query")
|
||||
public Result<DatacenterSqlConsoleResult> execute(
|
||||
@RequestBody DatacenterSqlConsoleRequest request) {
|
||||
LoginAccount account = SaTokenUtil.getLoginAccount();
|
||||
DatacenterSource source = registryService.getSourceRequired(
|
||||
request == null ? null : request.sourceId());
|
||||
return Result.ok(queryService.execute(
|
||||
source,
|
||||
request == null ? null : request.sql(),
|
||||
java.util.List.of(),
|
||||
request == null ? null : request.maxRows(),
|
||||
account,
|
||||
"MANUAL",
|
||||
account == null || account.getId() == null
|
||||
? null : account.getId().toString(),
|
||||
request == null ? null : request.queryId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消当前租户在任一节点执行的 SQL 查询。
|
||||
*
|
||||
* @param request 取消请求
|
||||
* @return 是否在本地或集群中接受取消提示
|
||||
*/
|
||||
@PostMapping("/cancel")
|
||||
@SaCheckPermission("/api/v1/datacenterSource/query")
|
||||
public Result<Boolean> cancel(@RequestBody DatacenterSqlCancelRequest request) {
|
||||
LoginAccount account = SaTokenUtil.getLoginAccount();
|
||||
return Result.ok(cancellationService.cancel(
|
||||
request == null ? null : request.queryId(), account));
|
||||
}
|
||||
}
|
||||
@@ -8,10 +8,16 @@ import tech.easyflow.common.entity.LoginAccount;
|
||||
import tech.easyflow.common.satoken.util.SaTokenUtil;
|
||||
import tech.easyflow.datacenter.entity.DatacenterTable;
|
||||
import tech.easyflow.datacenter.execution.model.DatacenterConnectionTestResult;
|
||||
import tech.easyflow.datacenter.meta.entity.DatacenterSource;
|
||||
import tech.easyflow.datacenter.meta.model.DatacenterBatchRegisterRequest;
|
||||
import tech.easyflow.datacenter.meta.model.DatacenterCatalogMeta;
|
||||
import tech.easyflow.datacenter.meta.model.DatacenterMetadataPage;
|
||||
import tech.easyflow.datacenter.meta.model.DatacenterRemoveSourceRequest;
|
||||
import tech.easyflow.datacenter.meta.model.DatacenterSourceActivateRequest;
|
||||
import tech.easyflow.datacenter.meta.model.DatacenterSourceCandidateMetadataRequest;
|
||||
import tech.easyflow.datacenter.meta.model.DatacenterSourceCandidateCatalogRequest;
|
||||
import tech.easyflow.datacenter.meta.model.DatacenterSourceDraftRequest;
|
||||
import tech.easyflow.datacenter.meta.model.DatacenterSourceReconfigureRequest;
|
||||
import tech.easyflow.datacenter.meta.model.DatacenterSourceView;
|
||||
import tech.easyflow.datacenter.meta.model.DatacenterTableDetailMeta;
|
||||
import tech.easyflow.datacenter.meta.service.DatacenterSourceService;
|
||||
|
||||
@@ -19,6 +25,9 @@ import javax.annotation.Resource;
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 数据源绑定、生命周期与元数据浏览接口。
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/datacenterSource")
|
||||
public class DatacenterSourceController {
|
||||
@@ -26,23 +35,100 @@ public class DatacenterSourceController {
|
||||
@Resource
|
||||
private DatacenterSourceService sourceService;
|
||||
|
||||
@PostMapping("/testConnection")
|
||||
@SaCheckPermission("/api/v1/datacenterSource/query")
|
||||
public Result<DatacenterConnectionTestResult> testConnection(@RequestBody DatacenterSource source) {
|
||||
@PostMapping("/draft")
|
||||
@SaCheckPermission("/api/v1/datacenterSource/save")
|
||||
public Result<DatacenterSourceView> saveDraft(@RequestBody DatacenterSourceDraftRequest request) {
|
||||
LoginAccount account = SaTokenUtil.getLoginAccount();
|
||||
return Result.ok(sourceService.testConnection(source, account));
|
||||
return Result.ok(sourceService.saveDraft(request, account));
|
||||
}
|
||||
|
||||
@PostMapping("/save")
|
||||
@SaCheckPermission("/api/v1/datacenterSource/save")
|
||||
public Result<DatacenterSource> save(@RequestBody DatacenterSource source) {
|
||||
@PostMapping("/{sourceId}/probe")
|
||||
@SaCheckPermission("/api/v1/datacenterSource/query")
|
||||
public Result<DatacenterConnectionTestResult> probe(@PathVariable BigInteger sourceId) {
|
||||
LoginAccount account = SaTokenUtil.getLoginAccount();
|
||||
return Result.ok(sourceService.saveSource(source, account));
|
||||
return Result.ok(sourceService.probe(sourceId, account));
|
||||
}
|
||||
|
||||
@PostMapping("/activate")
|
||||
@SaCheckPermission("/api/v1/datacenterSource/save")
|
||||
public Result<DatacenterSourceView> activate(@RequestBody DatacenterSourceActivateRequest request) {
|
||||
LoginAccount account = SaTokenUtil.getLoginAccount();
|
||||
return Result.ok(sourceService.activate(request, account));
|
||||
}
|
||||
|
||||
/**
|
||||
* 探测活动数据源的未发布候选配置。
|
||||
*
|
||||
* @param request 候选连接配置
|
||||
* @return 连接探测结果
|
||||
*/
|
||||
@PostMapping("/candidate/probe")
|
||||
@SaCheckPermission("/api/v1/datacenterSource/save")
|
||||
public Result<DatacenterConnectionTestResult> probeCandidate(
|
||||
@RequestBody DatacenterSourceDraftRequest request) {
|
||||
return Result.ok(sourceService.probeCandidate(
|
||||
request, SaTokenUtil.getLoginAccount()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 浏览活动数据源候选配置可访问的命名空间。
|
||||
*
|
||||
* @param request 候选连接配置
|
||||
* @return 命名空间列表
|
||||
*/
|
||||
@PostMapping("/candidate/catalogs")
|
||||
@SaCheckPermission("/api/v1/datacenterSource/save")
|
||||
public Result<List<DatacenterCatalogMeta>> candidateCatalogs(
|
||||
@RequestBody DatacenterSourceDraftRequest request) {
|
||||
return Result.ok(sourceService.listCandidateCatalogs(
|
||||
request, SaTokenUtil.getLoginAccount()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页浏览候选配置可访问的命名空间。
|
||||
*
|
||||
* @param request 候选配置和分页条件
|
||||
* @return 有界命名空间列表
|
||||
*/
|
||||
@PostMapping("/candidate/catalogs/page")
|
||||
@SaCheckPermission("/api/v1/datacenterSource/save")
|
||||
public Result<DatacenterMetadataPage<DatacenterCatalogMeta>> candidateCatalogsPage(
|
||||
@RequestBody DatacenterSourceCandidateCatalogRequest request) {
|
||||
return Result.ok(sourceService.listCandidateCatalogsPage(
|
||||
request, SaTokenUtil.getLoginAccount()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页浏览活动数据源候选配置可访问的表。
|
||||
*
|
||||
* @param request 候选配置与分页条件
|
||||
* @return 有界表列表
|
||||
*/
|
||||
@PostMapping("/candidate/tables")
|
||||
@SaCheckPermission("/api/v1/datacenterSource/save")
|
||||
public Result<DatacenterMetadataPage<DatacenterTable>> candidateTables(
|
||||
@RequestBody DatacenterSourceCandidateMetadataRequest request) {
|
||||
return Result.ok(sourceService.listCandidateTables(
|
||||
request, SaTokenUtil.getLoginAccount()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 原地发布活动数据源的新连接配置和纳管范围。
|
||||
*
|
||||
* @param request 重配置请求
|
||||
* @return 发布后的数据源视图
|
||||
*/
|
||||
@PostMapping("/reconfigure")
|
||||
@SaCheckPermission("/api/v1/datacenterSource/save")
|
||||
public Result<DatacenterSourceView> reconfigure(
|
||||
@RequestBody DatacenterSourceReconfigureRequest request) {
|
||||
return Result.ok(sourceService.reconfigure(
|
||||
request, SaTokenUtil.getLoginAccount()));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@SaCheckPermission("/api/v1/datacenterSource/query")
|
||||
public Result<Page<DatacenterSource>> page(Long pageNumber, Long pageSize) {
|
||||
public Result<Page<DatacenterSourceView>> page(Long pageNumber, Long pageSize) {
|
||||
LoginAccount account = SaTokenUtil.getLoginAccount();
|
||||
return Result.ok(sourceService.pageSources(pageNumber, pageSize, account));
|
||||
}
|
||||
@@ -54,19 +140,53 @@ public class DatacenterSourceController {
|
||||
return Result.ok(sourceService.listCatalogs(sourceId, account));
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页浏览当前数据源的命名空间。
|
||||
*
|
||||
* @param sourceId 数据源 ID
|
||||
* @param keyword 名称搜索词
|
||||
* @param pageNumber 页码
|
||||
* @param pageSize 每页大小
|
||||
* @return 有界命名空间列表
|
||||
*/
|
||||
@GetMapping("/catalogs/page")
|
||||
@SaCheckPermission("/api/v1/datacenterSource/query")
|
||||
public Result<DatacenterMetadataPage<DatacenterCatalogMeta>> catalogsPage(
|
||||
BigInteger sourceId,
|
||||
String keyword,
|
||||
Long pageNumber,
|
||||
Long pageSize) {
|
||||
return Result.ok(sourceService.listCatalogsPage(
|
||||
sourceId, keyword, pageNumber, pageSize,
|
||||
SaTokenUtil.getLoginAccount()));
|
||||
}
|
||||
|
||||
@GetMapping("/tables")
|
||||
@SaCheckPermission("/api/v1/datacenterSource/query")
|
||||
public Result<List<DatacenterTable>> tables(BigInteger sourceId, String catalogName) {
|
||||
public Result<DatacenterMetadataPage<DatacenterTable>> tables(
|
||||
BigInteger sourceId,
|
||||
String catalogName,
|
||||
String keyword,
|
||||
Long pageNumber,
|
||||
Long pageSize) {
|
||||
LoginAccount account = SaTokenUtil.getLoginAccount();
|
||||
return Result.ok(sourceService.listTables(sourceId, catalogName, account));
|
||||
return Result.ok(sourceService.listTables(
|
||||
sourceId, catalogName, keyword, pageNumber, pageSize, account));
|
||||
}
|
||||
|
||||
@GetMapping("/tableDetail")
|
||||
@SaCheckPermission("/api/v1/datacenterSource/query")
|
||||
public Result<DatacenterTableDetailMeta> tableDetail(BigInteger sourceId, String catalogName, String tableName,
|
||||
@RequestParam(defaultValue = "false") boolean register) {
|
||||
public Result<DatacenterTableDetailMeta> tableDetail(
|
||||
BigInteger sourceId,
|
||||
String catalogName,
|
||||
String tableName,
|
||||
@RequestParam(defaultValue = "false") boolean register,
|
||||
Long fieldPageNumber,
|
||||
Long fieldPageSize) {
|
||||
LoginAccount account = SaTokenUtil.getLoginAccount();
|
||||
return Result.ok(sourceService.getTableDetail(sourceId, catalogName, tableName, register, account));
|
||||
return Result.ok(sourceService.getTableDetail(
|
||||
sourceId, catalogName, tableName, register,
|
||||
fieldPageNumber, fieldPageSize, account));
|
||||
}
|
||||
|
||||
@PostMapping("/registerBatch")
|
||||
@@ -83,4 +203,44 @@ public class DatacenterSourceController {
|
||||
sourceService.removeSource(request == null ? null : request.getSourceId(), account);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 停用活动数据源。
|
||||
*
|
||||
* @param sourceId 数据源 ID
|
||||
* @return 停用后的数据源视图
|
||||
*/
|
||||
@PostMapping("/{sourceId}/disable")
|
||||
@SaCheckPermission("/api/v1/datacenterSource/save")
|
||||
public Result<DatacenterSourceView> disable(@PathVariable BigInteger sourceId) {
|
||||
return Result.ok(sourceService.disable(
|
||||
sourceId, SaTokenUtil.getLoginAccount()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新启用已停用数据源。
|
||||
*
|
||||
* @param sourceId 数据源 ID
|
||||
* @return 启用后的数据源视图
|
||||
*/
|
||||
@PostMapping("/{sourceId}/enable")
|
||||
@SaCheckPermission("/api/v1/datacenterSource/save")
|
||||
public Result<DatacenterSourceView> enable(@PathVariable BigInteger sourceId) {
|
||||
return Result.ok(sourceService.enable(
|
||||
sourceId, SaTokenUtil.getLoginAccount()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新已纳管对象的 JDBC 元数据观测状态。
|
||||
*
|
||||
* @param sourceId 数据源 ID
|
||||
* @return 刷新后的数据源视图
|
||||
*/
|
||||
@PostMapping("/{sourceId}/metadata/refresh")
|
||||
@SaCheckPermission("/api/v1/datacenterSource/save")
|
||||
public Result<DatacenterSourceView> refreshMetadata(
|
||||
@PathVariable BigInteger sourceId) {
|
||||
return Result.ok(sourceService.refreshMetadata(
|
||||
sourceId, SaTokenUtil.getLoginAccount()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,6 +126,7 @@ public record WorkflowDesignerOptionsView(
|
||||
* 已接入数据集安全选项。
|
||||
*
|
||||
* @param id 数据集 ID
|
||||
* @param tenantId 租户 ID
|
||||
* @param sourceId 数据源 ID
|
||||
* @param catalogId 目录 ID
|
||||
* @param tableName 数据表名称
|
||||
@@ -133,6 +134,7 @@ public record WorkflowDesignerOptionsView(
|
||||
*/
|
||||
public record DatasetOption(
|
||||
@JsonSerialize(using = ToStringSerializer.class) BigInteger id,
|
||||
@JsonSerialize(using = ToStringSerializer.class) BigInteger tenantId,
|
||||
@JsonSerialize(using = ToStringSerializer.class) BigInteger sourceId,
|
||||
@JsonSerialize(using = ToStringSerializer.class) BigInteger catalogId,
|
||||
String tableName,
|
||||
|
||||
@@ -653,6 +653,7 @@ public class WorkflowDesignerOptionService {
|
||||
private WorkflowDesignerOptionsView.DatasetOption toDatasetOption(DatacenterTable table) {
|
||||
return new WorkflowDesignerOptionsView.DatasetOption(
|
||||
table.getId(),
|
||||
table.getTenantId(),
|
||||
table.getSourceId(),
|
||||
table.getCatalogId(),
|
||||
table.getTableName(),
|
||||
|
||||
Reference in New Issue
Block a user