This is an automated email from the ASF dual-hosted git repository. lzljs3620320 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/paimon.git
The following commit(s) were added to refs/heads/master by this push: new 624d449bc2 [rest] Add path and other options to Table Options (#5325) 624d449bc2 is described below commit 624d449bc247a83714cc77cd3abfaa20bf1bb6b3 Author: Jingsong Lee <jingsongl...@gmail.com> AuthorDate: Fri Mar 21 19:05:00 2025 +0800 [rest] Add path and other options to Table Options (#5325) --- .../java/org/apache/paimon/rest/RESTCatalog.java | 24 ++++++++++++---- ...ceAuditResponse.java => AuditRESTResponse.java} | 25 +++++++++++----- .../paimon/rest/responses/GetDatabaseResponse.java | 33 ++++++++-------------- .../paimon/rest/responses/GetTableResponse.java | 13 ++++++++- .../paimon/rest/responses/GetViewResponse.java | 2 +- .../org/apache/paimon/rest/MockRESTMessage.java | 2 ++ .../org/apache/paimon/rest/RESTCatalogServer.java | 7 ++++- .../apache/paimon/rest/RESTObjectMapperTest.java | 1 - paimon-open-api/rest-catalog-open-api.yaml | 4 +++ .../paimon/open/api/RESTCatalogController.java | 3 ++ 10 files changed, 76 insertions(+), 38 deletions(-) diff --git a/paimon-core/src/main/java/org/apache/paimon/rest/RESTCatalog.java b/paimon-core/src/main/java/org/apache/paimon/rest/RESTCatalog.java index e61f165e68..48b665cf3a 100644 --- a/paimon-core/src/main/java/org/apache/paimon/rest/RESTCatalog.java +++ b/paimon-core/src/main/java/org/apache/paimon/rest/RESTCatalog.java @@ -93,6 +93,7 @@ import java.io.IOException; import java.io.UncheckedIOException; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -103,6 +104,8 @@ import java.util.function.Function; import java.util.stream.Collectors; import static java.util.Collections.emptyList; +import static org.apache.paimon.CoreOptions.BRANCH; +import static org.apache.paimon.CoreOptions.PATH; import static org.apache.paimon.catalog.CatalogUtils.checkNotBranch; import static org.apache.paimon.catalog.CatalogUtils.checkNotSystemDatabase; import static org.apache.paimon.catalog.CatalogUtils.checkNotSystemTable; @@ -229,8 +232,10 @@ public class RESTCatalog implements Catalog { resourcePaths.database(name), GetDatabaseResponse.class, restAuthFunction); - return new Database.DatabaseImpl( - name, response.options(), response.comment().orElse(null)); + Map<String, String> options = new HashMap<>(response.getOptions()); + options.put(DB_LOCATION_PROP, response.getLocation()); + response.putAuditOptionsTo(options); + return new Database.DatabaseImpl(name, options, options.get(COMMENT_PROP)); } catch (NoSuchResourceException e) { throw new DatabaseNotExistException(name); } catch (ForbiddenException e) { @@ -451,12 +456,19 @@ public class RESTCatalog implements Catalog { throw new TableNoPermissionException(identifier, e); } - return toTableMetadata(response); + return toTableMetadata(identifier.getDatabaseName(), response); } - private TableMetadata toTableMetadata(GetTableResponse response) { + private TableMetadata toTableMetadata(String db, GetTableResponse response) { TableSchema schema = TableSchema.create(response.getSchemaId(), response.getSchema()); - return new TableMetadata(schema, response.isExternal(), response.getId()); + Map<String, String> options = new HashMap<>(schema.options()); + options.put(PATH.key(), response.getPath()); + response.putAuditOptionsTo(options); + Identifier identifier = Identifier.create(db, response.getName()); + if (identifier.getBranchName() != null) { + options.put(BRANCH.key(), identifier.getBranchName()); + } + return new TableMetadata(schema.copy(options), response.isExternal(), response.getId()); } private Table toTable(String db, GetTableResponse response) { @@ -467,7 +479,7 @@ public class RESTCatalog implements Catalog { identifier, path -> fileIOForData(path, identifier), this::fileIOFromOptions, - i -> toTableMetadata(response), + i -> toTableMetadata(db, response), null, null); } catch (TableNotExistException e) { diff --git a/paimon-core/src/main/java/org/apache/paimon/rest/responses/BaseResourceAuditResponse.java b/paimon-core/src/main/java/org/apache/paimon/rest/responses/AuditRESTResponse.java similarity index 77% rename from paimon-core/src/main/java/org/apache/paimon/rest/responses/BaseResourceAuditResponse.java rename to paimon-core/src/main/java/org/apache/paimon/rest/responses/AuditRESTResponse.java index d867efd180..3d07a790b4 100644 --- a/paimon-core/src/main/java/org/apache/paimon/rest/responses/BaseResourceAuditResponse.java +++ b/paimon-core/src/main/java/org/apache/paimon/rest/responses/AuditRESTResponse.java @@ -24,13 +24,16 @@ import org.apache.paimon.shade.jackson2.com.fasterxml.jackson.annotation.JsonCre import org.apache.paimon.shade.jackson2.com.fasterxml.jackson.annotation.JsonGetter; import org.apache.paimon.shade.jackson2.com.fasterxml.jackson.annotation.JsonProperty; +import java.util.Map; + /** Base class for database, table, view, audit response. */ -public abstract class BaseResourceAuditResponse implements RESTResponse { - protected static final String FIELD_OWNER = "owner"; - protected static final String FIELD_CREATED_AT = "createdAt"; - protected static final String FIELD_CREATED_BY = "createdBy"; - protected static final String FIELD_UPDATED_AT = "updatedAt"; - protected static final String FIELD_UPDATED_BY = "updatedBy"; +public abstract class AuditRESTResponse implements RESTResponse { + + public static final String FIELD_OWNER = "owner"; + public static final String FIELD_CREATED_AT = "createdAt"; + public static final String FIELD_CREATED_BY = "createdBy"; + public static final String FIELD_UPDATED_AT = "updatedAt"; + public static final String FIELD_UPDATED_BY = "updatedBy"; @JsonProperty(FIELD_OWNER) private final String owner; @@ -48,7 +51,7 @@ public abstract class BaseResourceAuditResponse implements RESTResponse { private final String updatedBy; @JsonCreator - public BaseResourceAuditResponse( + public AuditRESTResponse( @JsonProperty(FIELD_OWNER) String owner, @JsonProperty(FIELD_CREATED_AT) long createdAt, @JsonProperty(FIELD_CREATED_BY) String createdBy, @@ -85,4 +88,12 @@ public abstract class BaseResourceAuditResponse implements RESTResponse { public String getUpdatedBy() { return updatedBy; } + + public void putAuditOptionsTo(Map<String, String> options) { + options.put(FIELD_OWNER, getOwner()); + options.put(FIELD_CREATED_BY, String.valueOf(getCreatedBy())); + options.put(FIELD_CREATED_AT, String.valueOf(getCreatedAt())); + options.put(FIELD_UPDATED_BY, String.valueOf(getUpdatedBy())); + options.put(FIELD_UPDATED_AT, String.valueOf(getUpdatedAt())); + } } diff --git a/paimon-core/src/main/java/org/apache/paimon/rest/responses/GetDatabaseResponse.java b/paimon-core/src/main/java/org/apache/paimon/rest/responses/GetDatabaseResponse.java index b226f41888..b77debf98b 100644 --- a/paimon-core/src/main/java/org/apache/paimon/rest/responses/GetDatabaseResponse.java +++ b/paimon-core/src/main/java/org/apache/paimon/rest/responses/GetDatabaseResponse.java @@ -18,7 +18,6 @@ package org.apache.paimon.rest.responses; -import org.apache.paimon.catalog.Database; import org.apache.paimon.rest.RESTResponse; import org.apache.paimon.shade.jackson2.com.fasterxml.jackson.annotation.JsonCreator; @@ -27,17 +26,14 @@ import org.apache.paimon.shade.jackson2.com.fasterxml.jackson.annotation.JsonIgn import org.apache.paimon.shade.jackson2.com.fasterxml.jackson.annotation.JsonProperty; import java.util.Map; -import java.util.Optional; - -import static org.apache.paimon.catalog.Catalog.COMMENT_PROP; /** Response for getting database. */ @JsonIgnoreProperties(ignoreUnknown = true) -public class GetDatabaseResponse extends BaseResourceAuditResponse - implements RESTResponse, Database { +public class GetDatabaseResponse extends AuditRESTResponse implements RESTResponse { private static final String FIELD_ID = "id"; private static final String FIELD_NAME = "name"; + private static final String FIELD_LOCATION = "location"; private static final String FIELD_OPTIONS = "options"; @JsonProperty(FIELD_ID) @@ -46,6 +42,9 @@ public class GetDatabaseResponse extends BaseResourceAuditResponse @JsonProperty(FIELD_NAME) private final String name; + @JsonProperty(FIELD_LOCATION) + private final String location; + @JsonProperty(FIELD_OPTIONS) private final Map<String, String> options; @@ -53,6 +52,7 @@ public class GetDatabaseResponse extends BaseResourceAuditResponse public GetDatabaseResponse( @JsonProperty(FIELD_ID) String id, @JsonProperty(FIELD_NAME) String name, + @JsonProperty(FIELD_LOCATION) String location, @JsonProperty(FIELD_OPTIONS) Map<String, String> options, @JsonProperty(FIELD_OWNER) String owner, @JsonProperty(FIELD_CREATED_AT) long createdAt, @@ -62,6 +62,7 @@ public class GetDatabaseResponse extends BaseResourceAuditResponse super(owner, createdAt, createdBy, updatedAt, updatedBy); this.id = id; this.name = name; + this.location = location; this.options = options; } @@ -75,23 +76,13 @@ public class GetDatabaseResponse extends BaseResourceAuditResponse return name; } + @JsonGetter(FIELD_LOCATION) + public String getLocation() { + return location; + } + @JsonGetter(FIELD_OPTIONS) public Map<String, String> getOptions() { return options; } - - @Override - public String name() { - return getName(); - } - - @Override - public Map<String, String> options() { - return getOptions(); - } - - @Override - public Optional<String> comment() { - return Optional.ofNullable(options.get(COMMENT_PROP)); - } } diff --git a/paimon-core/src/main/java/org/apache/paimon/rest/responses/GetTableResponse.java b/paimon-core/src/main/java/org/apache/paimon/rest/responses/GetTableResponse.java index c556b591cc..470da0503a 100644 --- a/paimon-core/src/main/java/org/apache/paimon/rest/responses/GetTableResponse.java +++ b/paimon-core/src/main/java/org/apache/paimon/rest/responses/GetTableResponse.java @@ -28,10 +28,11 @@ import org.apache.paimon.shade.jackson2.com.fasterxml.jackson.annotation.JsonPro /** Response for getting table. */ @JsonIgnoreProperties(ignoreUnknown = true) -public class GetTableResponse extends BaseResourceAuditResponse implements RESTResponse { +public class GetTableResponse extends AuditRESTResponse implements RESTResponse { private static final String FIELD_ID = "id"; private static final String FIELD_NAME = "name"; + private static final String FIELD_PATH = "path"; private static final String FIELD_IS_EXTERNAL = "isExternal"; private static final String FIELD_SCHEMA_ID = "schemaId"; private static final String FIELD_SCHEMA = "schema"; @@ -42,6 +43,9 @@ public class GetTableResponse extends BaseResourceAuditResponse implements RESTR @JsonProperty(FIELD_NAME) private final String name; + @JsonProperty(FIELD_PATH) + private final String path; + @JsonProperty(FIELD_IS_EXTERNAL) private final boolean isExternal; @@ -55,6 +59,7 @@ public class GetTableResponse extends BaseResourceAuditResponse implements RESTR public GetTableResponse( @JsonProperty(FIELD_ID) String id, @JsonProperty(FIELD_NAME) String name, + @JsonProperty(FIELD_PATH) String path, @JsonProperty(FIELD_IS_EXTERNAL) boolean isExternal, @JsonProperty(FIELD_SCHEMA_ID) long schemaId, @JsonProperty(FIELD_SCHEMA) Schema schema, @@ -66,6 +71,7 @@ public class GetTableResponse extends BaseResourceAuditResponse implements RESTR super(owner, createdAt, createdBy, updatedAt, updatedBy); this.id = id; this.name = name; + this.path = path; this.isExternal = isExternal; this.schemaId = schemaId; this.schema = schema; @@ -81,6 +87,11 @@ public class GetTableResponse extends BaseResourceAuditResponse implements RESTR return this.name; } + @JsonGetter(FIELD_PATH) + public String getPath() { + return this.path; + } + @JsonGetter(FIELD_IS_EXTERNAL) public boolean isExternal() { return isExternal; diff --git a/paimon-core/src/main/java/org/apache/paimon/rest/responses/GetViewResponse.java b/paimon-core/src/main/java/org/apache/paimon/rest/responses/GetViewResponse.java index ab1e0341b1..2233a2848e 100644 --- a/paimon-core/src/main/java/org/apache/paimon/rest/responses/GetViewResponse.java +++ b/paimon-core/src/main/java/org/apache/paimon/rest/responses/GetViewResponse.java @@ -28,7 +28,7 @@ import org.apache.paimon.shade.jackson2.com.fasterxml.jackson.annotation.JsonPro /** Response for getting view. */ @JsonIgnoreProperties(ignoreUnknown = true) -public class GetViewResponse extends BaseResourceAuditResponse implements RESTResponse { +public class GetViewResponse extends AuditRESTResponse implements RESTResponse { private static final String FIELD_ID = "id"; private static final String FIELD_NAME = "name"; diff --git a/paimon-core/src/test/java/org/apache/paimon/rest/MockRESTMessage.java b/paimon-core/src/test/java/org/apache/paimon/rest/MockRESTMessage.java index 9285f3de99..0d5d46c550 100644 --- a/paimon-core/src/test/java/org/apache/paimon/rest/MockRESTMessage.java +++ b/paimon-core/src/test/java/org/apache/paimon/rest/MockRESTMessage.java @@ -80,6 +80,7 @@ public class MockRESTMessage { return new GetDatabaseResponse( UUID.randomUUID().toString(), name, + "/tmp/", options, "owner", System.currentTimeMillis(), @@ -225,6 +226,7 @@ public class MockRESTMessage { return new GetTableResponse( UUID.randomUUID().toString(), "", + "/tmp/", false, 1, schema(options), diff --git a/paimon-core/src/test/java/org/apache/paimon/rest/RESTCatalogServer.java b/paimon-core/src/test/java/org/apache/paimon/rest/RESTCatalogServer.java index e78b4042f8..62382e10b1 100644 --- a/paimon-core/src/test/java/org/apache/paimon/rest/RESTCatalogServer.java +++ b/paimon-core/src/test/java/org/apache/paimon/rest/RESTCatalogServer.java @@ -744,6 +744,7 @@ public class RESTCatalogServer { new GetDatabaseResponse( UUID.randomUUID().toString(), database.name(), + "/tmp", database.options(), "owner", 1L, @@ -918,6 +919,7 @@ public class RESTCatalogServer { new GetTableResponse( entry.getValue().uuid(), identifier.getTableName(), + entry.getValue().schema().options().get(PATH.key()), entry.getValue().isExternal(), entry.getValue().schema().id(), entry.getValue().schema().toSchema(), @@ -953,13 +955,16 @@ public class RESTCatalogServer { } else { tableMetadata = tableMetadataStore.get(identifier.getFullName()); } + Schema schema = tableMetadata.schema().toSchema(); + String path = schema.options().remove(PATH.key()); response = new GetTableResponse( tableMetadata.uuid(), identifier.getTableName(), + path, tableMetadata.isExternal(), tableMetadata.schema().id(), - tableMetadata.schema().toSchema(), + schema, "owner", 1L, "created", diff --git a/paimon-core/src/test/java/org/apache/paimon/rest/RESTObjectMapperTest.java b/paimon-core/src/test/java/org/apache/paimon/rest/RESTObjectMapperTest.java index cde0bffcc3..9951544e04 100644 --- a/paimon-core/src/test/java/org/apache/paimon/rest/RESTObjectMapperTest.java +++ b/paimon-core/src/test/java/org/apache/paimon/rest/RESTObjectMapperTest.java @@ -95,7 +95,6 @@ public class RESTObjectMapperTest { OBJECT_MAPPER.readValue(responseStr, GetDatabaseResponse.class); assertEquals(name, parseData.getName()); assertEquals(response.getOptions().size(), parseData.getOptions().size()); - assertEquals(response.comment().get(), parseData.comment().get()); } @Test diff --git a/paimon-open-api/rest-catalog-open-api.yaml b/paimon-open-api/rest-catalog-open-api.yaml index 48e394764d..c30f09f8ac 100644 --- a/paimon-open-api/rest-catalog-open-api.yaml +++ b/paimon-open-api/rest-catalog-open-api.yaml @@ -1638,6 +1638,8 @@ components: type: string name: type: string + path: + type: string isExternal: type: boolean schemaId: @@ -1965,6 +1967,8 @@ components: type: string name: type: string + location: + type: string options: type: object additionalProperties: diff --git a/paimon-open-api/src/main/java/org/apache/paimon/open/api/RESTCatalogController.java b/paimon-open-api/src/main/java/org/apache/paimon/open/api/RESTCatalogController.java index a375ce332d..307a088ad4 100644 --- a/paimon-open-api/src/main/java/org/apache/paimon/open/api/RESTCatalogController.java +++ b/paimon-open-api/src/main/java/org/apache/paimon/open/api/RESTCatalogController.java @@ -176,6 +176,7 @@ public class RESTCatalogController { return new GetDatabaseResponse( UUID.randomUUID().toString(), "name", + "/tmp/", options, "owner", System.currentTimeMillis(), @@ -293,6 +294,7 @@ public class RESTCatalogController { new GetTableResponse( UUID.randomUUID().toString(), "", + "/tmp/", false, 1, new org.apache.paimon.schema.Schema( @@ -340,6 +342,7 @@ public class RESTCatalogController { return new GetTableResponse( UUID.randomUUID().toString(), "", + "/tmp/", false, 1, new org.apache.paimon.schema.Schema(