This is an automated email from the ASF dual-hosted git repository.

nicholasjiang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-paimon-webui.git


The following commit(s) were added to refs/heads/main by this push:
     new 10f01c6  [Feature] Improve metadata model (#54)
10f01c6 is described below

commit 10f01c606bdade2c512296cefb028390a8d646e6
Author: Hunter <[email protected]>
AuthorDate: Sat Oct 28 16:37:39 2023 +0800

    [Feature] Improve metadata model (#54)
---
 .../paimon/web/api/catalog/PaimonService.java      |   4 +-
 .../apache/paimon/web/api/table/TableChange.java   |   1 +
 .../apache/paimon/web/api/table/TableManager.java  |   9 +
 .../api/table/{ => metadata}/ColumnMetadata.java   |   2 +-
 .../{ => metadata}/ConsumerTableMetadata.java      |   2 +-
 .../table/{ => metadata}/FileTableMetadata.java    |   2 +-
 .../{ => metadata}/ManifestTableMetadata.java      |   2 +-
 .../table/{ => metadata}/OptionTableMetadata.java  |   2 +-
 .../table/{ => metadata}/SchemaTableMetadata.java  |   2 +-
 .../{ => metadata}/SnapshotTableMetadata.java      |   2 +-
 .../api/table/{ => metadata}/TableMetadata.java    |   2 +-
 .../api/table/{ => metadata}/TagTableMetadata.java |   2 +-
 .../paimon/web/api/catalog/PaimonServiceTest.java  |   4 +-
 .../paimon/web/api/table/TableManagerTest.java     |   2 +
 paimon-web-server/pom.xml                          |   5 +
 .../web/server/constant/MetadataConstant.java      |  41 ++--
 .../web/server/controller/DatabaseController.java  |   2 +-
 .../web/server/controller/LoginController.java     |   4 +-
 .../web/server/controller/MetadataController.java  |  68 +++++++
 .../web/server/controller/SysMenuController.java   |  10 +-
 .../web/server/controller/TableController.java     |   4 +-
 .../web/server/data/dto/QueryMetadataDTO.java      |  32 +--
 .../web/server/data/model/MetadataFieldsModel.java |  32 +--
 .../web/server/data/model/MetadataOptionModel.java |  36 ++--
 .../{RoleMenuTreeselectVo.java => DataFileVO.java} |  28 ++-
 .../paimon/web/server/data/vo/ManifestsVO.java     |  55 ++----
 .../server/data/vo/{MetaVo.java => MetaVO.java}    |  12 +-
 ...TreeselectVo.java => RoleMenuTreeselectVO.java} |   4 +-
 .../data/vo/{RouterVo.java => RouterVO.java}       |  14 +-
 .../apache/paimon/web/server/data/vo/SchemaVO.java |  81 +++++---
 .../paimon/web/server/data/vo/SnapshotVO.java      |  89 +++++++++
 .../data/vo/{UserInfoVo.java => UserInfoVO.java}   |   2 +-
 .../paimon/web/server/service/MetadataService.java |  63 ++++++
 .../paimon/web/server/service/SysMenuService.java  |   4 +-
 .../paimon/web/server/service/UserService.java     |   4 +-
 .../server/service/impl/MetadataServiceImpl.java   | 215 +++++++++++++++++++++
 .../server/service/impl/SysMenuServiceImpl.java    |  26 +--
 .../web/server/service/impl/UserServiceImpl.java   |  12 +-
 .../server/controller/MetadataControllerTest.java  | 209 ++++++++++++++++++++
 .../server/controller/SysMenuControllerTest.java   |   6 +-
 pom.xml                                            |   6 +
 41 files changed, 847 insertions(+), 255 deletions(-)

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 bd92a4c..78c8412 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.types.DataType;
 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 ec0f392..c9f891f 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 3e18828..ddbe3a0 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.CatalogProperties;
 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 4d09c6e..c97de6c 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 12e52dd..ec1f436 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 3c0776e..a862954 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%
copy from 
paimon-web-api/src/main/java/org/apache/paimon/web/api/table/ManifestTableMetadata.java
copy to 
paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/ManifestTableMetadata.java
index 574899c..e944eb7 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%
copy from 
paimon-web-api/src/main/java/org/apache/paimon/web/api/table/OptionTableMetadata.java
copy to 
paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/OptionTableMetadata.java
index ec259e0..b8f046c 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%
copy from 
paimon-web-api/src/main/java/org/apache/paimon/web/api/table/SchemaTableMetadata.java
copy to 
paimon-web-api/src/main/java/org/apache/paimon/web/api/table/metadata/SchemaTableMetadata.java
index e9744e5..4771170 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 9bc0bd4..e326b6f 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 89d02f4..9c9e0c5 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 f26170c..6e16219 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 37af5de..cec1294 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.DataType;
 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 a60ef27..54fa05f 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.table.Table;
 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 02ec9b7..b6f30d6 100644
--- a/paimon-web-server/pom.xml
+++ b/paimon-web-server/pom.xml
@@ -172,6 +172,11 @@ under the License.
             <version>${hadoop.version}</version>
             <scope>provided</scope>
         </dependency>
+
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+        </dependency>
     </dependencies>
 
     <build>
diff --git 
a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/OptionTableMetadata.java
 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/constant/MetadataConstant.java
similarity index 60%
copy from 
paimon-web-api/src/main/java/org/apache/paimon/web/api/table/OptionTableMetadata.java
copy to 
paimon-web-server/src/main/java/org/apache/paimon/web/server/constant/MetadataConstant.java
index ec259e0..54c66e9 100644
--- 
a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/OptionTableMetadata.java
+++ 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/constant/MetadataConstant.java
@@ -16,33 +16,16 @@
  * limitations under the License.
  */
 
-package org.apache.paimon.web.api.table;
-
-/** options table metadata. */
-public class OptionTableMetadata {
-
-    private String key;
-
-    private String value;
-
-    public OptionTableMetadata(String key, String value) {
-        this.key = key;
-        this.value = value;
-    }
-
-    public String getKey() {
-        return key;
-    }
-
-    public void setKey(String key) {
-        this.key = key;
-    }
-
-    public String getValue() {
-        return value;
-    }
-
-    public void setValue(String value) {
-        this.value = value;
-    }
+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 d70454b..395417e 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 class DatabaseController {
     }
 
     /**
-     * /** 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 e30af77..409598f 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 @@ package org.apache.paimon.web.server.controller;
 
 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<UserInfoVo> login(@RequestBody LoginDTO loginDTO) {
+    public R<UserInfoVO> 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 0000000..1435219
--- /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<List<SchemaVO>> getSchemaInfo(@RequestBody QueryMetadataDTO dto) {
+        return R.succeed(metadataService.getSchema(dto));
+    }
+
+    @PostMapping("/snapshot")
+    public R<List<SnapshotVO>> getSnapshotInfo(@RequestBody QueryMetadataDTO 
dto) {
+        return R.succeed(metadataService.getSnapshot(dto));
+    }
+
+    @PostMapping("/manifest")
+    public R<List<ManifestsVO>> getManifestInfo(@RequestBody QueryMetadataDTO 
dto) {
+        return R.succeed(metadataService.getManifest(dto));
+    }
+
+    @PostMapping("/dataFile")
+    public R<List<DataFileVO>> 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 d613594..102fe2b 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.model.SysMenu;
 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 class SysMenuController {
 
     /** Load the corresponding character menu list tree. */
     @GetMapping(value = "/roleMenuTreeselect/{roleId}")
-    public R<RoleMenuTreeselectVo> roleMenuTreeselect(@PathVariable("roleId") 
Integer roleId) {
+    public R<RoleMenuTreeselectVO> roleMenuTreeselect(@PathVariable("roleId") 
Integer roleId) {
         List<SysMenu> menus = menuService.selectMenuList();
 
         List<TreeSelect> treeMenus = menuService.buildMenuTreeSelect(menus);
         List<Integer> 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 class SysMenuController {
 
     /** Get router list. */
     @GetMapping("/getRouters")
-    public R<List<RouterVo>> getRouters() {
+    public R<List<RouterVO>> getRouters() {
         int userId = StpUtil.getLoginIdAsInt();
         List<SysMenu> 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 3784640..0c18f75 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 @@ package org.apache.paimon.web.server.controller;
 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-api/src/main/java/org/apache/paimon/web/api/table/OptionTableMetadata.java
 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/dto/QueryMetadataDTO.java
similarity index 60%
copy from 
paimon-web-api/src/main/java/org/apache/paimon/web/api/table/OptionTableMetadata.java
copy to 
paimon-web-server/src/main/java/org/apache/paimon/web/server/data/dto/QueryMetadataDTO.java
index ec259e0..572c84a 100644
--- 
a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/OptionTableMetadata.java
+++ 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/dto/QueryMetadataDTO.java
@@ -16,33 +16,17 @@
  * limitations under the License.
  */
 
-package org.apache.paimon.web.api.table;
+package org.apache.paimon.web.server.data.dto;
 
-/** options table metadata. */
-public class OptionTableMetadata {
+import lombok.Data;
 
-    private String key;
+/** DTO of query metadata is used for getting table metadata. */
+@Data
+public class QueryMetadataDTO {
 
-    private String value;
+    private String catalogName;
 
-    public OptionTableMetadata(String key, String value) {
-        this.key = key;
-        this.value = value;
-    }
+    private String databaseName;
 
-    public String getKey() {
-        return key;
-    }
-
-    public void setKey(String key) {
-        this.key = key;
-    }
-
-    public String getValue() {
-        return value;
-    }
-
-    public void setValue(String value) {
-        this.value = value;
-    }
+    private String tableName;
 }
diff --git 
a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/OptionTableMetadata.java
 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/model/MetadataFieldsModel.java
similarity index 60%
copy from 
paimon-web-api/src/main/java/org/apache/paimon/web/api/table/OptionTableMetadata.java
copy to 
paimon-web-server/src/main/java/org/apache/paimon/web/server/data/model/MetadataFieldsModel.java
index ec259e0..80805cb 100644
--- 
a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/OptionTableMetadata.java
+++ 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/model/MetadataFieldsModel.java
@@ -16,33 +16,19 @@
  * limitations under the License.
  */
 
-package org.apache.paimon.web.api.table;
+package org.apache.paimon.web.server.data.model;
 
-/** options table metadata. */
-public class OptionTableMetadata {
+import lombok.Data;
 
-    private String key;
+/** Model of metadata fields. */
+@Data
+public class MetadataFieldsModel {
 
-    private String value;
+    private int id;
 
-    public OptionTableMetadata(String key, String value) {
-        this.key = key;
-        this.value = value;
-    }
+    private String name;
 
-    public String getKey() {
-        return key;
-    }
+    private String type;
 
-    public void setKey(String key) {
-        this.key = key;
-    }
-
-    public String getValue() {
-        return value;
-    }
-
-    public void setValue(String value) {
-        this.value = value;
-    }
+    private String comment;
 }
diff --git 
a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/OptionTableMetadata.java
 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/model/MetadataOptionModel.java
similarity index 62%
rename from 
paimon-web-api/src/main/java/org/apache/paimon/web/api/table/OptionTableMetadata.java
rename to 
paimon-web-server/src/main/java/org/apache/paimon/web/server/data/model/MetadataOptionModel.java
index ec259e0..d2959fa 100644
--- 
a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/OptionTableMetadata.java
+++ 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/model/MetadataOptionModel.java
@@ -16,33 +16,19 @@
  * limitations under the License.
  */
 
-package org.apache.paimon.web.api.table;
+package org.apache.paimon.web.server.data.model;
 
-/** options table metadata. */
-public class OptionTableMetadata {
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
 
-    private String key;
-
-    private String value;
-
-    public OptionTableMetadata(String key, String value) {
-        this.key = key;
-        this.value = value;
-    }
+/** Model of metadata options. */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class MetadataOptionModel {
 
-    public String getKey() {
-        return key;
-    }
-
-    public void setKey(String key) {
-        this.key = key;
-    }
-
-    public String getValue() {
-        return value;
-    }
+    private String key;
 
-    public void setValue(String value) {
-        this.value = value;
-    }
+    private Object value;
 }
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/DataFileVO.java
similarity index 60%
copy from 
paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/RoleMenuTreeselectVo.java
copy to 
paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/DataFileVO.java
index 11418be..b0fb46f 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/DataFileVO.java
@@ -18,23 +18,21 @@
 
 package org.apache.paimon.web.server.data.vo;
 
-import org.apache.paimon.web.server.data.tree.TreeSelect;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
 
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.Getter;
+/** VO of metadata data file. */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class DataFileVO {
 
-import java.util.List;
+    private String partition;
 
-/** Role Menu List Tree Vo. */
-@Getter
-public class RoleMenuTreeselectVo {
-    private final List<Integer> checkedKeys;
-    private final List<TreeSelect> menus;
+    private long bucket;
 
-    public RoleMenuTreeselectVo(
-            @JsonProperty("checkedKeys") List<Integer> checkedKeys,
-            @JsonProperty("menus") List<TreeSelect> menus) {
-        this.checkedKeys = checkedKeys;
-        this.menus = menus;
-    }
+    private String filePath;
+
+    private String fileFormat;
 }
diff --git 
a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/ManifestTableMetadata.java
 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/ManifestsVO.java
similarity index 53%
rename from 
paimon-web-api/src/main/java/org/apache/paimon/web/api/table/ManifestTableMetadata.java
rename to 
paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/ManifestsVO.java
index 574899c..6060bdf 100644
--- 
a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/ManifestTableMetadata.java
+++ 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/ManifestsVO.java
@@ -16,28 +16,18 @@
  * limitations under the License.
  */
 
-package org.apache.paimon.web.api.table;
-
-/** manifest table metadata. */
-public class ManifestTableMetadata {
+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;
-    private final Long numDeletedFiles;
-    private final Long schemaId;
 
-    public ManifestTableMetadata(
-            String fileName,
-            Long fileSize,
-            Long numAddedFiles,
-            Long numDeletedFiles,
-            Long schemaId) {
+    public ManifestsVO(String fileName, Long fileSize, Long numAddedFiles) {
         this.fileName = fileName;
         this.fileSize = fileSize;
         this.numAddedFiles = numAddedFiles;
-        this.numDeletedFiles = numDeletedFiles;
-        this.schemaId = schemaId;
     }
 
     public String getFileName() {
@@ -52,54 +42,33 @@ public class ManifestTableMetadata {
         return numAddedFiles;
     }
 
-    public Long getNumDeletedFiles() {
-        return numDeletedFiles;
-    }
-
-    public Long getSchemaId() {
-        return schemaId;
-    }
-
-    public static ManifestTableMetadata.Builder builder() {
+    public static Builder builder() {
         return new Builder();
     }
 
-    /** The builder for ManifestTableMetadata. */
-    public static final class Builder {
+    /** ManifestsInfoVo Builder. */
+    public static class Builder {
         private String fileName;
         private Long fileSize;
         private Long numAddedFiles;
-        private Long numDeletedFiles;
-        private Long schemaId;
 
-        public Builder fileName(String fileName) {
+        public Builder setFileName(String fileName) {
             this.fileName = fileName;
             return this;
         }
 
-        public Builder fileSize(Long fileSize) {
+        public Builder setFileSize(Long fileSize) {
             this.fileSize = fileSize;
             return this;
         }
 
-        public Builder numAddedFiles(Long numAddedFiles) {
+        public Builder setNumAddedFiles(Long numAddedFiles) {
             this.numAddedFiles = numAddedFiles;
             return this;
         }
 
-        public Builder numDeletedFiles(Long numDeletedFiles) {
-            this.numDeletedFiles = numDeletedFiles;
-            return this;
-        }
-
-        public Builder schemaId(Long schemaId) {
-            this.schemaId = schemaId;
-            return this;
-        }
-
-        public ManifestTableMetadata build() {
-            return new ManifestTableMetadata(
-                    fileName, fileSize, numAddedFiles, numDeletedFiles, 
schemaId);
+        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 19bf2a5..b48c90e 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 @@ package org.apache.paimon.web.server.data.vo;
 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 11418be..c56a708 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 @@ import java.util.List;
 
 /** Role Menu List Tree Vo. */
 @Getter
-public class RoleMenuTreeselectVo {
+public class RoleMenuTreeselectVO {
     private final List<Integer> checkedKeys;
     private final List<TreeSelect> menus;
 
-    public RoleMenuTreeselectVo(
+    public RoleMenuTreeselectVO(
             @JsonProperty("checkedKeys") List<Integer> checkedKeys,
             @JsonProperty("menus") List<TreeSelect> 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 d485691..0322fff 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 @@ import java.util.List;
 
 /** 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<RouterVo> children;
+    private List<RouterVO> children;
 
     public String getName() {
         return name;
@@ -117,19 +117,19 @@ public class RouterVo {
         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<RouterVo> getChildren() {
+    public List<RouterVO> getChildren() {
         return children;
     }
 
-    public void setChildren(List<RouterVo> children) {
+    public void setChildren(List<RouterVO> children) {
         this.children = children;
     }
 }
diff --git 
a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/SchemaTableMetadata.java
 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/SchemaVO.java
similarity index 55%
rename from 
paimon-web-api/src/main/java/org/apache/paimon/web/api/table/SchemaTableMetadata.java
rename to 
paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/SchemaVO.java
index e9744e5..1b5e18f 100644
--- 
a/paimon-web-api/src/main/java/org/apache/paimon/web/api/table/SchemaTableMetadata.java
+++ 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/SchemaVO.java
@@ -16,40 +16,49 @@
  * limitations under the License.
  */
 
-package org.apache.paimon.web.api.table;
+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;
 
-/** schema table metadata. */
-public class SchemaTableMetadata {
+import java.time.LocalDateTime;
+import java.util.List;
+
+/** VO of metadata schema. */
+public class SchemaVO {
 
     private final Long schemaId;
-    private final String fields;
+    private final List<MetadataFieldsModel> fields;
     private final String partitionKeys;
     private final String primaryKeys;
-    private final String options;
     private final String comment;
+    private final List<MetadataOptionModel> option;
+    private final LocalDateTime updateTime;
 
-    public SchemaTableMetadata(
+    public SchemaVO(
             Long schemaId,
-            String fields,
+            List<MetadataFieldsModel> fields,
             String partitionKeys,
             String primaryKeys,
-            String options,
-            String comment) {
+            String comment,
+            List<MetadataOptionModel> option,
+            LocalDateTime updateTime) {
         this.schemaId = schemaId;
         this.fields = fields;
         this.partitionKeys = partitionKeys;
         this.primaryKeys = primaryKeys;
-        this.options = options;
         this.comment = comment;
+        this.option = option;
+        this.updateTime = updateTime;
     }
 
     public Long getSchemaId() {
         return schemaId;
     }
 
-    public String getFields() {
+    public List<MetadataFieldsModel> getFields() {
         return fields;
     }
 
@@ -61,60 +70,70 @@ public class SchemaTableMetadata {
         return primaryKeys;
     }
 
-    public String getOptions() {
-        return options;
-    }
-
     public String getComment() {
         return comment;
     }
 
-    public static SchemaTableMetadata.Builder builder() {
+    public LocalDateTime getUpdateTime() {
+        return updateTime;
+    }
+
+    public List<MetadataOptionModel> getOption() {
+        return option;
+    }
+
+    public static SchemaVO.Builder builder() {
         return new Builder();
     }
 
-    /** The builder for SchemaTableMetadata. */
-    public static final class Builder {
+    /** Builder for SchemaInfoVo. */
+    public static class Builder {
         private Long schemaId;
-        private String fields;
+        private List<MetadataFieldsModel> fields;
         private String partitionKeys;
         private String primaryKeys;
-        private String options;
         @Nullable private String comment;
+        @Nullable private List<MetadataOptionModel> option;
+        private LocalDateTime updateTime;
 
-        public Builder schemaId(Long schemaId) {
+        public Builder setSchemaId(Long schemaId) {
             this.schemaId = schemaId;
             return this;
         }
 
-        public Builder fields(String fields) {
+        public Builder setFields(List<MetadataFieldsModel> fields) {
             this.fields = fields;
             return this;
         }
 
-        public Builder partitionKeys(String partitionKeys) {
+        public Builder setPartitionKeys(String partitionKeys) {
             this.partitionKeys = partitionKeys;
             return this;
         }
 
-        public Builder primaryKeys(String primaryKeys) {
+        public Builder setPrimaryKeys(String primaryKeys) {
             this.primaryKeys = primaryKeys;
             return this;
         }
 
-        public Builder options(String options) {
-            this.options = options;
+        public Builder setComment(String comment) {
+            this.comment = comment;
             return this;
         }
 
-        public Builder comment(String comment) {
-            this.comment = comment;
+        public Builder setOption(List<MetadataOptionModel> option) {
+            this.option = option;
+            return this;
+        }
+
+        public Builder setUpdateTime(LocalDateTime updateTime) {
+            this.updateTime = updateTime;
             return this;
         }
 
-        public SchemaTableMetadata build() {
-            return new SchemaTableMetadata(
-                    schemaId, fields, partitionKeys, primaryKeys, options, 
comment);
+        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 0000000..c79ffa7
--- /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 fdd08e2..f8c23ab 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 @@ import java.util.List;
 
 /** 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 0000000..7c5cea5
--- /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<SchemaVO> getSchema(QueryMetadataDTO dto);
+
+    /**
+     * Retrieves a list of Metadata snapshot.
+     *
+     * @param dto query metadata info
+     * @return a list of snapshot objects
+     */
+    List<SnapshotVO> getSnapshot(QueryMetadataDTO dto);
+
+    /**
+     * Retrieves a list of Metadata manifest.
+     *
+     * @param dto query metadata info
+     * @return a list of manifest info objects
+     */
+    List<ManifestsVO> getManifest(QueryMetadataDTO dto);
+
+    /**
+     * Retrieves a list of Metadata data file.
+     *
+     * @param dto query metadata info
+     * @return a list of data file objects
+     */
+    List<DataFileVO> 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 4bc9072..d6ad1c1 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 @@ package org.apache.paimon.web.server.service;
 
 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<SysMenu> {
      * @param menus menu list
      * @return router list
      */
-    List<RouterVo> buildMenus(List<SysMenu> menus);
+    List<RouterVO> buildMenus(List<SysMenu> 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 b91af00..f30dc7b 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 @@ package org.apache.paimon.web.server.service;
 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<User> {
      * @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 0000000..6bbac39
--- /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<InternalRow> reader;
+
+    @Override
+    public List<SchemaVO> getSchema(QueryMetadataDTO dto) {
+
+        initEnvironment(dto, MetadataConstant.SCHEMAS);
+
+        List<SchemaVO> 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<SnapshotVO> getSnapshot(QueryMetadataDTO dto) {
+
+        initEnvironment(dto, MetadataConstant.SNAPSHOTS);
+
+        List<SnapshotVO> 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<ManifestsVO> getManifest(QueryMetadataDTO dto) {
+        initEnvironment(dto, MetadataConstant.MANIFESTS);
+
+        List<ManifestsVO> 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<DataFileVO> getDataFile(QueryMetadataDTO dto) {
+
+        initEnvironment(dto, MetadataConstant.FILES);
+
+        List<DataFileVO> 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<MetadataOptionModel> formatOptions(String jsonOption) {
+        Gson gson = new Gson();
+        Map<String, Object> map =
+                gson.fromJson(jsonOption, new TypeToken<Map<String, Object>>() 
{});
+        List<MetadataOptionModel> result = new LinkedList<>();
+        for (Object key : map.keySet()) {
+            result.add(new MetadataOptionModel(key.toString(), map.get(key)));
+        }
+        return result;
+    }
+
+    private static RecordReader<InternalRow> getReader(Table table) {
+        ReadBuilder readBuilder = table.newReadBuilder();
+        try (RecordReader<InternalRow> 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 26e4523..008dc23 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.enums.MenuType;
 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 class SysMenuServiceImpl extends 
ServiceImpl<SysMenuMapper, SysMenu>
      * @return router list
      */
     @Override
-    public List<RouterVo> buildMenus(List<SysMenu> menus) {
-        List<RouterVo> routers = new LinkedList<RouterVo>();
+    public List<RouterVO> buildMenus(List<SysMenu> menus) {
+        List<RouterVO> routers = new LinkedList<RouterVO>();
         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 class SysMenuServiceImpl extends 
ServiceImpl<SysMenuMapper, SysMenu>
                 router.setChildren(buildMenus(cMenus));
             } else if (isMenuFrame(menu)) {
                 router.setMeta(null);
-                List<RouterVo> childrenList = new ArrayList<RouterVo>();
-                RouterVo children = new RouterVo();
+                List<RouterVO> childrenList = new ArrayList<RouterVO>();
+                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 class SysMenuServiceImpl extends 
ServiceImpl<SysMenuMapper, SysMenu>
                 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<RouterVo> childrenList = new ArrayList<RouterVo>();
-                RouterVo children = new RouterVo();
+                List<RouterVO> childrenList = new ArrayList<RouterVO>();
+                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 9f059a9..45b4993 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.BaseException;
 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<UserMapper, 
User> 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 class UserServiceImpl extends ServiceImpl<UserMapper, 
User> implements Us
             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 class UserServiceImpl extends 
ServiceImpl<UserMapper, User> implements Us
      * 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 0000000..3f0ac45
--- /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<TableColumn> 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<Void> r = ObjectMapperUtils.fromJSON(responseString, new 
TypeReference<R<Void>>() {});
+        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<Void> result = ObjectMapperUtils.fromJSON(response, new 
TypeReference<R<Void>>() {});
+        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<Void> result = ObjectMapperUtils.fromJSON(response, new 
TypeReference<R<Void>>() {});
+        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<Void> result = ObjectMapperUtils.fromJSON(response, new 
TypeReference<R<Void>>() {});
+        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<Void> result = ObjectMapperUtils.fromJSON(response, new 
TypeReference<R<Void>>() {});
+        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 16cef62..d240cf4 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 @@ package org.apache.paimon.web.server.controller;
 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 class SysMenuControllerTest extends 
ControllerTestBase {
                         .andReturn()
                         .getResponse()
                         .getContentAsString();
-        R<RoleMenuTreeselectVo> r =
-                ObjectMapperUtils.fromJSON(result, new 
TypeReference<R<RoleMenuTreeselectVo>>() {});
+        R<RoleMenuTreeselectVO> r =
+                ObjectMapperUtils.fromJSON(result, new 
TypeReference<R<RoleMenuTreeselectVO>>() {});
         assertEquals(200, r.getCode());
         assertNotNull(r.getData());
         assertNotNull(r.getData().getMenus());
diff --git a/pom.xml b/pom.xml
index ff11d77..066c31c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -113,6 +113,7 @@ under the License.
         <sa-token.version>1.35.0.RC</sa-token.version>
         <common-lang3.version>3.12.0</common-lang3.version>
         <hutool.version>5.8.11</hutool.version>
+        <gson.version>2.10.1</gson.version>
     </properties>
 
     <dependencyManagement>
@@ -210,6 +211,11 @@ under the License.
                 <version>${common-lang3.version}</version>
             </dependency>
 
+            <dependency>
+                <groupId>com.google.code.gson</groupId>
+                <artifactId>gson</artifactId>
+                <version>${gson.version}</version>
+            </dependency>
 
         </dependencies>
     </dependencyManagement>

Reply via email to