Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug Fix: Expose tableExists endpoint on RESTCatalogAdapter #11678

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,13 @@ public static void purgeTable(Catalog catalog, TableIdentifier ident) {
}
}

public static void tableExists(Catalog catalog, TableIdentifier ident) {
boolean exists = catalog.tableExists(ident);
if (!exists) {
throw new NoSuchTableException("Table does not exist: %s", ident);
}
}

public static LoadTableResponse loadTable(Catalog catalog, TableIdentifier ident) {
Table table = catalog.loadTable(ident);

Expand Down
1 change: 1 addition & 0 deletions core/src/main/java/org/apache/iceberg/rest/Endpoint.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public class Endpoint {
// table endpoints
public static final Endpoint V1_LIST_TABLES = Endpoint.create("GET", ResourcePaths.V1_TABLES);
public static final Endpoint V1_LOAD_TABLE = Endpoint.create("GET", ResourcePaths.V1_TABLE);
public static final Endpoint V1_TABLE_EXISTS = Endpoint.create("HEAD", ResourcePaths.V1_TABLE);
public static final Endpoint V1_CREATE_TABLE = Endpoint.create("POST", ResourcePaths.V1_TABLES);
public static final Endpoint V1_UPDATE_TABLE = Endpoint.create("POST", ResourcePaths.V1_TABLE);
public static final Endpoint V1_DELETE_TABLE = Endpoint.create("DELETE", ResourcePaths.V1_TABLE);
Expand Down
13 changes: 13 additions & 0 deletions core/src/main/java/org/apache/iceberg/rest/RESTSessionCatalog.java
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ public class RESTSessionCatalog extends BaseViewSessionCatalog
.add(Endpoint.V1_DELETE_NAMESPACE)
.add(Endpoint.V1_LIST_TABLES)
.add(Endpoint.V1_LOAD_TABLE)
.add(Endpoint.V1_TABLE_EXISTS)
.add(Endpoint.V1_CREATE_TABLE)
.add(Endpoint.V1_UPDATE_TABLE)
.add(Endpoint.V1_DELETE_TABLE)
Expand Down Expand Up @@ -387,6 +388,18 @@ public List<TableIdentifier> listTables(SessionContext context, Namespace ns) {
return tables.build();
}

@Override
public boolean tableExists(SessionContext context, TableIdentifier identifier) {
Endpoint.check(endpoints, Endpoint.V1_TABLE_EXISTS);
checkIdentifierIsValid(identifier);
try {
client.head(paths.table(identifier), headers(context), ErrorHandlers.tableErrorHandler());
return true;
} catch (NoSuchTableException e) {
return false;
}
}

@Override
public boolean dropTable(SessionContext context, TableIdentifier identifier) {
Endpoint.check(endpoints, Endpoint.V1_DELETE_TABLE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ enum Route {
UPDATE_TABLE(
HTTPMethod.POST, ResourcePaths.V1_TABLE, UpdateTableRequest.class, LoadTableResponse.class),
DROP_TABLE(HTTPMethod.DELETE, ResourcePaths.V1_TABLE),
TABLE_EXISTS(HTTPMethod.HEAD, ResourcePaths.V1_TABLE),
RENAME_TABLE(HTTPMethod.POST, ResourcePaths.V1_TABLE_RENAME, RenameTableRequest.class, null),
REPORT_METRICS(
HTTPMethod.POST, ResourcePaths.V1_TABLE_METRICS, ReportMetricsRequest.class, null),
Expand Down Expand Up @@ -392,6 +393,12 @@ public <T extends RESTResponse> T handleRequest(
return null;
}

case TABLE_EXISTS:
{
CatalogHandlers.tableExists(catalog, tableIdentFromPathVars(vars));
return null;
}

case LOAD_TABLE:
{
TableIdentifier ident = tableIdentFromPathVars(vars);
Expand Down
44 changes: 22 additions & 22 deletions core/src/test/java/org/apache/iceberg/rest/TestRESTCatalog.java
Original file line number Diff line number Diff line change
Expand Up @@ -346,11 +346,11 @@ public void testCatalogBasicBearerToken() {
any());
Mockito.verify(adapter)
.execute(
eq(HTTPMethod.GET),
eq(HTTPMethod.HEAD),
eq("v1/namespaces/ns/tables/table"),
any(),
any(),
eq(LoadTableResponse.class),
eq(null),
eq(catalogHeaders),
any());
}
Expand Down Expand Up @@ -393,11 +393,11 @@ public void testCatalogCredentialNoOauth2ServerUri() {
// use the catalog token for all interactions
Mockito.verify(adapter)
.execute(
eq(HTTPMethod.GET),
eq(HTTPMethod.HEAD),
eq("v1/namespaces/ns/tables/table"),
any(),
any(),
eq(LoadTableResponse.class),
eq(null),
eq(catalogHeaders),
any());
}
Expand Down Expand Up @@ -448,11 +448,11 @@ public void testCatalogCredential(String oauth2ServerUri) {
// use the catalog token for all interactions
Mockito.verify(adapter)
.execute(
eq(HTTPMethod.GET),
eq(HTTPMethod.HEAD),
eq("v1/namespaces/ns/tables/table"),
any(),
any(),
eq(LoadTableResponse.class),
eq(null),
eq(catalogHeaders),
any());
}
Expand Down Expand Up @@ -509,11 +509,11 @@ public void testCatalogBearerTokenWithClientCredential(String oauth2ServerUri) {
// use the context token for table load
Mockito.verify(adapter)
.execute(
eq(HTTPMethod.GET),
eq(HTTPMethod.HEAD),
eq("v1/namespaces/ns/tables/table"),
any(),
any(),
eq(LoadTableResponse.class),
eq(null),
eq(contextHeaders),
any());
}
Expand Down Expand Up @@ -582,11 +582,11 @@ public void testCatalogCredentialWithClientCredential(String oauth2ServerUri) {
// use the context token for table load
Mockito.verify(adapter)
.execute(
eq(HTTPMethod.GET),
eq(HTTPMethod.HEAD),
eq("v1/namespaces/ns/tables/table"),
any(),
any(),
eq(LoadTableResponse.class),
eq(null),
eq(contextHeaders),
any());
}
Expand Down Expand Up @@ -657,11 +657,11 @@ public void testCatalogBearerTokenAndCredentialWithClientCredential(String oauth
// use the context token for table load
Mockito.verify(adapter)
.execute(
eq(HTTPMethod.GET),
eq(HTTPMethod.HEAD),
eq("v1/namespaces/ns/tables/table"),
any(),
any(),
eq(LoadTableResponse.class),
eq(null),
eq(contextHeaders),
any());
}
Expand Down Expand Up @@ -845,11 +845,11 @@ private void testClientAuth(
}
Mockito.verify(adapter)
.execute(
eq(HTTPMethod.GET),
eq(HTTPMethod.HEAD),
eq("v1/namespaces/ns/tables/table"),
any(),
any(),
eq(LoadTableResponse.class),
eq(null),
eq(expectedHeaders),
any());
if (!optionalOAuthParams.isEmpty()) {
Expand Down Expand Up @@ -1619,11 +1619,11 @@ public void testCatalogRefreshedTokenIsUsed(String oauth2ServerUri) {
"Bearer token-exchange-token:sub=client-credentials-token:sub=catalog");
Mockito.verify(adapter)
.execute(
eq(HTTPMethod.GET),
eq(HTTPMethod.HEAD),
eq("v1/namespaces/ns/tables/table"),
any(),
any(),
eq(LoadTableResponse.class),
eq(null),
eq(refreshedCatalogHeader),
any());
});
Expand Down Expand Up @@ -1735,11 +1735,11 @@ public void testCatalogExpiredBearerTokenIsRefreshedWithCredential(String oauth2

Mockito.verify(adapter)
.execute(
eq(HTTPMethod.GET),
eq(HTTPMethod.HEAD),
eq("v1/namespaces/ns/tables/table"),
any(),
any(),
eq(LoadTableResponse.class),
eq(null),
eq(ImmutableMap.of("Authorization", "Bearer token-exchange-token:sub=" + token)),
any());
}
Expand Down Expand Up @@ -1777,11 +1777,11 @@ public void testCatalogValidBearerTokenIsNotRefreshed() {

Mockito.verify(adapter)
.execute(
eq(HTTPMethod.GET),
eq(HTTPMethod.HEAD),
eq("v1/namespaces/ns/tables/table"),
any(),
any(),
eq(LoadTableResponse.class),
eq(null),
eq(OAuth2Util.authHeaders(token)),
any());
}
Expand Down Expand Up @@ -1919,11 +1919,11 @@ public void testCatalogTokenRefreshFailsAndUsesCredentialForRefresh(String oauth
"Bearer token-exchange-token:sub=client-credentials-token:sub=catalog");
Mockito.verify(adapter)
.execute(
eq(HTTPMethod.GET),
eq(HTTPMethod.HEAD),
eq("v1/namespaces/ns/tables/table"),
any(),
any(),
eq(LoadTableResponse.class),
eq(null),
eq(refreshedCatalogHeader),
any());
});
Expand Down