diff --git a/paimon-web-api/src/main/java/org/apache/paimon/web/api/catalog/PaimonService.java b/paimon-web-api/src/main/java/org/apache/paimon/web/api/catalog/PaimonService.java index bd92a4c34..78c84124b 100644 --- a/paimon-web-api/src/main/java/org/apache/paimon/web/api/catalog/PaimonService.java +++ b/paimon-web-api/src/main/java/org/apache/paimon/web/api/catalog/PaimonService.java @@ -28,9 +28,9 @@ import org.apache.paimon.web.api.exception.ColumnException; import org.apache.paimon.web.api.exception.DatabaseException; import org.apache.paimon.web.api.exception.TableException; -import org.apache.paimon.web.api.table.ColumnMetadata; import org.apache.paimon.web.api.table.TableChange; -import org.apache.paimon.web.api.table.TableMetadata; +import org.apache.paimon.web.api.table.metadata.ColumnMetadata; +import org.apache.paimon.web.api.table.metadata.TableMetadata; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; diff --git a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/TableChange.java b/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/TableChange.java index ec0f39263..c9f891fb1 100644 --- a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/TableChange.java +++ b/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/TableChange.java @@ -19,6 +19,7 @@ package org.apache.paimon.web.api.table; import org.apache.paimon.types.DataType; +import org.apache.paimon.web.api.table.metadata.ColumnMetadata; import javax.annotation.Nullable; diff --git a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/TableManager.java b/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/TableManager.java index 3e18828ba..ddbe3a0ec 100644 --- a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/TableManager.java +++ b/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/TableManager.java @@ -48,6 +48,15 @@ import org.apache.paimon.web.api.common.MetastoreType; import org.apache.paimon.web.api.common.OperatorKind; import org.apache.paimon.web.api.common.WriteMode; +import org.apache.paimon.web.api.table.metadata.ColumnMetadata; +import org.apache.paimon.web.api.table.metadata.ConsumerTableMetadata; +import org.apache.paimon.web.api.table.metadata.FileTableMetadata; +import org.apache.paimon.web.api.table.metadata.ManifestTableMetadata; +import org.apache.paimon.web.api.table.metadata.OptionTableMetadata; +import org.apache.paimon.web.api.table.metadata.SchemaTableMetadata; +import org.apache.paimon.web.api.table.metadata.SnapshotTableMetadata; +import org.apache.paimon.web.api.table.metadata.TableMetadata; +import org.apache.paimon.web.api.table.metadata.TagTableMetadata; import org.apache.paimon.web.common.annotation.VisibleForTesting; import org.apache.paimon.web.common.utils.ParameterValidationUtil; diff --git a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/ColumnMetadata.java b/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/ColumnMetadata.java similarity index 97% rename from paimon-web-api/src/main/java/org/apache/paimon/web/api/table/ColumnMetadata.java rename to paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/ColumnMetadata.java index 4d09c6e93..c97de6cb4 100644 --- a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/ColumnMetadata.java +++ b/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/ColumnMetadata.java @@ -16,7 +16,7 @@ * limitations under the License. */ -package org.apache.paimon.web.api.table; +package org.apache.paimon.web.api.table.metadata; import org.apache.paimon.types.DataType; diff --git a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/ConsumerTableMetadata.java b/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/ConsumerTableMetadata.java similarity index 96% rename from paimon-web-api/src/main/java/org/apache/paimon/web/api/table/ConsumerTableMetadata.java rename to paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/ConsumerTableMetadata.java index 12e52dd43..ec1f43641 100644 --- a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/ConsumerTableMetadata.java +++ b/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/ConsumerTableMetadata.java @@ -16,7 +16,7 @@ * limitations under the License. */ -package org.apache.paimon.web.api.table; +package org.apache.paimon.web.api.table.metadata; /** file table metadata. */ public class ConsumerTableMetadata { diff --git a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/FileTableMetadata.java b/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/FileTableMetadata.java similarity index 99% rename from paimon-web-api/src/main/java/org/apache/paimon/web/api/table/FileTableMetadata.java rename to paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/FileTableMetadata.java index 3c0776edb..a86295419 100644 --- a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/FileTableMetadata.java +++ b/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/FileTableMetadata.java @@ -16,7 +16,7 @@ * limitations under the License. */ -package org.apache.paimon.web.api.table; +package org.apache.paimon.web.api.table.metadata; import javax.annotation.Nullable; diff --git a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/ManifestTableMetadata.java b/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/ManifestTableMetadata.java similarity index 98% rename from paimon-web-api/src/main/java/org/apache/paimon/web/api/table/ManifestTableMetadata.java rename to paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/ManifestTableMetadata.java index 574899ce4..e944eb739 100644 --- a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/ManifestTableMetadata.java +++ b/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/ManifestTableMetadata.java @@ -16,7 +16,7 @@ * limitations under the License. */ -package org.apache.paimon.web.api.table; +package org.apache.paimon.web.api.table.metadata; /** manifest table metadata. */ public class ManifestTableMetadata { diff --git a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/OptionTableMetadata.java b/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/OptionTableMetadata.java similarity index 96% rename from paimon-web-api/src/main/java/org/apache/paimon/web/api/table/OptionTableMetadata.java rename to paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/OptionTableMetadata.java index ec259e013..b8f046cf6 100644 --- a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/OptionTableMetadata.java +++ b/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/OptionTableMetadata.java @@ -16,7 +16,7 @@ * limitations under the License. */ -package org.apache.paimon.web.api.table; +package org.apache.paimon.web.api.table.metadata; /** options table metadata. */ public class OptionTableMetadata { diff --git a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/SchemaTableMetadata.java b/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/SchemaTableMetadata.java similarity index 98% rename from paimon-web-api/src/main/java/org/apache/paimon/web/api/table/SchemaTableMetadata.java rename to paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/SchemaTableMetadata.java index e9744e5b5..477117038 100644 --- a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/SchemaTableMetadata.java +++ b/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/SchemaTableMetadata.java @@ -16,7 +16,7 @@ * limitations under the License. */ -package org.apache.paimon.web.api.table; +package org.apache.paimon.web.api.table.metadata; import javax.annotation.Nullable; diff --git a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/SnapshotTableMetadata.java b/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/SnapshotTableMetadata.java similarity index 99% rename from paimon-web-api/src/main/java/org/apache/paimon/web/api/table/SnapshotTableMetadata.java rename to paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/SnapshotTableMetadata.java index 9bc0bd4f5..e326b6ff5 100644 --- a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/SnapshotTableMetadata.java +++ b/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/SnapshotTableMetadata.java @@ -16,7 +16,7 @@ * limitations under the License. */ -package org.apache.paimon.web.api.table; +package org.apache.paimon.web.api.table.metadata; import javax.annotation.Nullable; diff --git a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/TableMetadata.java b/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/TableMetadata.java similarity index 99% rename from paimon-web-api/src/main/java/org/apache/paimon/web/api/table/TableMetadata.java rename to paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/TableMetadata.java index 89d02f49b..9c9e0c57c 100644 --- a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/TableMetadata.java +++ b/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/TableMetadata.java @@ -16,7 +16,7 @@ * limitations under the License. */ -package org.apache.paimon.web.api.table; +package org.apache.paimon.web.api.table.metadata; import com.google.common.base.Preconditions; diff --git a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/TagTableMetadata.java b/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/TagTableMetadata.java similarity index 98% rename from paimon-web-api/src/main/java/org/apache/paimon/web/api/table/TagTableMetadata.java rename to paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/TagTableMetadata.java index f26170c7b..6e16219ce 100644 --- a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/TagTableMetadata.java +++ b/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/TagTableMetadata.java @@ -16,7 +16,7 @@ * limitations under the License. */ -package org.apache.paimon.web.api.table; +package org.apache.paimon.web.api.table.metadata; import javax.annotation.Nullable; diff --git a/paimon-web-api/src/test/java/org/apache/paimon/web/api/catalog/PaimonServiceTest.java b/paimon-web-api/src/test/java/org/apache/paimon/web/api/catalog/PaimonServiceTest.java index 37af5de7a..cec1294ca 100644 --- a/paimon-web-api/src/test/java/org/apache/paimon/web/api/catalog/PaimonServiceTest.java +++ b/paimon-web-api/src/test/java/org/apache/paimon/web/api/catalog/PaimonServiceTest.java @@ -23,9 +23,9 @@ import org.apache.paimon.types.DataTypes; import org.apache.paimon.web.api.exception.DatabaseException; import org.apache.paimon.web.api.exception.TableException; -import org.apache.paimon.web.api.table.ColumnMetadata; import org.apache.paimon.web.api.table.TableChange; -import org.apache.paimon.web.api.table.TableMetadata; +import org.apache.paimon.web.api.table.metadata.ColumnMetadata; +import org.apache.paimon.web.api.table.metadata.TableMetadata; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; diff --git a/paimon-web-api/src/test/java/org/apache/paimon/web/api/table/TableManagerTest.java b/paimon-web-api/src/test/java/org/apache/paimon/web/api/table/TableManagerTest.java index a60ef27e9..54fa05f08 100644 --- a/paimon-web-api/src/test/java/org/apache/paimon/web/api/table/TableManagerTest.java +++ b/paimon-web-api/src/test/java/org/apache/paimon/web/api/table/TableManagerTest.java @@ -23,6 +23,8 @@ import org.apache.paimon.types.DataTypes; import org.apache.paimon.web.api.catalog.CatalogCreator; import org.apache.paimon.web.api.database.DatabaseManager; +import org.apache.paimon.web.api.table.metadata.ColumnMetadata; +import org.apache.paimon.web.api.table.metadata.TableMetadata; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; diff --git a/paimon-web-server/pom.xml b/paimon-web-server/pom.xml index 02ec9b71e..b6f30d656 100644 --- a/paimon-web-server/pom.xml +++ b/paimon-web-server/pom.xml @@ -172,6 +172,11 @@ under the License. ${hadoop.version} provided + + + com.google.code.gson + gson + diff --git a/paimon-web-server/src/main/java/org/apache/paimon/web/server/constant/MetadataConstant.java b/paimon-web-server/src/main/java/org/apache/paimon/web/server/constant/MetadataConstant.java new file mode 100644 index 000000000..54c66e95e --- /dev/null +++ b/paimon-web-server/src/main/java/org/apache/paimon/web/server/constant/MetadataConstant.java @@ -0,0 +1,31 @@ +/* + * 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.paimon.web.server.constant; + +/** Metadata constant. */ +public class MetadataConstant { + public static final String SNAPSHOTS = "snapshots"; + public static final String SCHEMAS = "schemas"; + public static final String OPTIONS = "options"; + public static final String MANIFESTS = "manifests"; + public static final String FILES = "files"; + public static final String CONSUMER = "consumers"; + public static final String TAGS = "tags"; + public static final String METADATA_TABLE_FORMAT = "%s$%s"; +} diff --git a/paimon-web-server/src/main/java/org/apache/paimon/web/server/controller/DatabaseController.java b/paimon-web-server/src/main/java/org/apache/paimon/web/server/controller/DatabaseController.java index d70454be7..395417e4e 100644 --- a/paimon-web-server/src/main/java/org/apache/paimon/web/server/controller/DatabaseController.java +++ b/paimon-web-server/src/main/java/org/apache/paimon/web/server/controller/DatabaseController.java @@ -79,7 +79,7 @@ public R createDatabase(@RequestBody DatabaseDTO databaseDTO) { } /** - * /** Get all database information. + * Get all database information. * * @return The list of all databases. */ diff --git a/paimon-web-server/src/main/java/org/apache/paimon/web/server/controller/LoginController.java b/paimon-web-server/src/main/java/org/apache/paimon/web/server/controller/LoginController.java index e30af771a..409598f1e 100644 --- a/paimon-web-server/src/main/java/org/apache/paimon/web/server/controller/LoginController.java +++ b/paimon-web-server/src/main/java/org/apache/paimon/web/server/controller/LoginController.java @@ -20,7 +20,7 @@ import org.apache.paimon.web.server.data.dto.LoginDTO; import org.apache.paimon.web.server.data.result.R; -import org.apache.paimon.web.server.data.vo.UserInfoVo; +import org.apache.paimon.web.server.data.vo.UserInfoVO; import org.apache.paimon.web.server.service.UserService; import cn.dev33.satoken.stp.SaTokenInfo; @@ -48,7 +48,7 @@ public class LoginController { * @return token string */ @PostMapping("/login") - public R login(@RequestBody LoginDTO loginDTO) { + public R login(@RequestBody LoginDTO loginDTO) { return R.succeed(userService.login(loginDTO)); } diff --git a/paimon-web-server/src/main/java/org/apache/paimon/web/server/controller/MetadataController.java b/paimon-web-server/src/main/java/org/apache/paimon/web/server/controller/MetadataController.java new file mode 100644 index 000000000..1435219bd --- /dev/null +++ b/paimon-web-server/src/main/java/org/apache/paimon/web/server/controller/MetadataController.java @@ -0,0 +1,68 @@ +/* + * 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.paimon.web.server.controller; + +import org.apache.paimon.web.server.data.dto.QueryMetadataDTO; +import org.apache.paimon.web.server.data.result.R; +import org.apache.paimon.web.server.data.vo.DataFileVO; +import org.apache.paimon.web.server.data.vo.ManifestsVO; +import org.apache.paimon.web.server.data.vo.SchemaVO; +import org.apache.paimon.web.server.data.vo.SnapshotVO; +import org.apache.paimon.web.server.service.MetadataService; + +import lombok.extern.slf4j.Slf4j; +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 java.util.List; + +/** Metadata api controller. */ +@Slf4j +@RestController +@RequestMapping("/api/metadata/query") +public class MetadataController { + + private final MetadataService metadataService; + + public MetadataController(MetadataService metadataService) { + this.metadataService = metadataService; + } + + @PostMapping("/schema") + public R> getSchemaInfo(@RequestBody QueryMetadataDTO dto) { + return R.succeed(metadataService.getSchema(dto)); + } + + @PostMapping("/snapshot") + public R> getSnapshotInfo(@RequestBody QueryMetadataDTO dto) { + return R.succeed(metadataService.getSnapshot(dto)); + } + + @PostMapping("/manifest") + public R> getManifestInfo(@RequestBody QueryMetadataDTO dto) { + return R.succeed(metadataService.getManifest(dto)); + } + + @PostMapping("/dataFile") + public R> getDataFileInfo(@RequestBody QueryMetadataDTO dto) { + return R.succeed(metadataService.getDataFile(dto)); + } +} diff --git a/paimon-web-server/src/main/java/org/apache/paimon/web/server/controller/SysMenuController.java b/paimon-web-server/src/main/java/org/apache/paimon/web/server/controller/SysMenuController.java index d61359480..102fe2b3e 100644 --- a/paimon-web-server/src/main/java/org/apache/paimon/web/server/controller/SysMenuController.java +++ b/paimon-web-server/src/main/java/org/apache/paimon/web/server/controller/SysMenuController.java @@ -23,8 +23,8 @@ import org.apache.paimon.web.server.data.result.R; import org.apache.paimon.web.server.data.result.enums.Status; import org.apache.paimon.web.server.data.tree.TreeSelect; -import org.apache.paimon.web.server.data.vo.RoleMenuTreeselectVo; -import org.apache.paimon.web.server.data.vo.RouterVo; +import org.apache.paimon.web.server.data.vo.RoleMenuTreeselectVO; +import org.apache.paimon.web.server.data.vo.RouterVO; import org.apache.paimon.web.server.service.SysMenuService; import org.apache.paimon.web.server.util.StringUtils; @@ -73,12 +73,12 @@ public R> treeselect(SysMenu menu) { /** Load the corresponding character menu list tree. */ @GetMapping(value = "/roleMenuTreeselect/{roleId}") - public R roleMenuTreeselect(@PathVariable("roleId") Integer roleId) { + public R roleMenuTreeselect(@PathVariable("roleId") Integer roleId) { List menus = menuService.selectMenuList(); List treeMenus = menuService.buildMenuTreeSelect(menus); List checkedKeys = menuService.selectMenuListByRoleId(roleId); - return R.succeed(new RoleMenuTreeselectVo(checkedKeys, treeMenus)); + return R.succeed(new RoleMenuTreeselectVO(checkedKeys, treeMenus)); } /** add new menu. */ @@ -119,7 +119,7 @@ public R remove(@PathVariable("menuId") Integer menuId) { /** Get router list. */ @GetMapping("/getRouters") - public R> getRouters() { + public R> getRouters() { int userId = StpUtil.getLoginIdAsInt(); List menus = menuService.selectMenuTreeByUserId(userId); return R.succeed(menuService.buildMenus(menus)); diff --git a/paimon-web-server/src/main/java/org/apache/paimon/web/server/controller/TableController.java b/paimon-web-server/src/main/java/org/apache/paimon/web/server/controller/TableController.java index 378464061..0c18f7555 100644 --- a/paimon-web-server/src/main/java/org/apache/paimon/web/server/controller/TableController.java +++ b/paimon-web-server/src/main/java/org/apache/paimon/web/server/controller/TableController.java @@ -21,9 +21,9 @@ import org.apache.paimon.table.Table; import org.apache.paimon.types.DataField; import org.apache.paimon.web.api.catalog.PaimonService; -import org.apache.paimon.web.api.table.ColumnMetadata; import org.apache.paimon.web.api.table.TableChange; -import org.apache.paimon.web.api.table.TableMetadata; +import org.apache.paimon.web.api.table.metadata.ColumnMetadata; +import org.apache.paimon.web.api.table.metadata.TableMetadata; import org.apache.paimon.web.server.data.dto.TableDTO; import org.apache.paimon.web.server.data.model.AlterTableRequest; import org.apache.paimon.web.server.data.model.CatalogInfo; diff --git a/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/dto/QueryMetadataDTO.java b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/dto/QueryMetadataDTO.java new file mode 100644 index 000000000..572c84a2e --- /dev/null +++ b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/dto/QueryMetadataDTO.java @@ -0,0 +1,32 @@ +/* + * 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.paimon.web.server.data.dto; + +import lombok.Data; + +/** DTO of query metadata is used for getting table metadata. */ +@Data +public class QueryMetadataDTO { + + private String catalogName; + + private String databaseName; + + private String tableName; +} diff --git a/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/model/MetadataFieldsModel.java b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/model/MetadataFieldsModel.java new file mode 100644 index 000000000..80805cb15 --- /dev/null +++ b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/model/MetadataFieldsModel.java @@ -0,0 +1,34 @@ +/* + * 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.paimon.web.server.data.model; + +import lombok.Data; + +/** Model of metadata fields. */ +@Data +public class MetadataFieldsModel { + + private int id; + + private String name; + + private String type; + + private String comment; +} diff --git a/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/model/MetadataOptionModel.java b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/model/MetadataOptionModel.java new file mode 100644 index 000000000..d2959face --- /dev/null +++ b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/model/MetadataOptionModel.java @@ -0,0 +1,34 @@ +/* + * 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.paimon.web.server.data.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** Model of metadata options. */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class MetadataOptionModel { + + private String key; + + private Object value; +} diff --git a/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/DataFileVO.java b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/DataFileVO.java new file mode 100644 index 000000000..b0fb46f8e --- /dev/null +++ b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/DataFileVO.java @@ -0,0 +1,38 @@ +/* + * 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.paimon.web.server.data.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** VO of metadata data file. */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class DataFileVO { + + private String partition; + + private long bucket; + + private String filePath; + + private String fileFormat; +} diff --git a/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/ManifestsVO.java b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/ManifestsVO.java new file mode 100644 index 000000000..6060bdfd0 --- /dev/null +++ b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/ManifestsVO.java @@ -0,0 +1,74 @@ +/* + * 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.paimon.web.server.data.vo; + +/** VO of metadata manifest. */ +public class ManifestsVO { + private final String fileName; + private final Long fileSize; + private final Long numAddedFiles; + + public ManifestsVO(String fileName, Long fileSize, Long numAddedFiles) { + this.fileName = fileName; + this.fileSize = fileSize; + this.numAddedFiles = numAddedFiles; + } + + public String getFileName() { + return fileName; + } + + public Long getFileSize() { + return fileSize; + } + + public Long getNumAddedFiles() { + return numAddedFiles; + } + + public static Builder builder() { + return new Builder(); + } + + /** ManifestsInfoVo Builder. */ + public static class Builder { + private String fileName; + private Long fileSize; + private Long numAddedFiles; + + public Builder setFileName(String fileName) { + this.fileName = fileName; + return this; + } + + public Builder setFileSize(Long fileSize) { + this.fileSize = fileSize; + return this; + } + + public Builder setNumAddedFiles(Long numAddedFiles) { + this.numAddedFiles = numAddedFiles; + return this; + } + + public ManifestsVO build() { + return new ManifestsVO(fileName, fileSize, numAddedFiles); + } + } +} diff --git a/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/MetaVo.java b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/MetaVO.java similarity index 88% rename from paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/MetaVo.java rename to paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/MetaVO.java index 19bf2a529..b48c90ebc 100644 --- a/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/MetaVo.java +++ b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/MetaVO.java @@ -21,7 +21,7 @@ import org.apache.paimon.web.server.util.StringUtils; /** Route display information. */ -public class MetaVo { +public class MetaVO { /** Set the name of the route displayed in the sidebar and Bread crumbs. */ private String title; @@ -34,26 +34,26 @@ public class MetaVo { /** link path. */ private String link; - public MetaVo() {} + public MetaVO() {} - public MetaVo(String title, String icon) { + public MetaVO(String title, String icon) { this.title = title; this.icon = icon; } - public MetaVo(String title, String icon, boolean noCache) { + public MetaVO(String title, String icon, boolean noCache) { this.title = title; this.icon = icon; this.noCache = noCache; } - public MetaVo(String title, String icon, String link) { + public MetaVO(String title, String icon, String link) { this.title = title; this.icon = icon; this.link = link; } - public MetaVo(String title, String icon, boolean noCache, String link) { + public MetaVO(String title, String icon, boolean noCache, String link) { this.title = title; this.icon = icon; this.noCache = noCache; diff --git a/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/RoleMenuTreeselectVo.java b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/RoleMenuTreeselectVO.java similarity index 95% rename from paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/RoleMenuTreeselectVo.java rename to paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/RoleMenuTreeselectVO.java index 11418bef1..c56a7081e 100644 --- a/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/RoleMenuTreeselectVo.java +++ b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/RoleMenuTreeselectVO.java @@ -27,11 +27,11 @@ /** Role Menu List Tree Vo. */ @Getter -public class RoleMenuTreeselectVo { +public class RoleMenuTreeselectVO { private final List checkedKeys; private final List menus; - public RoleMenuTreeselectVo( + public RoleMenuTreeselectVO( @JsonProperty("checkedKeys") List checkedKeys, @JsonProperty("menus") List menus) { this.checkedKeys = checkedKeys; diff --git a/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/RouterVo.java b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/RouterVO.java similarity index 92% rename from paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/RouterVo.java rename to paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/RouterVO.java index d485691ae..0322fffce 100644 --- a/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/RouterVo.java +++ b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/RouterVO.java @@ -24,7 +24,7 @@ /** route config info. */ @JsonInclude(JsonInclude.Include.NON_EMPTY) -public class RouterVo { +public class RouterVO { /** route name. */ private String name; @@ -56,10 +56,10 @@ public class RouterVo { private Boolean alwaysShow; /** other meta info. */ - private MetaVo meta; + private MetaVO meta; /** children route. */ - private List children; + private List children; public String getName() { return name; @@ -117,19 +117,19 @@ public void setAlwaysShow(Boolean alwaysShow) { this.alwaysShow = alwaysShow; } - public MetaVo getMeta() { + public MetaVO getMeta() { return meta; } - public void setMeta(MetaVo meta) { + public void setMeta(MetaVO meta) { this.meta = meta; } - public List getChildren() { + public List getChildren() { return children; } - public void setChildren(List children) { + public void setChildren(List children) { this.children = children; } } diff --git a/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/SchemaVO.java b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/SchemaVO.java new file mode 100644 index 000000000..1b5e18fe8 --- /dev/null +++ b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/SchemaVO.java @@ -0,0 +1,139 @@ +/* + * 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.paimon.web.server.data.vo; + +import org.apache.paimon.web.server.data.model.MetadataFieldsModel; +import org.apache.paimon.web.server.data.model.MetadataOptionModel; + +import javax.annotation.Nullable; + +import java.time.LocalDateTime; +import java.util.List; + +/** VO of metadata schema. */ +public class SchemaVO { + + private final Long schemaId; + private final List fields; + private final String partitionKeys; + private final String primaryKeys; + private final String comment; + private final List option; + private final LocalDateTime updateTime; + + public SchemaVO( + Long schemaId, + List fields, + String partitionKeys, + String primaryKeys, + String comment, + List option, + LocalDateTime updateTime) { + this.schemaId = schemaId; + this.fields = fields; + this.partitionKeys = partitionKeys; + this.primaryKeys = primaryKeys; + this.comment = comment; + this.option = option; + this.updateTime = updateTime; + } + + public Long getSchemaId() { + return schemaId; + } + + public List getFields() { + return fields; + } + + public String getPartitionKeys() { + return partitionKeys; + } + + public String getPrimaryKeys() { + return primaryKeys; + } + + public String getComment() { + return comment; + } + + public LocalDateTime getUpdateTime() { + return updateTime; + } + + public List getOption() { + return option; + } + + public static SchemaVO.Builder builder() { + return new Builder(); + } + + /** Builder for SchemaInfoVo. */ + public static class Builder { + private Long schemaId; + private List fields; + private String partitionKeys; + private String primaryKeys; + @Nullable private String comment; + @Nullable private List option; + private LocalDateTime updateTime; + + public Builder setSchemaId(Long schemaId) { + this.schemaId = schemaId; + return this; + } + + public Builder setFields(List fields) { + this.fields = fields; + return this; + } + + public Builder setPartitionKeys(String partitionKeys) { + this.partitionKeys = partitionKeys; + return this; + } + + public Builder setPrimaryKeys(String primaryKeys) { + this.primaryKeys = primaryKeys; + return this; + } + + public Builder setComment(String comment) { + this.comment = comment; + return this; + } + + public Builder setOption(List option) { + this.option = option; + return this; + } + + public Builder setUpdateTime(LocalDateTime updateTime) { + this.updateTime = updateTime; + return this; + } + + public SchemaVO build() { + return new SchemaVO( + schemaId, fields, partitionKeys, primaryKeys, comment, option, updateTime); + } + } +} diff --git a/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/SnapshotVO.java b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/SnapshotVO.java new file mode 100644 index 000000000..c79ffa734 --- /dev/null +++ b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/SnapshotVO.java @@ -0,0 +1,89 @@ +/* + * 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.paimon.web.server.data.vo; + +import java.time.LocalDateTime; + +/** VO of metadata snapshot. */ +public class SnapshotVO { + private final Long snapshotId; + private final Long schemaId; + private final Long commitIdentifier; + private final LocalDateTime commitTime; + + public SnapshotVO( + Long snapshotId, Long schemaId, Long commitIdentifier, LocalDateTime commitTime) { + this.snapshotId = snapshotId; + this.schemaId = schemaId; + this.commitIdentifier = commitIdentifier; + this.commitTime = commitTime; + } + + public Long getSnapshotId() { + return snapshotId; + } + + public Long getSchemaId() { + return schemaId; + } + + public Long getCommitIdentifier() { + return commitIdentifier; + } + + public LocalDateTime getCommitTime() { + return commitTime; + } + + public static Builder builder() { + return new Builder(); + } + + /** Builder for SnapshotInfoVo. */ + public static class Builder { + private Long snapshotId; + private Long schemaId; + private Long commitIdentifier; + private LocalDateTime commitTime; + + public Builder setSnapshotId(Long snapshotId) { + this.snapshotId = snapshotId; + return this; + } + + public Builder setSchemaId(Long schemaId) { + this.schemaId = schemaId; + return this; + } + + public Builder setCommitIdentifier(Long commitIdentifier) { + this.commitIdentifier = commitIdentifier; + return this; + } + + public Builder setCommitTime(LocalDateTime commitTime) { + this.commitTime = commitTime; + return this; + } + + public SnapshotVO build() { + return new SnapshotVO(snapshotId, schemaId, commitIdentifier, commitTime); + } + } +} diff --git a/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/UserInfoVo.java b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/UserInfoVO.java similarity index 98% rename from paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/UserInfoVo.java rename to paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/UserInfoVO.java index fdd08e20d..f8c23ab5d 100644 --- a/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/UserInfoVo.java +++ b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/UserInfoVO.java @@ -31,7 +31,7 @@ /** user data transfer object. */ @Data -public class UserInfoVo { +public class UserInfoVO { /** current user info. */ private User user; /** current user's tenant list. */ diff --git a/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/MetadataService.java b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/MetadataService.java new file mode 100644 index 000000000..7c5cea5e3 --- /dev/null +++ b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/MetadataService.java @@ -0,0 +1,63 @@ +/* + * 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.paimon.web.server.service; + +import org.apache.paimon.web.server.data.dto.QueryMetadataDTO; +import org.apache.paimon.web.server.data.vo.DataFileVO; +import org.apache.paimon.web.server.data.vo.ManifestsVO; +import org.apache.paimon.web.server.data.vo.SchemaVO; +import org.apache.paimon.web.server.data.vo.SnapshotVO; + +import java.util.List; + +/** Metadata service includes the service interfaces of metadata. */ +public interface MetadataService { + + /** + * Retrieves a list of Metadata schema. + * + * @param dto query metadata info + * @return a list of DatabaseInfo objects + */ + List getSchema(QueryMetadataDTO dto); + + /** + * Retrieves a list of Metadata snapshot. + * + * @param dto query metadata info + * @return a list of snapshot objects + */ + List getSnapshot(QueryMetadataDTO dto); + + /** + * Retrieves a list of Metadata manifest. + * + * @param dto query metadata info + * @return a list of manifest info objects + */ + List getManifest(QueryMetadataDTO dto); + + /** + * Retrieves a list of Metadata data file. + * + * @param dto query metadata info + * @return a list of data file objects + */ + List getDataFile(QueryMetadataDTO dto); +} diff --git a/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/SysMenuService.java b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/SysMenuService.java index 4bc9072ae..d6ad1c149 100644 --- a/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/SysMenuService.java +++ b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/SysMenuService.java @@ -20,7 +20,7 @@ import org.apache.paimon.web.server.data.model.SysMenu; import org.apache.paimon.web.server.data.tree.TreeSelect; -import org.apache.paimon.web.server.data.vo.RouterVo; +import org.apache.paimon.web.server.data.vo.RouterVO; import com.baomidou.mybatisplus.extension.service.IService; @@ -82,7 +82,7 @@ public interface SysMenuService extends IService { * @param menus menu list * @return router list */ - List buildMenus(List menus); + List buildMenus(List menus); /** * Builder menu tree. diff --git a/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/UserService.java b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/UserService.java index b91af006b..f30dc7b2b 100644 --- a/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/UserService.java +++ b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/UserService.java @@ -21,7 +21,7 @@ import org.apache.paimon.web.server.data.dto.LoginDTO; import org.apache.paimon.web.server.data.model.User; import org.apache.paimon.web.server.data.result.exception.BaseException; -import org.apache.paimon.web.server.data.vo.UserInfoVo; +import org.apache.paimon.web.server.data.vo.UserInfoVO; import com.baomidou.mybatisplus.extension.service.IService; @@ -36,7 +36,7 @@ public interface UserService extends IService { * @param loginDTO login params * @return {@link String} */ - UserInfoVo login(LoginDTO loginDTO) throws BaseException; + UserInfoVO login(LoginDTO loginDTO) throws BaseException; /** * Query the list of assigned user roles. diff --git a/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/MetadataServiceImpl.java b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/MetadataServiceImpl.java new file mode 100644 index 000000000..6bbac39a3 --- /dev/null +++ b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/MetadataServiceImpl.java @@ -0,0 +1,215 @@ +/* + * 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.paimon.web.server.service.impl; + +import org.apache.paimon.catalog.Catalog; +import org.apache.paimon.data.InternalRow; +import org.apache.paimon.reader.RecordReader; +import org.apache.paimon.table.Table; +import org.apache.paimon.table.source.ReadBuilder; +import org.apache.paimon.web.api.table.TableManager; +import org.apache.paimon.web.server.constant.MetadataConstant; +import org.apache.paimon.web.server.data.dto.QueryMetadataDTO; +import org.apache.paimon.web.server.data.model.CatalogInfo; +import org.apache.paimon.web.server.data.model.MetadataFieldsModel; +import org.apache.paimon.web.server.data.model.MetadataOptionModel; +import org.apache.paimon.web.server.data.vo.DataFileVO; +import org.apache.paimon.web.server.data.vo.ManifestsVO; +import org.apache.paimon.web.server.data.vo.SchemaVO; +import org.apache.paimon.web.server.data.vo.SnapshotVO; +import org.apache.paimon.web.server.service.CatalogService; +import org.apache.paimon.web.server.service.MetadataService; +import org.apache.paimon.web.server.util.PaimonServiceUtils; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** The implementation of {@link MetadataService}. */ +@Service +@Slf4j +public class MetadataServiceImpl implements MetadataService { + + private final CatalogService catalogService; + + public MetadataServiceImpl(CatalogService catalogService) { + this.catalogService = catalogService; + } + + private RecordReader reader; + + @Override + public List getSchema(QueryMetadataDTO dto) { + + initEnvironment(dto, MetadataConstant.SCHEMAS); + + List result = new LinkedList<>(); + try { + reader.forEachRemaining( + internalRow -> { + SchemaVO schemaVo = + SchemaVO.builder() + .setSchemaId(internalRow.getLong(0)) + .setFields( + new Gson() + .fromJson( + internalRow.getString(1).toString(), + new TypeToken< + LinkedList< + MetadataFieldsModel>>() {})) + .setPartitionKeys(internalRow.getString(2).toString()) + .setPrimaryKeys(internalRow.getString(3).toString()) + .setOption( + formatOptions(internalRow.getString(4).toString())) + .setComment(internalRow.getString(5).toString()) + .setUpdateTime( + internalRow.getTimestamp(6, 3).toLocalDateTime()) + .build(); + result.add(schemaVo); + }); + } catch (IOException e) { + throw new RuntimeException(e); + } + + return result; + } + + @Override + public List getSnapshot(QueryMetadataDTO dto) { + + initEnvironment(dto, MetadataConstant.SNAPSHOTS); + + List result = new LinkedList<>(); + + try { + reader.forEachRemaining( + internalRow -> { + SnapshotVO build = + SnapshotVO.builder() + .setSnapshotId(internalRow.getLong(0)) + .setSnapshotId(internalRow.getLong(1)) + .setCommitIdentifier(internalRow.getLong(3)) + .setCommitTime( + internalRow.getTimestamp(5, 3).toLocalDateTime()) + .build(); + result.add(build); + }); + } catch (IOException e) { + throw new RuntimeException(e); + } + + return result; + } + + @Override + public List getManifest(QueryMetadataDTO dto) { + initEnvironment(dto, MetadataConstant.MANIFESTS); + + List result = new LinkedList<>(); + + try { + reader.forEachRemaining( + internalRow -> { + ManifestsVO manifestsVo = + ManifestsVO.builder() + .setFileName(internalRow.getString(0).toString()) + .setFileSize(internalRow.getLong(1)) + .setNumAddedFiles(internalRow.getLong(2)) + .build(); + result.add(manifestsVo); + }); + } catch (IOException e) { + throw new RuntimeException(e); + } + + return result; + } + + @Override + public List getDataFile(QueryMetadataDTO dto) { + + initEnvironment(dto, MetadataConstant.FILES); + + List result = new LinkedList<>(); + + try { + reader.forEachRemaining( + internalRow -> { + DataFileVO dataFileVo = new DataFileVO(); + dataFileVo.setPartition(internalRow.getString(0).toString()); + dataFileVo.setBucket(internalRow.getLong(1)); + dataFileVo.setFilePath(internalRow.getString(2).toString()); + dataFileVo.setFileFormat(internalRow.getString(3).toString()); + result.add(dataFileVo); + }); + } catch (IOException e) { + throw new RuntimeException(e); + } + return result; + } + + private void initEnvironment(QueryMetadataDTO dto, String metadataConstantType) { + dto.setTableName( + String.format( + MetadataConstant.METADATA_TABLE_FORMAT, + dto.getTableName(), + metadataConstantType)); + CatalogInfo catalogInfo = + catalogService.getOne( + Wrappers.lambdaQuery(CatalogInfo.class) + .eq(CatalogInfo::getCatalogName, dto.getCatalogName()) + .select(i -> true)); + Catalog catalog = PaimonServiceUtils.getPaimonService(catalogInfo).catalog(); + try { + Table table = TableManager.getTable(catalog, dto.getDatabaseName(), dto.getTableName()); + this.reader = getReader(table); + } catch (Catalog.TableNotExistException e) { + throw new RuntimeException( + String.format("Table [%s] not exists", dto.getTableName()), e); + } + } + + private List formatOptions(String jsonOption) { + Gson gson = new Gson(); + Map map = + gson.fromJson(jsonOption, new TypeToken>() {}); + List result = new LinkedList<>(); + for (Object key : map.keySet()) { + result.add(new MetadataOptionModel(key.toString(), map.get(key))); + } + return result; + } + + private static RecordReader getReader(Table table) { + ReadBuilder readBuilder = table.newReadBuilder(); + try (RecordReader reader = + readBuilder.newRead().createReader(readBuilder.newScan().plan())) { + return reader; + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/SysMenuServiceImpl.java b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/SysMenuServiceImpl.java index 26e4523cf..008dc2314 100644 --- a/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/SysMenuServiceImpl.java +++ b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/SysMenuServiceImpl.java @@ -23,8 +23,8 @@ import org.apache.paimon.web.server.data.model.SysMenu; import org.apache.paimon.web.server.data.model.User; import org.apache.paimon.web.server.data.tree.TreeSelect; -import org.apache.paimon.web.server.data.vo.MetaVo; -import org.apache.paimon.web.server.data.vo.RouterVo; +import org.apache.paimon.web.server.data.vo.MetaVO; +import org.apache.paimon.web.server.data.vo.RouterVO; import org.apache.paimon.web.server.mapper.RoleMenuMapper; import org.apache.paimon.web.server.mapper.SysMenuMapper; import org.apache.paimon.web.server.mapper.SysRoleMapper; @@ -157,17 +157,17 @@ public List selectMenuListByRoleId(Integer roleId) { * @return router list */ @Override - public List buildMenus(List menus) { - List routers = new LinkedList(); + public List buildMenus(List menus) { + List routers = new LinkedList(); for (SysMenu menu : menus) { - RouterVo router = new RouterVo(); + RouterVO router = new RouterVO(); router.setHidden("1".equals(menu.getVisible())); router.setName(getRouteName(menu)); router.setPath(getRouterPath(menu)); router.setComponent(getComponent(menu)); router.setQuery(menu.getQuery()); router.setMeta( - new MetaVo( + new MetaVO( menu.getMenuName(), menu.getIcon(), menu.getIsCache() == 1, @@ -179,13 +179,13 @@ public List buildMenus(List menus) { router.setChildren(buildMenus(cMenus)); } else if (isMenuFrame(menu)) { router.setMeta(null); - List childrenList = new ArrayList(); - RouterVo children = new RouterVo(); + List childrenList = new ArrayList(); + RouterVO children = new RouterVO(); children.setPath(menu.getPath()); children.setComponent(menu.getComponent()); children.setName(StringUtils.capitalize(menu.getPath())); children.setMeta( - new MetaVo( + new MetaVO( menu.getMenuName(), menu.getIcon(), menu.getIsCache() == 1, @@ -194,15 +194,15 @@ public List buildMenus(List menus) { childrenList.add(children); router.setChildren(childrenList); } else if (menu.getParentId() == 0 && isInnerLink(menu)) { - router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon())); + router.setMeta(new MetaVO(menu.getMenuName(), menu.getIcon())); router.setPath("/"); - List childrenList = new ArrayList(); - RouterVo children = new RouterVo(); + List childrenList = new ArrayList(); + RouterVO children = new RouterVO(); String routerPath = innerLinkReplaceEach(menu.getPath()); children.setPath(routerPath); children.setComponent(Constants.INNER_LINK); children.setName(StringUtils.capitalize(routerPath)); - children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), menu.getPath())); + children.setMeta(new MetaVO(menu.getMenuName(), menu.getIcon(), menu.getPath())); childrenList.add(children); router.setChildren(childrenList); } diff --git a/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/UserServiceImpl.java b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/UserServiceImpl.java index 9f059a90b..45b499344 100644 --- a/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/UserServiceImpl.java +++ b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/UserServiceImpl.java @@ -29,7 +29,7 @@ import org.apache.paimon.web.server.data.result.exception.user.UserDisabledException; import org.apache.paimon.web.server.data.result.exception.user.UserNotExistsException; import org.apache.paimon.web.server.data.result.exception.user.UserPasswordNotMatchException; -import org.apache.paimon.web.server.data.vo.UserInfoVo; +import org.apache.paimon.web.server.data.vo.UserInfoVO; import org.apache.paimon.web.server.mapper.UserMapper; import org.apache.paimon.web.server.service.LdapService; import org.apache.paimon.web.server.service.RoleMenuService; @@ -69,7 +69,7 @@ public class UserServiceImpl extends ServiceImpl implements Us * @return {@link String} */ @Override - public UserInfoVo login(LoginDTO loginDTO) throws BaseException { + public UserInfoVO login(LoginDTO loginDTO) throws BaseException { String username = loginDTO.getUsername(); String password = loginDTO.getPassword(); @@ -81,7 +81,7 @@ public UserInfoVo login(LoginDTO loginDTO) throws BaseException { throw new UserDisabledException(); } // query user info - UserInfoVo userInfoVo = getUserInfoVo(user); + UserInfoVO userInfoVo = getUserInfoVo(user); // todo: Currently do not bind tenants /*if (CollectionUtils.isEmpty(userInfoVo.getTenantList())) { throw new UserNotBindTenantException(); @@ -96,10 +96,10 @@ public UserInfoVo login(LoginDTO loginDTO) throws BaseException { * get user info. include user, role, menu. tenant. * * @param user user - * @return {@link UserInfoVo} + * @return {@link UserInfoVO} */ - private UserInfoVo getUserInfoVo(User user) { - UserInfoVo userInfoVo = new UserInfoVo(); + private UserInfoVO getUserInfoVo(User user) { + UserInfoVO userInfoVo = new UserInfoVO(); userInfoVo.setUser(user); userInfoVo.setSaTokenInfo(StpUtil.getTokenInfo()); diff --git a/paimon-web-server/src/test/java/org/apache/paimon/web/server/controller/MetadataControllerTest.java b/paimon-web-server/src/test/java/org/apache/paimon/web/server/controller/MetadataControllerTest.java new file mode 100644 index 000000000..3f0ac45b3 --- /dev/null +++ b/paimon-web-server/src/test/java/org/apache/paimon/web/server/controller/MetadataControllerTest.java @@ -0,0 +1,209 @@ +/* + * 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.paimon.web.server.controller; + +import org.apache.paimon.web.server.data.dto.QueryMetadataDTO; +import org.apache.paimon.web.server.data.dto.TableDTO; +import org.apache.paimon.web.server.data.model.TableColumn; +import org.apache.paimon.web.server.data.result.R; +import org.apache.paimon.web.server.util.ObjectMapperUtils; +import org.apache.paimon.web.server.util.PaimonDataType; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.event.annotation.AfterTestClass; +import org.springframework.test.context.event.annotation.BeforeTestClass; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultHandlers; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** Tests for {@link MetadataController}. */ +@SpringBootTest +@AutoConfigureMockMvc +public class MetadataControllerTest extends ControllerTestBase { + + private static final String METADATA_PATH = "/api/metadata"; + + private static final String tablePath = "/api/table"; + + private static final String catalogName = "paimon_catalog"; + + private static final String databaseName = "paimon_database"; + + private static final String tableName = "paimon_table"; + + @BeforeTestClass + public void createTable() throws Exception { + List tableColumns = new ArrayList<>(); + TableColumn id = + new TableColumn("id", PaimonDataType.builder().type("INT").build(), "", false, "0"); + TableColumn name = + new TableColumn( + "name", PaimonDataType.builder().type("STRING").build(), "", false, "0"); + tableColumns.add(id); + tableColumns.add(name); + TableDTO table = + TableDTO.builder() + .catalogName(catalogName) + .databaseName(databaseName) + .tableName(tableName) + .tableColumns(tableColumns) + .partitionKey(Lists.newArrayList()) + .tableOptions(Maps.newHashMap()) + .build(); + + String responseString = + mockMvc.perform( + MockMvcRequestBuilders.post(tablePath + "/create") + .cookie(cookie) + .content(ObjectMapperUtils.toJSON(table)) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .accept(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andDo(MockMvcResultHandlers.print()) + .andReturn() + .getResponse() + .getContentAsString(); + + R r = ObjectMapperUtils.fromJSON(responseString, new TypeReference>() {}); + assertEquals(200, r.getCode()); + } + + @Test + public void testGetSchemaInfo() throws Exception { + QueryMetadataDTO metadata = new QueryMetadataDTO(); + metadata.setCatalogName(catalogName); + metadata.setDatabaseName(databaseName); + metadata.setTableName(tableName); + + String response = + mockMvc.perform( + MockMvcRequestBuilders.post(METADATA_PATH + "/querySchemaInfo") + .cookie(cookie) + .content(ObjectMapperUtils.toJSON(metadata)) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .accept(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andDo(MockMvcResultHandlers.print()) + .andReturn() + .getResponse() + .getContentAsString(); + + R result = ObjectMapperUtils.fromJSON(response, new TypeReference>() {}); + assertEquals(200, result.getCode()); + } + + @Test + public void testGetManifestInfo() throws Exception { + QueryMetadataDTO metadata = new QueryMetadataDTO(); + metadata.setCatalogName(catalogName); + metadata.setDatabaseName(databaseName); + metadata.setTableName(tableName); + + String response = + mockMvc.perform( + MockMvcRequestBuilders.post(METADATA_PATH + "/queryManifestInfo") + .cookie(cookie) + .content(ObjectMapperUtils.toJSON(metadata)) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .accept(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andDo(MockMvcResultHandlers.print()) + .andReturn() + .getResponse() + .getContentAsString(); + + R result = ObjectMapperUtils.fromJSON(response, new TypeReference>() {}); + assertEquals(200, result.getCode()); + } + + @Test + public void testGetDataFileInfo() throws Exception { + QueryMetadataDTO metadata = new QueryMetadataDTO(); + metadata.setCatalogName(catalogName); + metadata.setDatabaseName(databaseName); + metadata.setTableName(tableName); + + String response = + mockMvc.perform( + MockMvcRequestBuilders.post(METADATA_PATH + "/queryDataFileInfo") + .cookie(cookie) + .content(ObjectMapperUtils.toJSON(metadata)) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .accept(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andDo(MockMvcResultHandlers.print()) + .andReturn() + .getResponse() + .getContentAsString(); + + R result = ObjectMapperUtils.fromJSON(response, new TypeReference>() {}); + assertEquals(200, result.getCode()); + } + + @Test + public void testGetSnapshotInfo() throws Exception { + QueryMetadataDTO metadata = new QueryMetadataDTO(); + metadata.setCatalogName(catalogName); + metadata.setDatabaseName(databaseName); + metadata.setTableName(tableName); + + String response = + mockMvc.perform( + MockMvcRequestBuilders.post(METADATA_PATH + "/querySnapshotInfo") + .cookie(cookie) + .content(ObjectMapperUtils.toJSON(metadata)) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .accept(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andDo(MockMvcResultHandlers.print()) + .andReturn() + .getResponse() + .getContentAsString(); + + R result = ObjectMapperUtils.fromJSON(response, new TypeReference>() {}); + assertEquals(200, result.getCode()); + } + + @AfterTestClass + public void dropTable() throws Exception { + mockMvc.perform( + MockMvcRequestBuilders.delete( + tablePath + + "/drop/" + + catalogName + + "/" + + databaseName + + "/" + + tableName) + .cookie(cookie) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .accept(MediaType.APPLICATION_JSON_VALUE)); + } +} diff --git a/paimon-web-server/src/test/java/org/apache/paimon/web/server/controller/SysMenuControllerTest.java b/paimon-web-server/src/test/java/org/apache/paimon/web/server/controller/SysMenuControllerTest.java index 16cef6222..d240cf458 100644 --- a/paimon-web-server/src/test/java/org/apache/paimon/web/server/controller/SysMenuControllerTest.java +++ b/paimon-web-server/src/test/java/org/apache/paimon/web/server/controller/SysMenuControllerTest.java @@ -21,7 +21,7 @@ import org.apache.paimon.web.server.data.model.SysMenu; import org.apache.paimon.web.server.data.result.R; import org.apache.paimon.web.server.data.tree.TreeSelect; -import org.apache.paimon.web.server.data.vo.RoleMenuTreeselectVo; +import org.apache.paimon.web.server.data.vo.RoleMenuTreeselectVO; import org.apache.paimon.web.server.util.ObjectMapperUtils; import com.fasterxml.jackson.core.type.TypeReference; @@ -118,8 +118,8 @@ public void testGetRoleMenuTreeselect() throws Exception { .andReturn() .getResponse() .getContentAsString(); - R r = - ObjectMapperUtils.fromJSON(result, new TypeReference>() {}); + R r = + ObjectMapperUtils.fromJSON(result, new TypeReference>() {}); assertEquals(200, r.getCode()); assertNotNull(r.getData()); assertNotNull(r.getData().getMenus()); diff --git a/pom.xml b/pom.xml index ff11d775d..066c31c21 100644 --- a/pom.xml +++ b/pom.xml @@ -113,6 +113,7 @@ under the License. 1.35.0.RC 3.12.0 5.8.11 + 2.10.1 @@ -210,6 +211,11 @@ under the License. ${common-lang3.version} + + com.google.code.gson + gson + ${gson.version} +