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 61d635502e [core] RESTCatalog: Optimize ErrorResponse to support more
ResourceType (#5347)
61d635502e is described below
commit 61d635502e2561d97fdafd8fc70fcaf56d88075e
Author: shyjsarah <[email protected]>
AuthorDate: Wed Mar 26 15:14:14 2025 +0800
[core] RESTCatalog: Optimize ErrorResponse to support more ResourceType
(#5347)
---
.../java/org/apache/paimon/rest/RESTCatalog.java | 17 ++++----
.../rest/exceptions/AlreadyExistsException.java | 11 ++---
.../rest/exceptions/NoSuchResourceException.java | 11 ++---
.../paimon/rest/responses/ErrorResponse.java | 26 ++++++++----
.../rest/responses/ErrorResponseResourceType.java | 30 -------------
.../org/apache/paimon/rest/HttpClientTest.java | 4 +-
.../org/apache/paimon/rest/RESTCatalogServer.java | 49 +++++++++++-----------
paimon-open-api/rest-catalog-open-api.yaml | 1 +
8 files changed, 60 insertions(+), 89 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 3fea24bdf3..be61cfd894 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
@@ -56,7 +56,7 @@ import org.apache.paimon.rest.requests.RollbackTableRequest;
import org.apache.paimon.rest.responses.AlterDatabaseResponse;
import org.apache.paimon.rest.responses.CommitTableResponse;
import org.apache.paimon.rest.responses.ConfigResponse;
-import org.apache.paimon.rest.responses.ErrorResponseResourceType;
+import org.apache.paimon.rest.responses.ErrorResponse;
import org.apache.paimon.rest.responses.GetDatabaseResponse;
import org.apache.paimon.rest.responses.GetTableResponse;
import org.apache.paimon.rest.responses.GetTableSnapshotResponse;
@@ -373,7 +373,7 @@ public class RESTCatalog implements Catalog {
GetTableSnapshotResponse.class,
restAuthFunction);
} catch (NoSuchResourceException e) {
- if (e.resourceType() == ErrorResponseResourceType.SNAPSHOT) {
+ if (StringUtils.equals(e.resourceType(),
ErrorResponse.RESOURCE_TYPE_SNAPSHOT)) {
return Optional.empty();
}
throw new TableNotExistException(identifier);
@@ -424,10 +424,10 @@ public class RESTCatalog implements Catalog {
request,
restAuthFunction);
} catch (NoSuchResourceException e) {
- if (e.resourceType() == ErrorResponseResourceType.SNAPSHOT) {
+ if (StringUtils.equals(e.resourceType(),
ErrorResponse.RESOURCE_TYPE_SNAPSHOT)) {
throw new IllegalArgumentException(
String.format("Rollback snapshot '%s' doesn't exist.",
e.resourceName()));
- } else if (e.resourceType() == ErrorResponseResourceType.TAG) {
+ } else if (StringUtils.equals(e.resourceType(),
ErrorResponse.RESOURCE_TYPE_TAG)) {
throw new IllegalArgumentException(
String.format("Rollback tag '%s' doesn't exist.",
e.resourceName()));
}
@@ -555,9 +555,10 @@ public class RESTCatalog implements Catalog {
restAuthFunction);
} catch (NoSuchResourceException e) {
if (!ignoreIfNotExists) {
- if (e.resourceType() == ErrorResponseResourceType.TABLE) {
+ if (StringUtils.equals(e.resourceType(),
ErrorResponse.RESOURCE_TYPE_TABLE)) {
throw new TableNotExistException(identifier);
- } else if (e.resourceType() ==
ErrorResponseResourceType.COLUMN) {
+ } else if (StringUtils.equals(
+ e.resourceType(), ErrorResponse.RESOURCE_TYPE_COLUMN))
{
throw new ColumnNotExistException(identifier,
e.resourceName());
}
}
@@ -669,9 +670,9 @@ public class RESTCatalog implements Catalog {
request,
restAuthFunction);
} catch (NoSuchResourceException e) {
- if (e.resourceType() == ErrorResponseResourceType.TABLE) {
+ if (StringUtils.equals(e.resourceType(),
ErrorResponse.RESOURCE_TYPE_TABLE)) {
throw new TableNotExistException(identifier, e);
- } else if (e.resourceType() == ErrorResponseResourceType.TAG) {
+ } else if (StringUtils.equals(e.resourceType(),
ErrorResponse.RESOURCE_TYPE_TAG)) {
throw new TagNotExistException(identifier, fromTag, e);
} else {
throw e;
diff --git
a/paimon-core/src/main/java/org/apache/paimon/rest/exceptions/AlreadyExistsException.java
b/paimon-core/src/main/java/org/apache/paimon/rest/exceptions/AlreadyExistsException.java
index 6da7a492b6..b75e121fac 100644
---
a/paimon-core/src/main/java/org/apache/paimon/rest/exceptions/AlreadyExistsException.java
+++
b/paimon-core/src/main/java/org/apache/paimon/rest/exceptions/AlreadyExistsException.java
@@ -18,25 +18,20 @@
package org.apache.paimon.rest.exceptions;
-import org.apache.paimon.rest.responses.ErrorResponseResourceType;
-
/** Exception thrown on HTTP 409 means a resource already exists. */
public class AlreadyExistsException extends RESTException {
- private final ErrorResponseResourceType resourceType;
+ private final String resourceType;
private final String resourceName;
public AlreadyExistsException(
- ErrorResponseResourceType resourceType,
- String resourceName,
- String message,
- Object... args) {
+ String resourceType, String resourceName, String message,
Object... args) {
super(message, args);
this.resourceType = resourceType;
this.resourceName = resourceName;
}
- public ErrorResponseResourceType resourceType() {
+ public String resourceType() {
return resourceType;
}
diff --git
a/paimon-core/src/main/java/org/apache/paimon/rest/exceptions/NoSuchResourceException.java
b/paimon-core/src/main/java/org/apache/paimon/rest/exceptions/NoSuchResourceException.java
index 6dfb125671..fc27c6b9a3 100644
---
a/paimon-core/src/main/java/org/apache/paimon/rest/exceptions/NoSuchResourceException.java
+++
b/paimon-core/src/main/java/org/apache/paimon/rest/exceptions/NoSuchResourceException.java
@@ -18,25 +18,20 @@
package org.apache.paimon.rest.exceptions;
-import org.apache.paimon.rest.responses.ErrorResponseResourceType;
-
/** Exception thrown on HTTP 404 means a resource not exists. */
public class NoSuchResourceException extends RESTException {
- private final ErrorResponseResourceType resourceType;
+ private final String resourceType;
private final String resourceName;
public NoSuchResourceException(
- ErrorResponseResourceType resourceType,
- String resourceName,
- String message,
- Object... args) {
+ String resourceType, String resourceName, String message,
Object... args) {
super(message, args);
this.resourceType = resourceType;
this.resourceName = resourceName;
}
- public ErrorResponseResourceType resourceType() {
+ public String resourceType() {
return resourceType;
}
diff --git
a/paimon-core/src/main/java/org/apache/paimon/rest/responses/ErrorResponse.java
b/paimon-core/src/main/java/org/apache/paimon/rest/responses/ErrorResponse.java
index 5911ad820c..04a9119d4f 100644
---
a/paimon-core/src/main/java/org/apache/paimon/rest/responses/ErrorResponse.java
+++
b/paimon-core/src/main/java/org/apache/paimon/rest/responses/ErrorResponse.java
@@ -29,13 +29,27 @@ import
org.apache.paimon.shade.jackson2.com.fasterxml.jackson.annotation.JsonPro
@JsonIgnoreProperties(ignoreUnknown = true)
public class ErrorResponse implements RESTResponse {
+ public static final String RESOURCE_TYPE_DATABASE = "DATABASE";
+
+ public static final String RESOURCE_TYPE_TABLE = "TABLE";
+
+ public static final String RESOURCE_TYPE_COLUMN = "COLUMN";
+
+ public static final String RESOURCE_TYPE_SNAPSHOT = "SNAPSHOT";
+
+ public static final String RESOURCE_TYPE_BRANCH = "BRANCH";
+
+ public static final String RESOURCE_TYPE_TAG = "TAG";
+
+ public static final String RESOURCE_TYPE_VIEW = "VIEW";
+
private static final String FIELD_MESSAGE = "message";
private static final String FIELD_RESOURCE_TYPE = "resourceType";
private static final String FIELD_RESOURCE_NAME = "resourceName";
private static final String FIELD_CODE = "code";
@JsonProperty(FIELD_RESOURCE_TYPE)
- private final ErrorResponseResourceType resourceType;
+ private final String resourceType;
@JsonProperty(FIELD_RESOURCE_NAME)
private final String resourceName;
@@ -46,11 +60,7 @@ public class ErrorResponse implements RESTResponse {
@JsonProperty(FIELD_CODE)
private final Integer code;
- public ErrorResponse(
- ErrorResponseResourceType resourceType,
- String resourceName,
- String message,
- Integer code) {
+ public ErrorResponse(String resourceType, String resourceName, String
message, Integer code) {
this.resourceType = resourceType;
this.resourceName = resourceName;
this.code = code;
@@ -59,7 +69,7 @@ public class ErrorResponse implements RESTResponse {
@JsonCreator
public ErrorResponse(
- @JsonProperty(FIELD_RESOURCE_TYPE) ErrorResponseResourceType
resourceType,
+ @JsonProperty(FIELD_RESOURCE_TYPE) String resourceType,
@JsonProperty(FIELD_RESOURCE_NAME) String resourceName,
@JsonProperty(FIELD_MESSAGE) String message,
@JsonProperty(FIELD_CODE) int code) {
@@ -75,7 +85,7 @@ public class ErrorResponse implements RESTResponse {
}
@JsonGetter(FIELD_RESOURCE_TYPE)
- public ErrorResponseResourceType getResourceType() {
+ public String getResourceType() {
return resourceType;
}
diff --git
a/paimon-core/src/main/java/org/apache/paimon/rest/responses/ErrorResponseResourceType.java
b/paimon-core/src/main/java/org/apache/paimon/rest/responses/ErrorResponseResourceType.java
deleted file mode 100644
index dc715303bd..0000000000
---
a/paimon-core/src/main/java/org/apache/paimon/rest/responses/ErrorResponseResourceType.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.rest.responses;
-
-/** The type of resource that caused the error. */
-public enum ErrorResponseResourceType {
- DATABASE,
- TABLE,
- COLUMN,
- SNAPSHOT,
- BRANCH,
- TAG,
- VIEW
-}
diff --git
a/paimon-core/src/test/java/org/apache/paimon/rest/HttpClientTest.java
b/paimon-core/src/test/java/org/apache/paimon/rest/HttpClientTest.java
index c688665c69..b1f68bd71e 100644
--- a/paimon-core/src/test/java/org/apache/paimon/rest/HttpClientTest.java
+++ b/paimon-core/src/test/java/org/apache/paimon/rest/HttpClientTest.java
@@ -25,7 +25,6 @@ import org.apache.paimon.rest.auth.RESTAuthFunction;
import org.apache.paimon.rest.auth.RESTAuthParameter;
import org.apache.paimon.rest.exceptions.BadRequestException;
import org.apache.paimon.rest.responses.ErrorResponse;
-import org.apache.paimon.rest.responses.ErrorResponseResourceType;
import org.apache.paimon.shade.guava30.com.google.common.collect.ImmutableMap;
@@ -81,7 +80,8 @@ public class HttpClientTest {
mockResponseDataStr = server.createResponseBody(mockResponseData);
errorResponseStr =
server.createResponseBody(
- new ErrorResponse(ErrorResponseResourceType.DATABASE,
"test", "test", 400));
+ new ErrorResponse(
+ ErrorResponse.RESOURCE_TYPE_DATABASE, "test",
"test", 400));
httpClient = new HttpClient(server.getBaseUrl());
httpClient.setErrorHandler(errorHandler);
AuthProvider authProvider = new BearTokenAuthProvider(TOKEN);
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 b755c7772c..fd1497d03d 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
@@ -54,7 +54,6 @@ import org.apache.paimon.rest.responses.AlterDatabaseResponse;
import org.apache.paimon.rest.responses.CommitTableResponse;
import org.apache.paimon.rest.responses.ConfigResponse;
import org.apache.paimon.rest.responses.ErrorResponse;
-import org.apache.paimon.rest.responses.ErrorResponseResourceType;
import org.apache.paimon.rest.responses.GetDatabaseResponse;
import org.apache.paimon.rest.responses.GetTableResponse;
import org.apache.paimon.rest.responses.GetTableSnapshotResponse;
@@ -424,7 +423,7 @@ public class RESTCatalogServer {
} catch (Catalog.DatabaseNotExistException e) {
response =
new ErrorResponse(
- ErrorResponseResourceType.DATABASE,
+ ErrorResponse.RESOURCE_TYPE_DATABASE,
e.database(),
e.getMessage(),
404);
@@ -432,7 +431,7 @@ public class RESTCatalogServer {
} catch (Catalog.TableNotExistException e) {
response =
new ErrorResponse(
- ErrorResponseResourceType.TABLE,
+ ErrorResponse.RESOURCE_TYPE_TABLE,
e.identifier().getTableName(),
e.getMessage(),
404);
@@ -440,7 +439,7 @@ public class RESTCatalogServer {
} catch (Catalog.ColumnNotExistException e) {
response =
new ErrorResponse(
- ErrorResponseResourceType.COLUMN,
+ ErrorResponse.RESOURCE_TYPE_COLUMN,
e.column(),
e.getMessage(),
404);
@@ -448,7 +447,7 @@ public class RESTCatalogServer {
} catch (Catalog.DatabaseNoPermissionException e) {
response =
new ErrorResponse(
- ErrorResponseResourceType.DATABASE,
+ ErrorResponse.RESOURCE_TYPE_DATABASE,
e.database(),
e.getMessage(),
403);
@@ -456,7 +455,7 @@ public class RESTCatalogServer {
} catch (Catalog.TableNoPermissionException e) {
response =
new ErrorResponse(
- ErrorResponseResourceType.TABLE,
+ ErrorResponse.RESOURCE_TYPE_TABLE,
e.identifier().getTableName(),
e.getMessage(),
403);
@@ -464,7 +463,7 @@ public class RESTCatalogServer {
} catch (Catalog.DatabaseAlreadyExistException e) {
response =
new ErrorResponse(
- ErrorResponseResourceType.DATABASE,
+ ErrorResponse.RESOURCE_TYPE_DATABASE,
e.database(),
e.getMessage(),
409);
@@ -472,7 +471,7 @@ public class RESTCatalogServer {
} catch (Catalog.TableAlreadyExistException e) {
response =
new ErrorResponse(
- ErrorResponseResourceType.TABLE,
+ ErrorResponse.RESOURCE_TYPE_TABLE,
e.identifier().getTableName(),
e.getMessage(),
409);
@@ -480,7 +479,7 @@ public class RESTCatalogServer {
} catch (Catalog.ColumnAlreadyExistException e) {
response =
new ErrorResponse(
- ErrorResponseResourceType.COLUMN,
+ ErrorResponse.RESOURCE_TYPE_COLUMN,
e.column(),
e.getMessage(),
409);
@@ -488,7 +487,7 @@ public class RESTCatalogServer {
} catch (Catalog.ViewNotExistException e) {
response =
new ErrorResponse(
- ErrorResponseResourceType.VIEW,
+ ErrorResponse.RESOURCE_TYPE_VIEW,
e.identifier().getTableName(),
e.getMessage(),
404);
@@ -496,7 +495,7 @@ public class RESTCatalogServer {
} catch (Catalog.ViewAlreadyExistException e) {
response =
new ErrorResponse(
- ErrorResponseResourceType.VIEW,
+ ErrorResponse.RESOURCE_TYPE_VIEW,
e.identifier().getTableName(),
e.getMessage(),
409);
@@ -556,7 +555,7 @@ public class RESTCatalogServer {
if (!snapshotOptional.isPresent()) {
response =
new ErrorResponse(
- ErrorResponseResourceType.SNAPSHOT,
+ ErrorResponse.RESOURCE_TYPE_SNAPSHOT,
identifier.getDatabaseName(),
"No Snapshot",
404);
@@ -582,7 +581,7 @@ public class RESTCatalogServer {
}
return Optional.of(
mockResponse(
- new ErrorResponse(ErrorResponseResourceType.TABLE,
null, "", 404), 404));
+ new ErrorResponse(ErrorResponse.RESOURCE_TYPE_TABLE,
null, "", 404), 404));
}
private MockResponse commitTableHandle(Identifier identifier, String data)
throws Exception {
@@ -617,7 +616,7 @@ public class RESTCatalogServer {
return new MockResponse().setResponseCode(200);
}
return mockResponse(
- new ErrorResponse(ErrorResponseResourceType.SNAPSHOT, "" +
snapshotId, "", 404),
+ new ErrorResponse(ErrorResponse.RESOURCE_TYPE_SNAPSHOT, "" +
snapshotId, "", 404),
404);
}
@@ -644,7 +643,7 @@ public class RESTCatalogServer {
}
}
return mockResponse(
- new ErrorResponse(ErrorResponseResourceType.TAG, "" + tagName,
"", 404), 404);
+ new ErrorResponse(ErrorResponse.RESOURCE_TYPE_TAG, "" +
tagName, "", 404), 404);
}
private void cleanSnapshot(Identifier identifier, Long snapshotId, Long
latestSnapshotId)
@@ -692,7 +691,7 @@ public class RESTCatalogServer {
parameters.getOrDefault(MAX_RESULTS, null));
return mockResponse(
new ErrorResponse(
- ErrorResponseResourceType.TABLE,
+ ErrorResponse.RESOURCE_TYPE_TABLE,
null,
"invalid input queryParameter maxResults"
+ parameters.get(MAX_RESULTS),
@@ -845,7 +844,7 @@ public class RESTCatalogServer {
}
}
return mockResponse(
- new ErrorResponse(ErrorResponseResourceType.DATABASE, null,
"", 404), 404);
+ new ErrorResponse(ErrorResponse.RESOURCE_TYPE_DATABASE, null,
"", 404), 404);
}
private List<String> listTables(String databaseName) {
@@ -872,7 +871,7 @@ public class RESTCatalogServer {
parameters.getOrDefault(MAX_RESULTS, null));
return mockResponse(
new ErrorResponse(
- ErrorResponseResourceType.TABLE,
+ ErrorResponse.RESOURCE_TYPE_TABLE,
null,
"invalid input queryParameter maxResults"
+ parameters.get(MAX_RESULTS),
@@ -904,7 +903,7 @@ public class RESTCatalogServer {
parameters.getOrDefault(MAX_RESULTS, null));
return mockResponse(
new ErrorResponse(
- ErrorResponseResourceType.TABLE,
+ ErrorResponse.RESOURCE_TYPE_TABLE,
null,
"invalid input queryParameter maxResults"
+ parameters.get(MAX_RESULTS),
@@ -1111,21 +1110,21 @@ public class RESTCatalogServer {
if (e.getMessage().contains("Tag")) {
response =
new ErrorResponse(
- ErrorResponseResourceType.TAG, fromTag,
e.getMessage(), 404);
+ ErrorResponse.RESOURCE_TYPE_TAG, fromTag,
e.getMessage(), 404);
return mockResponse(response, 404);
}
if (e.getMessage().contains("Branch name")
&& e.getMessage().contains("already exists")) {
response =
new ErrorResponse(
- ErrorResponseResourceType.BRANCH, branch,
e.getMessage(), 409);
+ ErrorResponse.RESOURCE_TYPE_BRANCH, branch,
e.getMessage(), 409);
return mockResponse(response, 409);
}
if (e.getMessage().contains("Branch name")
&& e.getMessage().contains("doesn't exist")) {
response =
new ErrorResponse(
- ErrorResponseResourceType.BRANCH, branch,
e.getMessage(), 404);
+ ErrorResponse.RESOURCE_TYPE_BRANCH, branch,
e.getMessage(), 404);
return mockResponse(response, 404);
}
}
@@ -1145,7 +1144,7 @@ public class RESTCatalogServer {
parameters.getOrDefault(MAX_RESULTS, null));
return mockResponse(
new ErrorResponse(
- ErrorResponseResourceType.TABLE,
+ ErrorResponse.RESOURCE_TYPE_TABLE,
null,
"invalid input queryParameter maxResults"
+ parameters.get(MAX_RESULTS),
@@ -1216,7 +1215,7 @@ public class RESTCatalogServer {
parameters.getOrDefault(MAX_RESULTS, null));
return mockResponse(
new ErrorResponse(
- ErrorResponseResourceType.TABLE,
+ ErrorResponse.RESOURCE_TYPE_TABLE,
null,
"invalid input queryParameter maxResults"
+ parameters.get(MAX_RESULTS),
@@ -1251,7 +1250,7 @@ public class RESTCatalogServer {
parameters.getOrDefault(MAX_RESULTS, null));
return mockResponse(
new ErrorResponse(
- ErrorResponseResourceType.TABLE,
+ ErrorResponse.RESOURCE_TYPE_TABLE,
null,
"invalid input queryParameter maxResults"
+ parameters.get(MAX_RESULTS),
diff --git a/paimon-open-api/rest-catalog-open-api.yaml
b/paimon-open-api/rest-catalog-open-api.yaml
index 98ee92e6a7..44b1a63385 100644
--- a/paimon-open-api/rest-catalog-open-api.yaml
+++ b/paimon-open-api/rest-catalog-open-api.yaml
@@ -1521,6 +1521,7 @@ components:
type: string
resourceType:
type: string
+ enum: ["DATABASE", "TABLE", "COLUMN", "SNAPSHOT", "BRANCH", "TAG",
"VIEW", "UNKNOWN"]
resourceName:
type: string
code: