JingsongLi commented on code in PR #8179:
URL: https://github.com/apache/paimon/pull/8179#discussion_r3503229103
##########
paimon-core/src/main/java/org/apache/paimon/rest/RESTCatalog.java:
##########
@@ -910,6 +914,143 @@ public PagedList<Function> listFunctionDetailsPaged(
}
}
+ @Override
+ public List<String> listResources(String databaseName) throws
DatabaseNotExistException {
+ try {
+ return api.listResources(databaseName);
+ } catch (NoSuchResourceException e) {
+ throw new DatabaseNotExistException(databaseName);
+ } catch (ForbiddenException e) {
+ throw new DatabaseNoPermissionException(databaseName, e);
+ }
+ }
+
+ @Override
+ public Resource getResource(Identifier identifier) throws
ResourceNotExistException {
+ try {
+ GetResourceResponse response = api.getResource(identifier);
+ return toResource(identifier, response);
+ } catch (NoSuchResourceException e) {
+ throw new ResourceNotExistException(identifier, e);
+ } catch (ForbiddenException e) {
+ throw new TableNoPermissionException(identifier, e);
+ }
+ }
+
+ @Override
+ public void createResource(Identifier identifier, Resource resource,
boolean ignoreIfExists)
+ throws ResourceAlreadyExistException, DatabaseNotExistException {
+ RESTFunctionValidator.checkFunctionName(identifier.getObjectName());
+ try {
+ api.createResource(
+ identifier,
+ resource.comment().orElse(null),
+ resource.uri(),
+ resource.resourceType());
+ } catch (NoSuchResourceException e) {
+ throw new DatabaseNotExistException(identifier.getDatabaseName(),
e);
+ } catch (AlreadyExistsException e) {
+ if (ignoreIfExists) {
+ return;
+ }
+ throw new ResourceAlreadyExistException(identifier, e);
+ }
+ }
+
+ @Override
+ public void dropResource(Identifier identifier, boolean ignoreIfNotExists)
+ throws ResourceNotExistException {
+ RESTFunctionValidator.checkFunctionName(identifier.getObjectName());
+ try {
+ api.dropResource(identifier);
+ } catch (NoSuchResourceException e) {
+ if (ignoreIfNotExists) {
+ return;
+ }
+ throw new ResourceNotExistException(identifier, e);
+ }
+ }
+
+ @Override
+ public void alterResource(
+ Identifier identifier, List<ResourceChange> changes, boolean
ignoreIfNotExists)
+ throws ResourceNotExistException {
+ try {
+ api.alterResource(identifier, changes);
+ } catch (NoSuchResourceException e) {
+ if (!ignoreIfNotExists) {
+ throw new ResourceNotExistException(identifier, e);
+ }
+ } catch (ForbiddenException e) {
+ throw new TableNoPermissionException(identifier, e);
+ } catch (BadRequestException e) {
+ throw new IllegalArgumentException(e.getMessage());
+ }
+ }
+
+ @Override
+ public PagedList<String> listResourcesPaged(
+ String databaseName,
+ @Nullable Integer maxResults,
+ @Nullable String pageToken,
+ @Nullable String resourceNamePattern)
+ throws DatabaseNotExistException {
+ try {
+ return api.listResourcesPaged(databaseName, maxResults, pageToken,
resourceNamePattern);
+ } catch (NoSuchResourceException e) {
+ throw new DatabaseNotExistException(databaseName);
+ } catch (ForbiddenException e) {
+ throw new DatabaseNoPermissionException(databaseName, e);
+ }
+ }
+
+ @Override
+ public PagedList<Resource> listResourceDetailsPaged(
+ String databaseName,
+ @Nullable Integer maxResults,
+ @Nullable String pageToken,
+ @Nullable String resourceNamePattern)
+ throws DatabaseNotExistException {
+ try {
+ PagedList<GetResourceResponse> resources =
+ api.listResourceDetailsPaged(
+ databaseName, maxResults, pageToken,
resourceNamePattern);
+ return new PagedList<>(
+ resources.getElements().stream()
+ .map(r ->
toResource(Identifier.create(databaseName, r.name()), r))
+ .collect(Collectors.toList()),
+ resources.getNextPageToken());
+ } catch (NoSuchResourceException e) {
+ throw new DatabaseNotExistException(databaseName);
+ } catch (ForbiddenException e) {
+ throw new DatabaseNoPermissionException(databaseName, e);
+ }
+ }
+
+ private Resource toResource(Identifier identifier, GetResourceResponse
response) {
+ String uri = response.uri();
+ return Resource.toResource(
+ ResourceType.fromValue(response.resourceType()),
+ identifier,
+ response.comment(),
+ uri,
+ response.size(),
+ response.lastModifiedTime(),
+ fileIOForData(new Path(uri), identifier));
Review Comment:
This wraps resources with the table-oriented `RESTTokenFileIO`. When
`data-token.enabled=true`, the first `resource.toBytes()` /
`resource.newInputStream()` calls `RESTTokenFileIO.refreshToken()`, which in
turn invokes `api.loadTableToken(identifier)`. Here `identifier` is the
resource name, not a table, so the client asks
`/databases/{db}/tables/{resource}/token` and fails with 404/403 for normal
resources. That makes REST resources unreadable under data-token mode, even
though the metadata lookup succeeds. Resource reading needs a resource-token
path or a non-table FileIO path instead of reusing table token refresh.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]